OpenVPN не знаходить ca.crt, хоча профіль завантажується
Шлях до профілю не є базою для файлів усередині нього. Дізнайтеся, чому абсолютний --config усе одно не знаходить ca.crt і як запуск визначає відповідь.
Служба запускається, читає профіль без зауважень, а потім падає на рядку, який виглядає не пов’язаним із справою: вона не може відкрити ca.crt. У сертифікаті нічого не змінилося, а шлях до профілю в unit-файлі абсолютний. Саме це поєднання і є підказкою. Переданий вами шлях вказує на один файл, а імена всередині цього файлу розв’язуються зовсім в іншому місці, тому запуск, який виглядає цілком визначеним, усе ще може читати свої ключі з каталогу, якого ніхто не мав на увазі.
Збій має небагато причин, і їх варто розділити за порядком: базовий каталог, який процес справді мав, контекст запуску служби та права або пісочниця навколо файлу, коли шлях уже правильний. Кожна залишає інший слід — у unit-файлі, у процесі та у файловій системі.
Шлях до профілю — не базовий каталог
Уявіть процес, який стартує в /tmp і отримує /etc/vpn/prod/tenant-a.ovpn. Усередині цього профілю рядок ca ca.crt задає відносний шлях. Ніщо в аргументі, який знайшов профіль, не переписує це ім’я, тому процес шукає /tmp/ca.crt і повідомляє про відсутній файл.
Збиває з пантелику порядок помилок. OpenVPN спершу розбирає конфігурацію і відкриває вказані файли в міру досягнення, тому друкарська помилка в профілі повідомляється ще до того, як торкнуться будь-якого ключа, а відсутній сертифікат з’являється лише коли розбір доходить до цього місця. Отже, профіль, що завантажується, — доказ правильності синтаксису, а не того, що названі в ньому файли знайдено.
Що розділяє керівництво: --config і --cd
Керівництво OpenVPN 2.6 описує дві різні опції. Одна завантажує файл конфігурації. Інша змінює каталог процесу до читання конфігурації, ключа, скрипта та інших файлів і вимагає абсолютного каталогу без посилання на поточний.
openvpn --cd /etc/vpn/prod --config tenant-a.ovpn
Такий виклик — це форма, а не вказівка запускати чужий профіль. Що він дає — детермінізм: база для кожного відносного імені в ланцюжку вказана в команді, а не успадкована від оболонки чи менеджера, який запустив процес. Альтернатива так само придатна і часто краща для служби: залиште робочий каталог у спокої і зробіть кожен згаданий файл абсолютним усередині профілю.
Щоб ви не обрали, перевіряйте весь ланцюжок, а не перший збій. Профіль може підтягнути інший файл конфігурації, і відносні імена включеного файлу розв’язуються відносно того самого каталогу процесу, а не каталогу файлу, який їх включив. Шляхи журналів, файли автентифікації та допоміжні скрипти підкоряються тому самому правилу.
Служба стартує в іншому місці
Інтерактивна оболонка в каталозі профілю нічого не доводить про спакований unit-файл. Менеджери задають власний робочий каталог, а скрипт-обгортка може знову його змінити до запуску бінарника. Unit, що падає, — єдиний запуск, про який варто міркувати.
systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd
Друга команда показує каталог, який живий процес справді тримає, і це надійніше за unit-файл, коли задіяна обгортка. Якщо вони розходяться, відповідь — обгортка, а unit-файл — хибний слід.
Після пошуку: права, chroot і пісочниця
Правильний базовий каталог усе одно може дати те саме повідомлення, бо розв’язання і доступ — окремі кроки. Процесу потрібні права на виконання для кожного батьківського каталогу і права на читання файлу, а unit служби, що ховає частину файлової системи, змінює те, що процес узагалі може побачити.
Три поширені варіанти дають ідентичну помилку. Файл доступний лише root, а служба скидає привілеї перед його відкриттям. Unit задає захисне подання файлової системи, яке не містить каталогу профілю. Демон працює з chroot, тому шлях, що існує на хості, у цьому поданні відсутній.
Діагностуйте за власником файлу та ідентичністю процесу, а не послабленням прав. Робити приватний ключ доступним усім, щоб заглушити цю помилку, — це обмін гучного збою на тихий, а ключ — саме та частина каталогу, яку найменше хочеться розкривати.
Доведіть виправлення власним запуском
Перезапустіть справжній unit із каталогу, не пов’язаного з профілем, і поспостерігайте за тим самим рядком запуску. Потім переконайтеся, що процес під час роботи тримає потрібний каталог і що завантажений сертифікат — очікуваний.
systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager
Коли завантаження шляхів вдалося, автентифікація і маршрутизація залишаються окремими етапами зі своїми збоями, а з’єднання, яке піднімається, але не пропускає трафік, — інше розслідування. Виправлення тут стосується лише того, з якого каталогу прийшли файли, і воно має бути видно у виклику, а не згадуватися тим, хто останній раз запускав його вручну.
Якщо профіль розгортається менеджером конфігурації, покладіть туди і базовий каталог, або абсолютні імена файлів. Ручне виправлення на одному хості — версія цієї проблеми, що повертається після наступної перезбірки.