На Pi працюють два процеси OpenVPN, які одночасно приймають роумінгових користувачів і досягають провайдера вище, і вони майже нічого не ділять, крім обладнання. Один слухає вхідні тунелі, другий телефонує назовні. Кожен читає свій каталог, і кожен має свій режим відмови. Перезапуск не того — найпоширеніший спосіб, яким виправлення клієнта натомість валить слухача.

Узгодьте назву модуля з каталогом, який він завантажує

Upstream 2.6 постачає два шаблонні модулі, [email protected] і [email protected]. Шаблон сервера запускається в /etc/openvpn/server і завантажує звідти %i.conf. Шаблон клієнта запускається в /etc/openvpn/client. Екземпляр з іменем roaming може існувати в обох місцях одночасно — як сервер і як клієнт, з двома незв'язаними конфігураціями і без будь-якого зв'язку між ними, крім рядка.

Питайте systemd, а не файлову систему, бо пакувальники додають додаткові файли, які можуть змінити робочий каталог або аргументи, які отримує бінарник.

systemctl list-units --type=service 'openvpn-*@*'
systemctl cat [email protected]
systemctl show -p WorkingDirectory -p ExecStart [email protected]

Перша команда перелічує кожен створений модуль, включно з тими, що впали й залишилися завантаженими. Друга друкує файл модуля разом із будь-яким перевизначенням. Третя — найшвидший спосіб побачити два факти, що вирішують питання: каталог, у якому запускається процес, і шлях конфігурації, який йому передали.

Вирішуйте за напрямком пакетів, а не за назвою інтерфейсу

Екземпляр сервера володіє слухаючим сокетом і приймає з'єднання. Його шифрований транспорт — це локальний вхід і локальний вихід на Pi, а трафік, який він пересилає для користувачів, іде шляхом пересилання і підкоряється іншому набору правил. Екземпляр клієнта в цьому сенсі не має слухача: він телефонує партнеру, тому його шифрований транспорт — локальний вихід до нижнього рівня.

Ця різниця каже, куди належить правило. Правило, що збігається з інтерфейсом у ланцюгу пересилання, лише дозволяє трафік, який маршрутизація вже вибрала; воно ніколи не вибирає маршрут. Коли пакети роумінгового користувача виходять не тим шляхом, ланцюг для перевірки — forward, а не output.

Подивіться на сокети, перш ніж теоретизувати. Сервер, прив'язаний до udp/1194, показує слухаючий сокет. Клієнт показує асоціацію з адресою провайдера і нічого, що слухає.

ss -lunp | grep openvpn
ss -unp state established '( dport = :1194 or sport = :1194 )'

Маршрут за замовчуванням одного екземпляра може перехопити відповіді іншого

redirect-gateway, який проштовхує верхній клієнт, встановлює маршрут за замовчуванням, що конкурує з усім іншим на машині, включно з відповідями, які сервер надсилає роумінговим користувачам. OpenVPN робить виняток для власної адреси партнера, щоб тунель залишався доступним, але цей виняток нічого не каже про телефон у готельній мережі.

Симптом зазвичай асиметричний. Рукостискання завершується, клієнт повідомляє про з'єднання, і трафік помирає після першого пакета відповіді. Маршрутизація політик на основі джерела або мітка пакета, встановлена на екземплярі сервера за допомогою --mark, тримають два потоки окремо; жодне з цього саме по собі не є повним набором правил, і обом потрібні чинні маршрути в таблиці, яку вони вибирають.

Перевіряйте локальне рішення, а не стан тунелю, бо ядро вибирає джерело й інтерфейс раніше, ніж OpenVPN побачить пакет.

ip route get 203.0.113.44
ip rule show

Перезапустіть одну роль і доведіть, що друга вижила

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

Запишіть умову зупинки до зміни: втрата верхнього тунелю блокує роумінгових користувачів чи відкочується на власний аплінк Pi? DNS і IPv6 також потребують чіткої відповіді, бо просунутий резолвер часто живе довше за маршрут, який зробив його корисним.

systemctl restart [email protected]
systemctl is-active [email protected]
journalctl -u [email protected] -n 20 --no-pager

Приймайте зміну лише коли три речі істинні одночасно: нове вхідне з'єднання завершується, переісланий застосунок досягає призначення через передбачений вихід, і обидва процеси все ще повідомляють про свого очікуваного партнера. Якщо одне з трьох не вдається, ви змінили не той екземпляр або не той маршрут, і наступний крок — перечитати модуль, а не перезапускати щось інше.

Схожі статті