Ви вводите правильне ім’я користувача. Правильний пароль. Навіть вставляєте його з менеджера паролів, тобто він точно вірний. А OpenVPN відповідає найхолоднішим повідомленням у мережевому світі: AUTH_FAILED.
Це той тип помилки, який краде години, бо позначений як людська проблема («поганий пароль»), хоча часто це проблема системи (політика, плагін, годинник, шифр, відклик, середовище). Ставимося до цього як до інциденту, а не моралізаторства.
Що насправді означає AUTH_FAILED (і чого це не означає)
AUTH_FAILED означає: сервер вирішив відхилити клієнта під час етапу «автентифікація користувача» й повідомив про це клієнта. І все. Це не означає «ваш пароль неправильний». Навіть не означає, що сервер перевіряв ваш пароль.
Аутентифікація в OpenVPN може включати кілька шарів, і різні шари дають оманливо подібні результати для клієнта:
- TLS-ідентичність: сертифікати, CA, відклик (CRL), EKU, правильність годинника, TLS-опції.
- Аутентифікація користувача: статичний файл, PAM, LDAP, RADIUS, обгортки типу OAuth, шлюзи MFA, власні скрипти.
- Політика: обмеження на користувача, членство в групі, «без одночасних сесій», правила за джерельною IP, дозволи маршрутів.
- Прокладка сесії: auth-token, renegotiation, кешування автентифікації, client-config-dir перекриття.
Операційно дратівлива частина: залежно від конфігурації клієнт може побачити AUTH_FAILED, навіть якщо справжня проблема була в TLS-деталі, збою плагіна, тайм-ауті бекенда або невідповідності нормалізації імені користувача.
Один рядок помилки — багато режимів відмови
OpenVPN навмисно розширюваний. Саме тому він живе в підприємствах, де ще стоїть мейнфрейм і три провайдери ідентичності. Але розширюваність означає, що «рішення» може прийти зі скрипта або плагіна поза ядром OpenVPN. І коли скрипт каже «ні», клієнт чує «AUTH_FAILED», навіть якщо скрипт сказав «ні, бо LDAP недоступний» або «ні, бо в імені користувача є @ і ми його обрізаємо».
Одна перефразована ідея від Werner Vogels (CTO Amazon), яку операційні люди повторюють не дарма: все ламається, весь час; проектуйте й експлуатуйте, приймаючи це як даність
(перефразовано). AUTH_FAILED — ідеальний приклад: ваше завдання — знайти, яка залежність дала збій.
Короткий жарт #1: Паролі — як молоко: усі клянуться, що воно свіже, поки не почне лякати в продакшені.
Швидкий план діагностики (перевірити перше/друге/третє)
Це потік «зупинити кровотечу». Він орієнтований на зменшення середнього часу до ясності, а не на пояснення теорії. Глибшу археологію можна зробити пізніше.
Перше: підтвердьте, де саме відбувається збій (TLS чи автентифікація користувача)
- Збільшіть вербозність клієнта до 4–6. Шукайте: “TLS: Initial packet,” “VERIFY OK,” “Peer Connection Initiated,” а потім “AUTH_FAILED.”
- Якщо TLS не завершується, не ганяйтеся за паролями. Перевіряйте сертифікати, час, шифри, ланцюжок CA та прослуховування сервера/порт/файрвол.
- Якщо TLS завершується, а потім AUTH_FAILED, розслідуйте pipeline автентифікації користувача: плагін, скрипт, PAM/LDAP/RADIUS/MFA та серверні перевірки політик.
Друге: перевірте логи сервера в точний часовий штамп
- Знайдіть рядок з’єднання для того клієнта (звичайні поля: common-name, username, real address).
- Шукайте `AUTH_FAILED`, `PLUGIN_CALL`, `AUTH-PAM`, `radiusplugin`, `auth-user-pass-verify`, `client-denied`.
- Якщо бачите помилку бекенда (bind LDAP, тайм-аут RADIUS), трактуйте це як відмову ідентичності, а не помилку користувача.
Третє: перевірте припущення про формат імені користувача, realm і метод автентифікації
- Чи очікує сервер `samaccountname`, `user@domain` або `DOMAIN\user`?
- Ви використовуєте `–auth-user-pass` з файлом паролів, і чи немає в ньому зайвих пробілів у кінці?
- Чи потрібна MFA? В деяких налаштуваннях «лише пароль» відхиляють з AUTH_FAILED та марним логом.
Четверте: перевірте політику та стан
- Правила одночасних сесій (duplicate-cn, management interface, ліміти сесій).
- Відкликаний сертифікат або вимкнений користувач, хоча облікові дані ще «правильні».
- client-config-dir перекриття (персональні push, iroute або `disable`).
П’яте: відтворіть у контрольованому середовищі
- Спробуйте ті самі облікові дані з відомою-гарною конфігурацією клієнта.
- Спробуйте відомо-гарного користувача з конфігурацією клієнта, яка дає збій.
- Це за кілька хвилин відокремлює «ідентичність» від «конфігурації клієнта».
Факти й контекст: чому автентифікація OpenVPN дивно складна
Декілька невеликих, конкретних фактів допоможуть пояснити, чому AUTH_FAILED у реальному світі став універсальним маркером:
- OpenVPN з’явився у 2001 році, і його точки розширення (скрипти/плагіни) були створені для гетерогенних корпоративних систем задовго до того, як «SSO» стало стандартом.
- Аутентифікація користувача/паролю не є природною для TLS VPN; OpenVPN додав її, щоб задовольнити організації, які хотіли другий фактор крім сертифікатів.
- Інтеграція PAM зробила OpenVPN «рідним» на Unix — і також успадкувала складність PAM: політики облікових записів, прострочені паролі, блокування акаунтів і порядок модулів.
- Підтримка RADIUS стала типовою в ентерпрайзі, бо централізує рішення з автентифікації та MFA, але додає тайм-аути, які виглядають як погані паролі.
- client-config-dir OpenVPN потужний: ви можете непомітно перебити налаштування для користувача. Ця сила також дозволяє тихо зламати доступ одного користувача.
- Списки відкликань (CRL) складні в експлуатації: це файли, вони застарівають, їх забувають. Відкликаний сертифікат може існувати разом з «правильним» паролем і все одно блокувати доступ.
- Коректність годинника критична для безпеки: сертифікати і деякі токени мають часові рамки. Розбіжність часу дає помилки автентифікації, які маскуються під проблеми з обліковими даними.
- Еволюціонував кеш автентифікації (auth-token, renegotiation) щоб зменшити пропитування паролем, але неправильна конфігурація може спричинити цикли або «застарілі токени».
- Сучасні угоди про шифри змінили значення за замовчуванням в OpenVPN 2.5+ (data-ciphers). Невідповідності можуть привести до ранніх розривів, що користувачі трактують як «проблеми автентифікації».
Тріаж на стороні клієнта: доведіть, що ви відправили
Коли хтось каже «облікові дані правильні», часто мають на увазі «облікові дані працюють в іншому місці». Це не те саме. Клієнт OpenVPN може надсилати інше ім’я користувача, ніж очікує користувач. Або він може надсилати правильне ім’я з неправильним кодуванням. Або файл пароля може містити новий рядок, carriage return або BOM.
Шукайте докази в логах клієнта (не в почуттях)
На клієнті збільшіть verbosity і шукайте послідовність:
- Встановлено TLS handshake.
- Сервер надсилає опції.
- Клієнт запитує ім’я/пароль або читає їх з файлу.
- Сервер відповідає AUTH_FAILED або надсилає auth-token.
Якщо ви не бачите завершеного TLS handshake, не гоніться за автентифікацією користувача. Якщо бачите — сервер досяжний і «розмова про пароль» відбулася (або була спроба).
Зверніть увагу на формат імені користувача
Корпоративні налаштування OpenVPN часто нормалізують імена користувачів. Дехто обрізає realm; дехто вимагає його. Дехто приймає `DOMAIN\user`, а відкидає `user@domain`. Дехто приводить усе до нижнього регістру. Дехто трактує «john.smith» і «John.Smith» як різних користувачів у спадоковому каталозі.
Коли ви діагностуєте — вирішіть один канонічний формат і протестуйте його. Інакше ви будете «праві» трьома різними способами й все одно помилитесь у продакшені.
Файли з обліковими даними — пастки
--auth-user-pass /path/to/file очікує файл з двома рядками: ім’я користувача і пароль. Цей файл може підвести через:
- Windows CRLF кінець рядка (
\r\n), що додає прихований\rв паролі. - Трайлінг-пробіл, скопійований з тикету.
- UTF-8 BOM на початку рядка з ім’ям користувача.
Короткий жарт #2: Єдина річ, що живе довше за прострочений VPN-пароль — це прихований Windows carriage return у кінці нього.
Тріаж на стороні сервера: доведіть, що вирішив сервер
Логи сервера — джерело істини, але тільки якщо ви логуєте достатньо і дивитесь у правильному місці. OpenVPN може логувати через syslog, файл, systemd journal або management interface. Плагіни і скрипти можуть логувати в інші місця. І інколи єдина підказка — що плагін повернув ненульовий код.
Знайте свій механізм автентифікації
На сервері автентифікація користувача зазвичай надходить від одного з цих джерел:
- PAM (
openvpn-plugin-auth-pam.so): використовує системний стек PAM, може застосовувати прострочення пароля/блокування акаунту. - Зовнішній скрипт (
auth-user-pass-verify): ваш скрипт вирішує. Якщо він падає — отримуєте AUTH_FAILED. - RADIUS плагін: делегує RADIUS серверу; тайм-аути і проблеми з shared secret виглядають як погані паролі.
- LDAP плагін/скрипт: виконує bind до LDAP; невірний base DN, фільтр або TLS-настройки викликають відмови.
- MFA шлюз: потоки на кшталт Duo часто змінюють поле пароля (додають код push) або використовують RADIUS challenge/response.
Відрізняйте «відхилено автентифікацію» від «ламана автентифікація»
Pipeline автентифікації може відхилити, бо користувач неправильний. А може відхилити, бо pipeline зламався. Операційно це різні серйозності:
- Користувач неправильний: один користувач, постійно, бекенд здоровий.
- Pipeline зламана: багато користувачів, тайм-аути, помилки плагінів, сплески логів, навантаження на CPU, проблеми з резолвером.
Будьте безжальні у відокремленні цих випадків. Якщо п’ятеро людей одночасно падають відразу після деплою — це не п’ять людей, що раптово забули, як друкувати.
Практичні завдання: команди, виводи, рішення
Нижче — практичні перевірки, які можна виконати. Кожна містить реалістичний фрагмент виводу і рішення з нього. Використовуйте їх як рукомовний план, а не як шведський стіл.
Завдання 1: Підтвердити, що клієнт дійсно досягає сервера і завершує TLS
cr0x@server:~$ sudo openvpn --config client.ovpn --verb 5
...
TCP/UDP: Preserving recently used remote address: [AF_INET]203.0.113.10:1194
TLS: Initial packet from [AF_INET]203.0.113.10:1194, sid=2c0e1f9d 1a2b3c4d
VERIFY OK: depth=1, CN=corp-vpn-ca
VERIFY OK: depth=0, CN=vpn-gateway-1
Control Channel: TLSv1.3, cipher TLS_AES_256_GCM_SHA384, peer certificate: 256 bit RSA
[corp-vpn] Peer Connection Initiated with [AF_INET]203.0.113.10:1194
AUTH: Received control message: AUTH_FAILED
SIGTERM[soft,auth-failure] received, process exiting
Значення: TLS спрацював; збій у user auth/політиці. Рішення: Припиніть дебаг сертифікатів і переходьте до логів серверу/плагінів автентифікації.
Завдання 2: Перевірити журнал сервера на рядки, пов’язані з автентифікацією, у момент збою
cr0x@server:~$ sudo journalctl -u openvpn-server@corp -S "2025-12-27 09:10:00" -U "2025-12-27 09:15:00"
Dec 27 09:12:31 vpn1 openvpn[1842]: 198.51.100.44:51233 TLS: Username/Password authentication deferred for username 'j.smith'
Dec 27 09:12:31 vpn1 openvpn[1842]: 198.51.100.44:51233 PLUGIN_CALL: POST /usr/lib/openvpn/openvpn-plugin-auth-pam.so/PLUGIN_AUTH_USER_PASS_VERIFY status=1
Dec 27 09:12:31 vpn1 openvpn[1842]: 198.51.100.44:51233 AUTH_FAILED: user 'j.smith'
Значення: PAM-плагін відхилив. Рішення: Перевірити конфігурацію PAM, стан акаунту і чи повертає PAM «прострочено/заблоковано» versus «помилковий пароль».
Завдання 3: Перевірити, який механізм автентифікації використовує сервер
cr0x@server:~$ sudo grep -E '^(plugin|auth-user-pass-verify|client-cert-not-required|verify-client-cert|management)' /etc/openvpn/server/corp.conf
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login
verify-client-cert require
management 127.0.0.1 7505
Значення: Включено PAM-плагін; клієнт-сертифікат також обов’язковий. Рішення: Тріажуйте PAM і перевірте валідність/відклик сертифікатів, якщо симптоми не відповідають user auth.
Завдання 4: Протестувати PAM напряму на сервері (ізолюючи OpenVPN)
cr0x@server:~$ sudo pamtester login j.smith authenticate
Password:
pamtester: Authentication failure
Значення: PAM відкидає; OpenVPN лише кур’єр. Рішення: Перевірити доступність директорії, порядок модулів PAM, прострочення пароля, блокування акаунту, стан NSS/SSSD.
Завдання 5: Подивитися стек PAM, який використовує плагін
cr0x@server:~$ sudo sed -n '1,200p' /etc/pam.d/login
auth required pam_securetty.so
auth requisite pam_nologin.so
auth include common-auth
account include common-account
session include common-session
Значення: Плагін використовує сервіс «login», який може бути суворішим, ніж ви очікуєте (nologin, securetty). Рішення: Розгляньте окремий PAM-сервіс (наприклад, /etc/pam.d/openvpn), щоб уникнути сторонніх обмежень.
Завдання 6: Перевірити SSSD / здоров’я директорії (поширений тихий винуватець)
cr0x@server:~$ sudo systemctl status sssd --no-pager
● sssd.service - System Security Services Daemon
Loaded: loaded (/lib/systemd/system/sssd.service; enabled)
Active: active (running) since Fri 2025-12-27 08:40:18 UTC; 32min ago
...
Значення: SSSD працює, але це не гарантує, що він може достукатися до LDAP. Рішення: Виконати запит по користувачу і перевірити логи на тайм-аути.
Завдання 7: Перевірити пошук користувача та членство в групі (політика може блокувати)
cr0x@server:~$ id j.smith
uid=110245(j.smith) gid=10000(domain users) groups=10000(domain users),12010(vpn-users)
Значення: Користувач існує і входить до vpn-users. Рішення: Якщо автентифікація все одно ламається — це не «користувач відсутній»; перевіряйте стан пароля/акаунту або upstream-політики/MFA-потік.
Завдання 8: Перевірити стан акаунту (заблокований/прострочений) при локальній або LDAP-підтримці
cr0x@server:~$ sudo passwd -S j.smith
j.smith L 2025-11-02 0 99999 7 -1
Значення: «L» вказує на заблокований акаунт (для локальних акаунтів; інтерпретація залежить від налаштувань директорії). Рішення: Розблокувати/скинути через відповідний провайдер ідентичності; припиніть просити користувача «спробувати ще раз».
Завдання 9: Перевірити файл облікових даних клієнта на приховані символи
cr0x@server:~$ sed -n '1,2p' -n auth.txt | cat -A
j.smith$
MyS3cretP@ssw0rd^M$
Значення: Рядок пароля закінчується ^M (CR). Це інший пароль. Рішення: Конвертуйте файл у Unix-кінці рядків і повторіть спробу.
Завдання 10: Виправити CRLF у файлі облікових даних і повторити тест
cr0x@server:~$ sed -i 's/\r$//' auth.txt
cr0x@server:~$ sed -n '1,2p' auth.txt | cat -A
j.smith$
MyS3cretP@ssw0rd$
Значення: CR видалено. Рішення: Перезапустіть клієнт; якщо тепер працює, ви щойно зекономили годину даремного звинувачення LDAP.
Завдання 11: Перевірити відклик сертифіката / проблеми CRL
cr0x@server:~$ sudo grep -E '^(crl-verify|ca|cert|key)' /etc/openvpn/server/corp.conf
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn-gateway-1.crt
key /etc/openvpn/pki/private/vpn-gateway-1.key
crl-verify /etc/openvpn/pki/crl.pem
Значення: CRL застосовується. Відкликаний клієнтський сертифікат може заблокувати доступ, навіть якщо пароль правильний. Рішення: Перевірте, чи сертифікат, що підключається, відкликаний і чи файл CRL актуальний/читабельний.
Завдання 12: Інспектувати свіжість і права на CRL
cr0x@server:~$ sudo ls -l /etc/openvpn/pki/crl.pem
-rw-r----- 1 root openvpn 2451 Nov 1 2024 /etc/openvpn/pki/crl.pem
Значення: Старий timestamp. Якщо ваша PKI оновлюється, ви можете застосовувати застарілий CRL (або пропускати недавні відклики). Рішення: Перегенеруйте/освіжіть CRL в процесі PKI-операцій і переконайтеся, що OpenVPN може його читати.
Завдання 13: Підтвердити, що OpenVPN читає ту конфігурацію, яку ви думаєте
cr0x@server:~$ sudo systemctl cat openvpn-server@corp
# /lib/systemd/system/openvpn-server@.service
ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config /etc/openvpn/server/%i.conf
Значення: Інстанс використовує /etc/openvpn/server/corp.conf. Рішення: Припиніть редагувати неправильний файл під /etc/openvpn/ і чекати див.
Завдання 14: Перевірити management interface для підказок в реальному часі (якщо ввімкнено)
cr0x@server:~$ printf "status 3\nquit\n" | nc 127.0.0.1 7505
OpenVPN STATISTICS
Updated,2025-12-27 09:13:02
CLIENT_LIST,UNDEF,198.51.100.44:51233,10.8.0.0,0,0,2025-12-27 09:12:31
END
Значення: Клієнт так і не став повністю встановленим (UNDEF common name як підказка). Рішення: Зосередьтеся на етапі автентифікації, а не на маршрутизації/опціях push.
Завдання 15: Перевірити час сервера (токени/MFA і валідність сертифікатів залежать від нього)
cr0x@server:~$ timedatectl
Local time: Fri 2025-12-27 09:13:55 UTC
Universal time: Fri 2025-12-27 09:13:55 UTC
RTC time: Fri 2025-12-27 09:13:55
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Значення: Час синхронізовано. Рішення: Якби час не синхронізувався — виправте NTP перед тим, як дебажити «випадкові» помилки автентифікації, особливо зі швидкоживими токенами.
Завдання 16: Перевірити DNS-резолюцію на VPN-сервері (LDAP/RADIUS часто використовують імена хостів)
cr0x@server:~$ getent hosts ldap01.corp.local
10.20.30.40 ldap01.corp.local
Значення: Ім’я резолюється. Рішення: Якщо не резолюється або вказує на стару IP — виправте DNS/hosts/SSSD resolver; бекенди автентифікації не будуть доступні надійно.
Завдання 17: Якщо використовується RADIUS, підтвердити підключення (тайм-аут vs відмова)
cr0x@server:~$ nc -vz radius01 1812
Connection to radius01 1812 port [tcp/*] succeeded!
Значення: TCP-зв’язок існує (зауважте: RADIUS зазвичай UDP; це лише доводить базову доступність імен/маршруту/фаєрволу). Рішення: Якщо мережа заблокована, RADIUS-плагін може пред’явити це як AUTH_FAILED.
Завдання 18: Перевірити узгодженість версій OpenVPN (поведінка змінюється між версіями)
cr0x@server:~$ openvpn --version
OpenVPN 2.6.8 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD]
library versions: OpenSSL 3.0.13 30 Jan 2024, LZO 2.10
Значення: Сервер 2.6.x з OpenSSL 3. Рішення: Якщо клієнти старі, перевірте data-ciphers і мінімальну версію TLS. Невідповідність може виглядати як «дивні» проблеми з автентифікацією для користувачів.
Типові помилки (симптом → корінь проблеми → виправлення)
1) Симптом: «AUTH_FAILED» відразу після «Peer Connection Initiated»
Корінь проблеми: Плагін або скрипт автентифікації відхиляє; облікові дані можуть бути в порядку, але бекенд недоступний або політика забороняє користувача.
Виправлення: Перегляньте логи сервера навколо `PLUGIN_CALL` / `AUTH-PAM` / виводу скрипта. Якщо це відмова бекенда — обробляйте як інцидент і відновіть залежність.
2) Симптом: Облікові дані працюють через SSH/PAM, але OpenVPN каже AUTH_FAILED
Корінь проблеми: PAM-плагін OpenVPN вказує на інший PAM-сервіс (наприклад, `login`) з додатковими обмеженнями (nologin, securetty, правила за часом).
Виправлення: Використайте виділений PAM-сервіс (наприклад, /etc/pam.d/openvpn) і налаштуйте `plugin … openvpn` відповідно.
3) Симптом: Тільки Windows-клієнти падають; Linux/macOS в порядку
Корінь проблеми: Файл облікових даних збережено з CRLF, що додає `\r` до пароля; або GUI-клієнт відправляє ім’я в іншому форматі.
Виправлення: Нормалізуйте кінці рядків; уникайте файлів паролів коли можливо; тестуйте з ручним введенням; стандартизуте формат імені користувача.
4) Симптом: Падає тільки один користувач, стабільно на різних пристроях
Корінь проблеми: Акаунт заблокований, пароль прострочений, користувача видалено з потрібної групи, або сертифікат відкликано, поки пароль залишається дійсним.
Виправлення: Перевірте стан у постачальника ідентичності для цього користувача; підтвердіть членство в групі; перевірте CRL і статус сертифіката.
5) Симптом: Усі падають одразу після оновлення OpenVPN
Корінь проблеми: Змінилися значення за замовчуванням шифрів/TLS; бінарник плагіна несумісний; або суворіша перевірка виявила проблеми з сертифікатами.
Виправлення: Перевірте `data-ciphers` і мінімальні налаштування TLS; підтвердіть шлях плагіна й ABI-сумісність; за потреби відкатуйте, а потім впроваджуйте зміни поступово.
6) Симптом: Випадкові користувачі падають, потім вдається повторно
Корінь проблеми: Тайм-аути бекенда (RADIUS/LDAP), флапи DNS, перевантаження сервера автентифікації або обмеження частих спроб/блокування.
Виправлення: Інструментуйте й моніторьте latency бекендів; обережно зменшуйте тайм-аути; додавайте резерви; виправте DNS. Повторні спроби — не стратегія.
7) Симптом: Користувач вводить правильний пароль + MFA, але все одно AUTH_FAILED
Корінь проблеми: Інтеграція MFA очікує інший формат (приєднати OTP, використовувати challenge/response) або потребує специфічного RADIUS-атрибуту.
Виправлення: Погодьте MFA-потік з командою ідентичності; оновіть інструкції для клієнтів; переконайтеся, що плагін підтримує ваш режим MFA.
8) Симптом: AUTH_FAILED при реконнекті/renegotiation, а не при першому з’єднанні
Корінь проблеми: Кешування автентифікації/renegotiation некоректні; `auth-nocache` і політики токенів конфліктують; стан сесії втрачається при рестарті сервера.
Виправлення: Вирішіть, чи потрібні вам токени; узгодьте налаштування сервера й клієнта; протестуйте вікна renegotiation; уникайте «напівввімкнених» конфігурацій токенів.
Три корпоративні міні-історії з практики
Міні-історія 1: Інцидент через неправильне припущення
В компанії був VPN-шлюз, який «використовував LDAP». Та фраза роками крутилася в тикетах як мантра, що відвертала питання. Новий SRE отримав пейдж через хвилю AUTH_FAILED після зміни в каталозі. Користувачі наполягали, що їхні облікові дані вірні. Хелпдеск казав, що VPN в порядку. Панелі показували нуль, бо їх не існувало.
SRE підключився до логів OpenVPN і бачив `PLUGIN_CALL`, далі `status=1`. Деталі відсутні. Вони припустили збій bind до LDAP і перевірили: мережу, DNS, файрвол. Все виглядало нормально. Година пішла на пошук «чи ви поламали LDAP?» у календарі змін команд.
Перш ніж писати листа, вони перевірили конфіг сервера OpenVPN і помітили, що використовується PAM, а не прямий LDAP. LDAP був upstream через SSSD, і кеш SSSD був застарілий, бо сервер не міг дістатися джерела часу після зміни маршруту. Kerberos/LDAP шар не падав геть; він став повільним і непостійним. PAM повертав помилки. OpenVPN повідомляв AUTH_FAILED.
Неправильне припущення було тонке: «AUTH_FAILED після зміни в каталозі = bind LDAP впав». Насправді проблема була в тайм-синхронізації, через яку виростали тайм-аути резолюції, що викликало відмови PAM — тип речей, які змушують ставитися до NTP як до продакшн-бази даних.
Виправили маршрут до NTP, перезапустили SSSD, щоб очистити кеш, і збій зник. Команда каталогу так і не дізналася про листа у чернетках, який міг бути звинуваченням.
Міні-історія 2: Оптимізація, що обернулась проти
Команда безпеки хотіла менше запитів пароля. Вони ввімкнули повторну автентифікацію на основі токенів, щоб користувачі не вводили облікові дані при кожному реконекті. Звучало добре: менше підказок, менше блокувань, менше тикетів. Впровадили це «тихо», що в корпоративній часовій шкалі означає «перед святами».
Спочатку все було добре. Потім ноутбуки почали переходити в сон, змінювати мережі й пробувати підключитися. Деякі реконекти проходили, інші — падали з AUTH_FAILED. Хелпдеск класифікував це як «проблеми з паролем». Користувачі скидали паролі, що звісно не допомагало токенам. Тож з’явилися й VPN-фейли, й потік скидань паролів.
Корінь був у невідповідності між життєвим циклом токенів і поведінкою renegotiation. Деякі клієнти надсилали застарілий токен після тривалого сну; сервер вважав його недійсним і відкидав. Логування було недостатнім, тож усе виглядало як проблеми з паролем, хоча паролі не вводилися взагалі.
Виправлення було нудним: узгодити політики токенів з реальною поведінкою пристроїв, збільшити логування навколо валідації токенів і додати фолбек на клієнті з запитом облікових даних, коли токен не пройшов. І мораль: не міняйте поведінку автентифікації прямо перед святами, якщо не любите вивчати нові непристойні слова у вихідні.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Внутрішня платформа тримала два OpenVPN-шлюзи за лоадбалансером. Нічого надприродного. Фантастичною була їхня дисципліна: кожна зміна мала канарку, а кожна канарка — відомо-гарного тестового користувача та відомо-поганого. Вони також мали невелику суїту перевірок залежностей ідентичності, що запускалася щохвилини: чи резолюються LDAP-хости, чи можемо виконати bind, чи доступний RADIUS, чи синхронізовано час.
Одного ранку користувачі почали скаржитися на AUTH_FAILED — лише на одному шлюзі. Канаркові перевірки помітили це за дві хвилини: latency bind до LDAP різко зросла на vpn2, але не на vpn1. Лоадбалансер усе ще шив трафік на vpn2, бо health checks були лише «порт відкритий».
Оскільки вони мали логи по вузлу й структуровані перевірки, не розмірковували, чи користувачі забули паролі. Вони злити трафік з vpn2, відновили сервіс, а потім спокійно досліджували: у vpn2 резолвер вказував на старий DNS-сервер. DNS для LDAP флапав, що викликало тайм-аути автентифікації й відмови.
Виправили конфіг резолвера, додали до health check лоадбалансера фактичну перевірку залежностей автентифікації й написали постмортем з одним реченням провини: «Ми покладалися на перевірку порту як представник pipeline ідентичності». Це було нудно, але запобігло повторенню інциденту в наступному вбранні.
Чеклісти / покроковий план
Покроково: коли один користувач повідомляє AUTH_FAILED
- Затримайте часову мітку (з урахуванням часової зони) і публічну IP-клієнта.
- Запитайте точний формат імені користувача, який він вводив (включаючи домен/realm).
- Підтвердіть, чи використовував файл облікових даних або інтерактивний промпт.
- Перевірте логи сервера в той час. Знайдіть рядок з’єднання і рядок рішення по автентифікації.
- Визначте бекенд автентифікації: PAM vs скрипт vs RADIUS vs LDAP плагін.
- Протестуйте бекенд напряму: PAM test, LDAP bind, RADIUS connectivity, перевірка членства в групі.
- Перевірте рівні політики: членство в групі, ліміти одночасних сесій, персональні CCD перекриття.
- Якщо є сертифікати: перевірте, що клієнтський сертифікат не прострочений/не відкликаний; перевірте свіжість CRL.
- Прийміть рішення: відновлення користувача (розблок/скидання) або інфраструктурний інцидент (бекенд недоступний).
Покроково: коли багато користувачів повідомляють AUTH_FAILED
- Припустіть відмову залежності, поки не спростовано.
- Перевірте одного відомо-гарного користувача з відомою-гарною конфігурацією. Якщо і він падає — це не проблема освіти користувача.
- Перевірте бекенди ідентичності: доступність директорії, стан RADIUS, статус MFA-провайдера, DNS, синхронізацію часу.
- Перевірте останні зміни: оновлення OpenVPN, плагінів, правки PAM, ротація сертифікатів, зміни файрволу.
- Ізолюйте по вузлах, якщо маєте кілька шлюзів: зніміть один із пулу по черзі, щоб побачити локалізацію проблеми.
- Тимчасово збільшіть логування (уважно щодо чутливих даних), щоб зафіксувати шляхи виходу плагінів/скриптів.
- Спершу стабілізуйте: відкотіть або обійдіть некритичні auth-фічі, якщо політика дозволяє (наприклад, тимчасово послабити групові перевірки).
- Запишіть хронологію. За 24 години ви забудете, і майбутній ви заслуговує кращого опису.
Чого уникати (думка автора)
- Не просіть користувачів скидати паролі як перший крок. Це створює шум і ховає системні відмови.
- Не дебажте лише з клієнта. AUTH_FAILED — це серверне рішення.
- Не міняйте три змінні одночасно («ми оновили OpenVPN, ротацію сертифікатів і PAM»). Це не інженерія, це азартна гра.
- Робіть один відомо-гарний клієнт і зберігайте його недоторканим. Це ваша контрольна група.
Часті питання
Чому OpenVPN каже AUTH_FAILED, коли пароль правильний?
Тому що сервер відхилив спробу автентифікації з причин, що включають, але не обмежуються: неправильний пароль, заблокований акаунт, прострочений пароль, відсутність у потрібній групі, тайм-аут бекенда, збій плагіна або політика MFA.
Як дізнатися, чи це проблеми TLS/сертифікатів, чи ім’я/пароль?
Шукайте завершений TLS handshake в логах клієнта. Якщо бачите “Peer Connection Initiated” і потім AUTH_FAILED, TLS ймовірно пройшов, а далі впала user auth/політика.
Чи може відкликаний сертифікат спричинити AUTH_FAILED навіть з правильними даними?
Так. Якщо сервер вимагає клієнтські сертифікати і застосовує CRL, відкликаний сертифікат заблокує доступ незалежно від правильності імені/пароля.
Який найшвидший лог на сервері на systemd-based Linux?
journalctl -u openvpn-server@<instance> навколо часу збою. Шукайте виклики плагінів, запуск скриптів і явні рядки AUTH_FAILED з іменами користувачів.
Чому лише Windows-користувачі падають?
Типові причини: CRLF у файлі облікових даних, інший формат імені в GUI, або користувачі копіюють пароль з пробілом наприкінці. Перевірте файл облікових даних за допомогою cat -A і стандартизуте введення.
Ми використовуємо PAM. Чому SSH працює, а OpenVPN ні?
PAM модульний. SSH може використовувати PAM-сервіс sshd, тоді як OpenVPN — login (або інший). Ці стеки можуть відрізнятися в правилах для акаунтів, дозволених TTY чи поведінці nologin.
Чи може DNS дійсно виглядати як AUTH_FAILED?
Так. Якщо ваш бекенд автентифікації використовує імена хостів (LDAP, RADIUS, MFA шлюзи), проблеми резолюції або застарілий DNS можуть спричиняти тайм-аути, що закінчуються загальним відмовою автентифікації.
Чи важлива синхронізація часу для автентифікації VPN?
Абсолютно. Сертифікати мають вік, MFA і токени залежать від часу, а Kerberos-автентифікація дуже чутлива до зсуву годинника. Якщо час невірний — виправте його перш за все.
Чи варто постійно вмикати більше вербозності в логах?
Тримайте базовий рівень логів, достатній для відокремлення проблем TLS від відмов бекенду. Тимчасово підвищуйте вербозність під час інцидентів. Слідкуйте, щоб чутлива інформація зі скриптів/плагінів не потрапляла в логи.
Чи безпечно покладатися на health checks «порт відкритий» для VPN-шлюзів?
Ні. Лістенер може бути доступний, тоді як pipeline автентифікації — зламаний. Додайте health checks, що перевіряють доступність залежностей (DNS, bind до директорії, відповіді RADIUS) і виводьте вузли з пулу при їхній відмові.
Висновок: наступні кроки, що дійсно зменшують шум від пейджера
Якщо ви виконаєте лише кілька дій з цього списку:
- Відокремлюйте помилки TLS від помилок автентифікації користувача за доказами з логів клієнта. Припиніть трактувати AUTH_FAILED автоматично як «поганий пароль».
- Змушуйте сервер пояснювати себе: забезпечте логи з результатами плагінів/скриптів і простим пошуком по часовій мітці.
- Тестуйте бекенди ідентичності напряму (PAM/SSSD/LDAP/RADIUS), щоб могли впевнено сказати «відмова ідентичності».
- Стандартизуйте формати імен користувачів і задокументуйте MFA-потоки в одному місці, що не застаріє.
- Створіть відомо-гарного тестового користувача і відомо-гарну конфігурацію клієнта і використовуйте їх як контрольну групу під час інцидентів.
AUTH_FAILED — це не вирок. Це підказка, що сервер ухвалив рішення. Ваше завдання — знайти компонент, який йому «прошепотів» це рішення.