Одна директива 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
Коли етап розбору пройдено, наступна помилка стосуватиметься файлу, сертифіката або шифру, а не лексики, і це справжній прогрес. Збережіть робочу копію та нотатку в один рядок про те, що було з’єднано; те саме вставлення повториться в когось іншого в тій самій команді.