Одна директива OpenVPN на строку, и почему перенос строки обманывает
Мягкий перенос на экране — не перевод строки в файле. Проверьте настоящие переводы строк, прежде чем заменять испорченный раздел чужим шаблоном.
Профиль, который раньше запускался, теперь завершается ошибкой опций, а строка, которую цитирует парсер, выглядит на экране совершенно разумно. Вот ловушка: файл конфигурации — это список физических строк, в каждой из которых один ключ опции и её аргументы, и длинная строка, перенесённая редактором, выглядит неотличимо от двух строк, пока не посмотришь на байты. Ни сеть, ни сертификат, ни туннель в этом классе сбоев не участвуют. Две строки, которые на экране выглядят одинаково, могут различаться одним байтом.
Выполняйте проверки ниже по порядку и остановитесь на первой неудачной. Каждая дешевле следующей, и каждая исключает своё объяснение.
Одна строка — одна директива
Парсер читает строку, берёт первое слово как опцию и считает остаток аргументами этой опции. Поэтому строка вроде cert server.crt port 1194 — это не две инструкции подряд. Это одна опция cert с тремя аргументами, и третий не является именем файла, которое опция принимает. Читать ошибку как отсутствующий перевод строки правильно; читать её как отсутствующую директиву — нет.
# malformed: one option, three arguments
cert server.crt port 1194
# intended: two options, one argument each
cert server.crt
port 1194
Эти две исправленные строки — фрагмент, а не конфигурация. Они существуют, чтобы показать, где проходит граница. Каждая обычная директива в профиле подчиняется тому же правилу, и строка, соединяющая две из них, даёт либо ошибку аргумента, либо значение, которого опция не ожидала.
Докажите, что перевод строки настоящий
Редакторы переносят строки для отображения. Некоторые ещё и вставляют жёсткие переводы при вставке, а некоторые нет, поэтому один и тот же визуальный результат может происходить из двух очень разных файлов. Покажите окончания строк и посчитайте строки, прежде чем что-либо менять. Измерение стоит одной команды; догадка стоит вечера.
cat -A /etc/openvpn/server/lab.conf | sed -n '10,20p'
awk 'NR>=10 && NR<=20 {printf "%d:%s\n", NR, $0}' /etc/openvpn/server/lab.conf
В первом выводе каждый настоящий перевод строки отображается как маркер $, поэтому перенесённая, но не разорванная строка не показывает маркера там, где переносится ваш экран. Вторая команда печатает строки с номерами — это самый быстрый способ сравнить то, что сообщает парсер, с тем, что содержит файл.
Лишние пробелы тоже не создают директиву. Отступ — косметика, и строка, начинающаяся с пробела, остаётся той же единственной опцией. Если сообщение об ошибке указывает номер строки, читайте именно эту строку, а не абзац, к которому она относится.
Цитируйте путь, а не список директив
Кавычки нужны для аргументов с пробелами, а не для группировки опций. Путь к сертификату с пробелом требует собственных кавычек; две директивы, разделяющие одну пару кавычек, по-прежнему одна испорченная строка.
cert "/etc/openvpn/pki/lab certs/server.crt"
key "/etc/openvpn/pki/lab certs/server.key"
Проверяйте имена опций одновременно с разметкой, потому что склеенная строка может дать правдоподобно выглядящий токен, которого никогда не существовало. Директива порта — port; профиль, использующий для той же идеи что-то другое, потерпит неудачу даже после исправления границ строк. Если имя кажется незнакомым, сравнивайте его со списком опций вашей версии, а не с примером с форума.
Храните встроенные блоки как блоки
Профили могут нести сертификаты и ключи встроенно, и эти блоки — данные, а не конфигурация. Строки PEM внутри блока не являются опциями, которые нужно выравнивать, переотступать или соединять, и маркеры блока должны оставаться на своих строках.
Относитесь к встроенному блоку как к непрозрачной области: исправьте строки опций вокруг него, оставьте его содержимое байт в байт нетронутым и никогда не вставляйте его в публичную ветку поддержки. Если инструмент форматирования переписал блок, восстановите его из своей PKI, а не чините вручную.
Исправляйте наименьший участок, а не шаблон
Заманчивое исправление — заменить весь файл конфигурацией из руководства, которое «работает». Это меняет одну испорченную строку на набор изменений политики, которые никто не проверял: другие параметры DH, настройки сжатия, выбор шифра, дублирующиеся слушатели. Исходная проблема мала и локальна, а замена — ни то ни другое.
Скопируйте профиль в защищённый рабочий файл, исправьте границы строк в этой копии и дайте штатному владельцу службы загрузить её. Затем запустите экземпляр и прочитайте первую ошибку, если она есть, с самого начала.
openvpn --config /etc/openvpn/server/lab.conf --verb 3 --log /tmp/parse.log
grep -n 'Options error' /tmp/parse.log
Когда этап разбора пройден, следующая ошибка будет о файле, сертификате или шифре, а не о лексике, и это настоящий прогресс. Сохраните рабочую копию и заметку в одну строку о том, что было соединено; та же вставка повторится у кого-то ещё в той же команде.