Сообщение говорит, что OpenVPN не может загрузить встроенный сертификат, а имя файла, которое вы держите в голове, утверждает обратное. То, что получил парсер, важнее того, что содержит файловая система, потому что директива cert принимает два совершенно разных типа значения. Один — это путь, который она открывает; другой — текст PEM, пришедший внутри конфигурации. Пока вы не знаете, какую форму получил работающий клиент, любое исправление — догадка.

Две формы хранения, одна директива

Директивы cert, key и ca принимают путь или встроенный блок. Когда значение — путь, OpenVPN открывает этот файл и читает объект с диска. Когда конфигурация содержит блок, ограниченный тегами cert, та же директива вместо этого использует содержимое между этими тегами, и отдельный файл не участвует.

Обе формы в итоге дают один и тот же тип объекта, поэтому работающая установка может переходить между ними без каких-либо других изменений. Профиль, несущий встроенный клиентский сертификат и закрытый ключ, самодостаточен, и его копирование на другую машину работает без копирования каталога сертификатов.

Обратное неверно. Положить client.crt рядом с профилем, который встраивает собственные данные, ничего не меняет, потому что ничто в конфигурации не ссылается на этот файл. Это самая частая причина, по которой файл, явно существующий, выглядит игнорируемым.

Как встроенный блок становится объектом

Встроенное содержимое извлекается из конфигурации и передаётся парсеру PEM как текст. Этот парсер ожидает обычные границы: строку BEGIN, полезную нагрузку base64 и соответствующую строку END. Если блок был обрезан неудачным копированием, обёрнут в HTML страницей загрузки или открыт в редакторе, нормализовавшем дефисы, парсер терпит неудачу на содержимом, которое выглядит присутствующим.

<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>

Поэтому и формулировка ошибки вводит в заблуждение. Слово встроенный описывает, куда посмотрел загрузчик, а не что он там нашёл. Файл, названный в конфигурации, и встроенный в неё объект могут дать одну и ту же жалобу, когда лежащие в основе байты непригодны.

Проверьте, какую форму загруженный профиль действительно использует, а не какой файл случайно открыл ваш редактор:

grep -nE '^(ca|cert|key) |^<(ca|cert|key)>' client.ovpn

Как разрешается ссылка на путь

Значение пути открывается относительно рабочего каталога клиента, а не каталога, содержащего конфигурацию. Под systemd этот рабочий каталог — то, что задаёт юнит, а интерактивный запуск из вашей оболочки наследует нечто совсем другое. Поэтому один и тот же файл конфигурации может работать при ручной проверке и отказывать как служба.

Относительные пути наследуют ту же неоднозначность. Увидев голое имя файла, спросите, каков текущий каталог процесса в продакшене, вместо того чтобы предполагать совпадение с вашим терминалом.

Для сертификата, хранящегося отдельно, автономный разбор подтверждает объект, прежде чем вы будете отлаживать что-либо выше него:

openssl x509 -in client.crt -noout -subject -issuer -dates
openssl pkey -in client.key -noout -check

Эти команды доказывают, что файлы читаемы и структурно корректны. Они не доказывают, что партнёр доверяет издателю, что сертификат всё ещё в пределах срока действия или что ключ принадлежит ему.

Что ошибка парсера может и чего не может сказать

Сбой разбора локализует проблему на одном входе и одном этапе. Он не говорит, какую из двух форм хранения использовал клиент, и не говорит, был бы объект принят. Это отдельные вопросы с отдельными доказательствами.

Когда разбор успешен, следующий сбой относится к более позднему этапу. Отказ в доверии, несовпадение назначения или несовпадение ключа сообщает партнёр или уровень TLS, а не загрузчик. Повторная замена одного и того же файла не сдвинет эту ошибку.

Держите чувствительную половину вне публичных отчётов, пока ведёте расследование. Делитесь именами директив, текстом ошибки и структурой блока, удалив материал ключа и любую идентифицирующую нагрузку. Руководство openvpn(8) описывает обе формы файловых директив и поведение рабочего каталога, стоящее за ними.

Похожие статьи