client-config-dir игнорируется после того, как OpenVPN стал службой
Относительный client-config-dir разрешается относительно рабочего каталога демона. Прочитайте unit, проверьте права на пути, затем подтвердите поиск в журнале.
Туннель поднимается и клиент подключается, но фиксированный адрес и проталкиваемые маршруты, которые вы задали для этого одного пользователя, отсутствуют. В журнале нет “file not found”, и именно это отправляет людей перевыпускать сертификаты. В большинстве таких случаев демон работает из другого каталога, чем оболочка, в которой вы тестировали, и client-config-dir так и не был разрешён так, как вы предполагали. Исправление — это коррекция пути, а не сброс учётных данных.
Прочитайте unit, прежде чем трогать конфигурацию
Начните с процесса, который реально работает, а не с файла, который вы правили. Спросите systemd о строке запуска, рабочем каталоге и учётной записи, на которую он переходит. Эти три ответа объясняют большинство отказов этого класса:
systemctl show openvpn-server@server -p ExecStart -p WorkingDirectory -p User -p RootDirectoryПустой WorkingDirectory означает, что unit стартует в /, поэтому относительный client-config-dir ccd ищется в /ccd. Такого каталога почти никогда нет, и демон не считает его отсутствие фатальным.
Сравните с интерактивным запуском, который вы использовали при тестировании, где текущим каталогом вашей оболочки, скорее всего, был каталог конфигурации. Тот же файл, те же ключевые слова, два разных результата.
Относительно чего разрешается относительный путь
Ключевое слово разрешается относительно рабочего каталога процесса в момент использования опции. Это не значит “рядом с файлом конфигурации, который я передал через --config”. OpenVPN охотно прочитает конфигурацию из абсолютного пути и всё равно разрешит относительные значения в другом месте, и именно в этом ловушка. Руководство OpenVPN 2.6 излагает правило в разделе --client-config-dir и ещё раз в разделе --cd.
Ключевое слово cd меняет этот контекст до чтения других файлов, поэтому unit, который задаёт cd /etc/openvpn/server и затем client-config-dir ccd, разрешается в /etc/openvpn/server/ccd. Если вы добавляете cd, проверьте порядок директив и помните, что это влияет на каждую другую относительную ссылку в том же файле.
Пройдите путь глазами учётной записи демона
Путь может быть правильным и при этом нечитаемым. После сброса привилегий демон уже не root, поэтому каждый родительский каталог требует права поиска для этой учётной записи, а сам клиентский файл — права чтения. Одного недостающего бита выполнения на родительском каталоге достаточно, чтобы скрыть файл, и ошибка проявляется только как клиент, который тихо получает пул по умолчанию.
namei печатает права каждого компонента по порядку, что быстрее, чем проверять каталоги по одному:
namei -l /etc/openvpn/server/ccd/client1Затем проверьте чтение от имени учётной записи службы, а не от своего:
runuser -u openvpn -- test -r /etc/openvpn/server/ccd/client1 && echo readableЕсли unit использует chroot, каталог должен существовать внутри тюрьмы, а путь в конфигурации интерпретируется после применения chroot. Файл, который есть на хосте вне тюрьмы, изнутри невидим.
Подтвердите поиск вместо догадок
Поднимите уровень журнала на один перезапуск и прочитайте, что сервер говорит об опциях, специфичных для клиента. При verb 4 демон сообщает импортированную конфигурацию для каждого клиента, поэтому отсутствующая строка — прямое доказательство того, что для этого соединения не был прочитан ни один файл.
openvpn --config /etc/openvpn/server.conf --verb 4 --client-config-dir /etc/openvpn/server/ccdЗапустите это на переднем плане на свободном порту и подключите одного клиента. Это полностью убирает systemd из картины: если переопределения появляются здесь, а не под службой, разница в контексте unit, а не в файле.
Решите, что должно происходить, когда ни один файл не подходит. Без ccd-exclusive клиент принимается только с глобальными настройками пула, и это тот самый тихий отказ, описанный выше. С ней отсутствующий файл становится отклонённым соединением, и такое отклонение легче заметить, но труднее отладить под нагрузкой.
Исправьте, перезапустите, проверьте
Сделайте каталог абсолютным в конфигурации и оставьте так. Относительные пути безопасны только тогда, когда unit фиксирует рабочий каталог, а фиксация — это лишняя движущаяся часть, которую кто-то позже уберёт.
client-config-dir /etc/openvpn/server/ccd
ccd-exclusiveПерезапустите экземпляр, заново подключите одного известного клиента и прочитайте адрес, который он получил, вместе с протолкнутыми к нему маршрутами. Если адрес совпадает со строкой ifconfig-push в файле этого клиента, поиск сработал. Если клиент всё ещё попадает в общий пул, вернитесь к количеству строк журнала: ноль импортов означает, что путь или идентичность неверны, один импорт с неверным содержимым означает, что вы правите другой файл, не тот, который читает демон.
Откатитесь, восстановив предыдущие unit и конфигурацию вместе, затем перезапустите. Сертификаты для всего этого перевыпускать не нужно, и именно отношение к проблеме каталога как к проблеме учётных данных превращает пятиминутное исправление в окно обслуживания.