OpenVPN читає пароль із термінала, а не з stdin
Де OpenVPN насправді читає пароль, чому файл на stdin не працює і три підтримувані способи скриптового входу в Linux і macOS.
OpenVPN запитує ім'я користувача та пароль на керівному терміналі, а файл, перенаправлений на стандартний вхід, — не цей термінал. Саме ця деталь пояснює скрипт, який зависає, хоча пароль лежить прямо в каналі. Запрошення малює клієнт, а читання йде з термінального пристрою, тому перенаправлення stdin нічого не змінює. Подайте клієнту дані через один із його задокументованих входів, і той самий скрипт підключиться з першої спроби.
Три входи покривають майже всі випадки, і кожен відмовляє по-своєму. Вибирайте за запрошенням, яке клієнт справді показує, а не за варіантом, який найлегше заскриптувати.
Запрошення надходить не з stdin
Коли OpenVPN потрібні облікові дані, він відкриває керівний термінал і читає звідти. Тому інтерактивна перевірка виглядає нормально, а та сама команда під cron або у unit-файлі стоїть без руху, із запрошенням, записаним у журнал, куди ніхто не дивиться. Деякі збірки відкочуються на стандартний вхід, коли термінала немає, і ця неузгодженість гірша за жорстку помилку, бо ховає проблему до розгортання.
Перевірте середовище, перш ніж писати будь-який код: запустіть клієнт під тим самим користувачем, з тим самим stdin, що й планувальник чи менеджер служб. Якщо запрошення так і не з'являється в журналі, а процес не просувається, щось чекає на термінал, якого немає.
Перший вхід: файл облікових даних із двох рядків
Опція автентифікації приймає шлях, і файл містить рівно два рядки: спочатку ім'я користувача, потім пароль, і більше нічого. Вказуйте шлях явно, а не покладайтеся на типову назву файлу, бо забутий файл з обліковими даними в робочому каталозі — це спосіб, у який до вжитку потрапляє не той обліковий запис. Встановіть режим 0600 і передайте власність обліковому запису, який запускає клієнт.
Клієнт читає цей файл один раз під час запуску, тож зміна пароля означає перезапуск процесу. Зазвичай це саме те, що потрібно, і це місце в runbook поряд із процедурою зміни.
Другий вхід: askpass для парольної фрази ключа
Захищений парольною фразою приватний ключ викликає друге, інше запрошення, і в нього є власна файлова відповідь: опція askpass читає фразу з першого рядка файлу. Для тунелів на основі SSH еквівалент — програма askpass, яку запускає клієнт і чий стандартний вивід стає секретом.
Жодна з форм не кладе секрет у список аргументів, і обидві залишають його існувати файлом або виконуваним файлом, що його друкує. Захист — це права файлу й власність процесу, а не неочевидність. Помічник, що повторює зашитий у код рядок, — це секрет із зайвими кроками.
Третій вхід: власний CLI портального клієнта
Корпоративні клієнти зазвичай постачають точку входу в командному рядку, яка підключається до іменованого порталу без вікна, і це підтримуваний шлях. У Linux клієнт GlobalProtect надає операції підключення та імпорту сертифіката через свій CLI, а порталам з автентифікацією за сертифікатом потрібен крок імпорту, перш ніж автоматичне підключення запрацює. Віддавайте перевагу йому перед синтезованими натисканнями клавіш: ви отримуєте справжній код виходу, відсутність залежності від фокуса вікна, і він переживає заблокований екран.
Якщо першому підключенню все ще потрібна людина, щоб прийняти сертифікат, автоматизація не завершена. Зробіть імпорт під час налаштування і запишіть його як передумову.
Коли потокові потрібен псевдотермінал
Послідовність, яка запитує пароль, а потім одноразовий код, не має одного файлу для читання. Драйвер термінала на кшталт Expect — правильний інструмент, бо він чекає на кожен шаблон по черзі, і йому потрібен запущений процес, перш ніж він взагалі щось зіставить.
Переважають дві помилки. Скрипт, що чекає на запрошення, не запустивши клієнт, чекає вічно, а Tcl — не оболонка, тому арифметика оболонки, написана всередині блоку expect, не обчислюється так, як читається. Тримайте прапорець налагодження ввімкненим, поки будуєте шаблони, потім вимкніть його.
Секрети, що витікають, і де вони ховаються
Усе, передане аргументом, видно у списку процесів, тому облікові дані належать файлу або помічнику, але не командному рядку. Одноразові коди витрачаються за задумом і мають створюватися для кожної спроби. Журнали збоїв часто несуть ім'я користувача, а іноді й більше, тож відредагуйте їх, перш ніж кудись надсилати, і тримайте секрет поза самим профілем, бо конфігураційний файл із вбудованим паролем потрапляє в заявки та репозиторії. Зміна облікового запису тоді означає полювання на кожну копію, і саме цієї ціни уникає така схема.
Перевірте вибрані входи, потім підключіть їх до unit-файлу або планувальника, який справді запускатиме клієнт. Тунель живе рівно стільки, скільки живе цей процес.