Файл облікових даних чи керівний сокет OpenVPN: що скриптувати
auth-user-pass закриває запрошення акаунта; керівний сокет закриває всі чотири. Порівняйте поверхню, ціну скрипта і те, як кожен відмовляє в службі.
Скрипт, який запускає OpenVPN і так і не підключається, зазвичай не проблема мережі: клієнт стоїть біля запрошення, яке нема де намалювати. OpenVPN має рівно два підтримувані способи відповісти на це запрошення без людини — файл облікових даних за auth-user-pass і керівний сокет, — і вони не взаємозамінні. Файл коштує однієї директиви і відповідає на одне запрошення; сокет відповідає на будь-яке запрошення і дає всьому, що вміє відкрити порт loopback, неавтентифікований канал керування. Що з цього потрібне вашому розгортанню, залежить від того, яке запрошення справді блокує, і від того, який секрет ви можете дозволити собі залишити в спокої.
Назвіть запрошення, перш ніж вибирати механізм
Чотири запрошення виглядають на терміналі однаково. Пара облікових даних приходить із налаштування PAM або auth-user-pass-verify сервера, і на неї відповідає auth-user-pass. Парольна фраза закритого ключа належить файлу ключа і читається через --askpass або вводиться вручну. Пакет PKCS#12 запитує власний пароль. Автентифікація проксі використовує auth-файл, який приймає --http-proxy, а не облікові дані акаунта.
Коли OpenVPN працює як дочірній процес systemd, PHP або Node, термінала немає, тому кожне з цих запрошень блокує мовчки. Процес стоїть, журнал припиняється після рядка шифру, і модуль зрештою впирається в тайм-аут; ця тиша — причина, чому люди додають цикл повторів або sleep замість того, щоб подивитися, яке запрошення чекає. Відповісти на всі чотири може лише керівний сокет. Файл облікових даних відповідає на перше і ні на що більше.
auth-user-pass: один файл, одне запрошення
Файл містить ім'я користувача в першому рядку і пароль у другому, і нічого більше: без лапок, без назв ключів, без коментаря. Задайте режим 600 і зробіть власником той акаунт, який запускає openvpn; для служби це часто окремий користувач, а не ваша обліковка. Файл, що належить root, під /root — це різниця між командою, яка працює у вашій оболонці, і модулем, який падає під час завантаження.
Дві деталі перетворюють правильний файл на запрошення. Редактор, що зберігає CRLF, залишає приклеєне до пароля повернення каретки, тому сервер відхиляє пароль, який у файлі виглядає правильним; перевіряйте через cat -A або od -c, а не на око. А auth-user-pass без аргументу всередині профілю за задумом означає «спитати користувача», і друга директива в командному рядку може цього не перевизначити, бо профіль розбирається там, де лежить.
Порядок опцій — третя пастка, і він залежить від версії. Деякі збірки OpenVPN 2.4 ігнорують --auth-user-pass, коли він стоїть перед --config, тому ті самі дві опції в іншому порядку підключаються. Помістіть директиву в профіль або після --config у командному рядку і перед будь-якими іншими змінами пошукайте в профілі всі входження.
auth-nocache належить до цього механізму, але нічого не дає. Він обмежує, як довго клієнт тримає облікові дані в пам'яті, що допомагає після збою і зовсім не допомагає, коли файла немає. Перепідключення після завершення сесії на боці сервера знову читає файл, тому облікові дані, що працювали під час завантаження, можуть усе ж спливти посеред дня.
Керівний сокет: будь-яке запрошення, більше поверхні
Запустіть клієнт зі слухачем і явно заявіть, що запрошення повідомлятимуться на ньому, використовуючи директиви, задокументовані в посібнику OpenVPN 2.6:
management 127.0.0.1 3030
management-query-passwords
З bash тримайте з'єднання на вільному дескрипторі файла і відповідайте за назвою запрошення, а не за позицією, бо перепідключення може питати в іншому порядку:
exec 3<>/dev/tcp/127.0.0.1/3030
while read -r -u 3 line; do
case "$line" in
*"Need 'Auth' username/password"*)
echo 'username "Auth" alice' >&3
echo 'password "Auth" secret' >&3 ;;
*"Need 'Private Key' password"*)
echo 'password "Private Key" secret' >&3 ;;
esac
done
Межа — транспорт. Протокол керування — відкритий текст через TCP на loopback, тому слухача не можна публікувати на адресі LAN або тунелю, щоб до нього дістався віддалений контролер; віддалений контролер означає переспрямування SSH, а не ширше прив'язування. Демон спільноти приймає й лише одного клієнта керування за раз, тому GUI або монітор не можуть ділити сокет із вашим скриптом. Друге з'єднання відхиляється, а не ставиться в чергу, і збій виглядає як скрипт, що оглух.
Цей сокет — ще й канал керування. Без пароля керування все, що може підключитися до 127.0.0.1:3030, може читати стан, убити тунель або самостійно відповісти на запрошення. Пароль керування і файл облікових даних — секрети одного класу, і обидва заслуговують однакової уваги.
Що підходить розгортанню
Вибирайте файл облікових даних, коли єдине запрошення — пара облікових даних, клієнт працює як служба зі стабільним власником, і ви можете тримати файл 600 поза резервними копіями, які не контролюєте. Вибирайте керівний сокет, коли в грі парольна фраза ключа або пароль PKCS#12, коли обгортка вже наглядає за процесом, або коли треба спостерігати стан і запрошення під час налагодження перепідключення.
Дві умови рухають рішення. Якщо обгортка — /bin/sh, модуль systemd, що викликає бінарник напряму, або мінімальний контейнер, клей для сокета лише на bash недоступний, і файл — дешевша відповідь. Якщо секрет часто обертається, жоден файл не є добрим домом для нього: запитайте зв'язку ключів із маленької обгортки і дозвольте модулю викликати обгортку, що тримає обертання в одному місці, а пароль — поза історією оболонки.
Підстановка процесів стоїть між ними і не належить жодному. Однорядковий приклад нижче працює тому, що bash розкриває його до запуску openvpn, а не тому, що клієнт розуміє синтаксис:
openvpn --config client.ovpn --auth-user-pass <(printf "%s
%s
" "$USER" "$PASS")
Він ламається під /bin/sh, у модулі, що обходить оболонку, і в образах без bash або /dev/fd. Тримайте його для інтерактивних тестів і ніколи — як контракт, від якого залежить служба.
Захистіть секрет, потім перевірте за журналом
Обидва механізми залишають секрет, читабельний для процесу OpenVPN. Ніколи не кладіть пароль у командний рядок або у файл модуля, де ps і systemctl показують його кожному локальному користувачеві; передавайте шлях до файлу, а не значення в ньому. Там, де сертифікати можуть замінити пару облікових даних, це прибирає категорію запрошення, а не ховає її.
Правильний запуск показує завершення послідовності запрошень і вихід сесії на «Initialization Sequence Completed». Якщо клієнт зупиняється на тому самому запрошенні, зіставлення не вдалося: надрукуйте точні рядки, які надіслав сокет, перевірте лапки і назву запрошення та виправте шаблон замість додавання sleep. Тунель, що повідомляє про успіх і нічого не несе, — це проблема маршрутизації або push, а не облікових даних.
Потім перевірте перепідключення, а не лише перший запуск. Скиньте сесію на боці сервера або дочекайтеся її тайм-ауту; клієнт спитає знову, і саме там файл, який під час завантаження виглядав правильним, покаже, чи ще читається він тим акаунтом, що перепідключається.