Один Pi, два экземпляра OpenVPN: что читает каждый модуль
Два демона OpenVPN на одном Pi читают разные файлы конфигурации и выходят через разные перехватчики. Сопоставьте каждый экземпляр, затем отдельно проверьте путь полезной нагрузки.
Посчитайте процессы OpenVPN, прежде чем трогать профиль. Pi, который принимает роуминговых пользователей и одновременно подключается к вышестоящему сервису, запускает два демона, и каждый читает файл конфигурации, выбранный набранным вами именем экземпляра. Шаблоны пакета затем дают каждому демону свой рабочий каталог, свой файл состояния выполнения и своё туннельное устройство. Если разделить это неправильно, вы проведёте вечер, меняя верную настройку в файле, который работающий процесс никогда не открывает.
Каждое имя экземпляра выбирает свой файл
В файлах модулей, поставляемых с OpenVPN 2.6, аргументы запуска содержат подстановку экземпляра, которая заполняется текстом после знака @. Шаблон сервера работает из каталога конфигурации сервера и разрешает свой аргумент относительно %i.conf там, а шаблон клиента делает то же самое из каталога клиента. Поэтому [email protected] читает admits.conf в каталоге сервера, а [email protected] читает uplink.conf в каталоге клиента, и ни одно из этих имён не имеет никакого смысла в другом каталоге.
Проверьте соответствие на самой машине, а не предполагайте, что пакет сохранил вышестоящие значения по умолчанию. Drop-in дистрибутива может полностью заменить рабочий каталог или аргумент конфигурации.
systemctl cat [email protected]
systemctl cat [email protected]Прочитайте строку WorkingDirectory и аргумент конфигурации в этом выводе, потому что только включённый модуль решает, какой файл загружается. Drop-in, добавляющий --config к ExecStart, побеждает шаблон даже тогда, когда путь шаблона выглядит правильным. Запрашивайте пути фрагментов и drop-in, когда хотите узнать, действует ли локальное переопределение. Если обе роли разрешаются в один файл, у вас один процесс, который пытается быть и сервером, и клиентом, и более поздний параметр в этом файле тихо побеждает.
Локальный транспорт и перенаправляемая нагрузка попадают в разные перехватчики
Зашифрованное соединение сервера с каждым роуминговым пользователем создаётся на самом Pi, поэтому его внешние ответы уходят через локальный перехватчик вывода. Соединение клиента с вышестоящим партнёром тоже является локально созданным выводом, хотя и достигает удалённой сети. Перенаправляемая полезная нагрузка — третья категория, и ядро сопоставляет её только после того, как уже выбрало исходящее устройство для пакета.
| Flow | Hook that sees it | What to inspect |
|---|---|---|
| Roaming user handshakes to the server | Local input and local output | Listener socket, bind address, rule admitting the UDP port |
| User payload leaving through the upstream tunnel | Forward | IPv4 forwarding switch, selected route, permission rule, any translation |
| Pi's own connection to the upstream peer | Local output | Underlay route to the provider endpoint, not the tunnel route |
Правило, сопоставляющее исходящий интерфейс внутри цепочки forward, может разрешить или отбросить пакет, который маршрутизация уже назначила этому интерфейсу, но оно никогда не выбирает интерфейс. Когда один узел завершает один туннель и начинает другой, политика, отправляющая пользовательскую нагрузку в вышестоящий туннель, и политика, защищающая собственные зашифрованные ответы Pi, — два отдельных решения. Они случайно оказываются на одной физической сетевой карте, поэтому их путают.
Это различие объясняет частый частичный отказ. Пользователи подключаются, рукопожатие завершается, а их трафик всё равно уходит не туда, потому что рукопожатие было локальным, нагрузка — перенаправляемой, и проверено было только одно из двух.
Импортированный маршрут может проглотить ответы вашим пользователям
Настройка безопасности клиентского профиля решает, что вышестоящая сторона может протолкнуть в таблицу маршрутизации Pi, и широкое перенаправление — это вариант, превращающий работающий узел с двумя ролями в сломанный. Если протолкнутый маршрут покрывает публичные адреса роуминговых пользователей, ответы, которые сервер создаёт для них, могут пойти по новому маршруту в вышестоящий туннель вместо выхода через нижний уровень. Люди часто убеждаются, что туннель до провайдера ещё работает, и на этом останавливаются, потому что этот трафик — собственный транспорт туннеля, и он продолжает течь, пока всё остальное ведёт себя неправильно.
Политика на основе источника или метки — это способ держать два потока раздельно. Опция mark Linux в OpenVPN помечает собственные зашифрованные пакеты демона меткой межсетевого экрана, которую правило маршрутизации затем может отправить в отдельную таблицу. Адреса источника работают так же хорошо, когда внешние ответы сервера всегда уходят с одного адреса нижнего уровня. Любому из подходов нужны действительные маршруты в выбранной таблице и исключение для точки присутствия провайдера, иначе сам туннель перестаёт подниматься.
Прежде чем писать хоть одно правило, спросите у ядра, какой путь ответ действительно выберет. Адреса ниже — заполнители для адреса нижнего уровня Pi и публичного адреса одного роумингового пользователя.
ip rule show
ip route get 198.51.100.7 from 192.0.2.10Проверьте разделение, затем останавливайте по одной роли
Проверяйте три потока по отдельности, потому что работающее рукопожатие ничего не доказывает про два других. Примите новое входящее соединение, отправьте одно разрешённое приложение через вышестоящий выход и убедитесь, что оба процесса по-прежнему достигают своих партнёров.
Затем остановите роль клиента и посмотрите, что сохраняет роль сервера. Это самый дешёвый способ найти правило маршрута или метки, которое предназначалось одному экземпляру, а применилось к обоим.
systemctl stop [email protected]
systemctl status [email protected] --no-pager
ss -lunp | grep openvpn
journalctl -u [email protected] -n 20 --no-pagerВы хотите увидеть, что слушатель по-прежнему привязан, туннельное устройство на месте, а журнал свободен от новых ошибок, пока роль клиента остановлена. Если остановка клиента обрывает и ответы сервера существующим пользователям, две роли делят нечто, что должно было быть ограничено одной из них. Записывайте, какой экземпляр, какой файл конфигурации и какого владельца потока затронуло каждое изменение, иначе следующий человек, отлаживающий этот узел, повторит то же открытие с нуля.