Застосунок, прив’язаний до адреси VPN, усе одно йде не тим маршрутом
Сокет, прив’язаний до адреси VPN, дотримується звичайного маршруту за замовчуванням. Перевірте належність адреси та пошук з урахуванням джерела, перш ніж додавати правила політики.
Застосунок прив’язується до адреси VPN, а з’єднання все одно виходить через звичайний маршрут за замовчуванням. У bind нічого не зламалося: він зробив саме те, що робить bind. Прив’язка сокета до локальної адреси вибирає адресу джерела, яку ядро записує в заголовок. Вона не встановлює маршрут і не створює правило політики, яке надсилало б пакети з цим джерелом у певний тунель.
Решта цієї настанови — порядок перевірки, який я використовую, разом із командою, що дає кожне спостереження.
Що насправді вирішує прив’язка
Прив’язка призначає сокету локальну адресу. Далі ядро виконує той самий пошук маршруту, який виконало б інакше, якщо правило політики не змінить, яку таблицю читає цей пошук.
Тому пакет може вийти з адресою джерела VPN через фізичний інтерфейс. На тому боці він приходить із приватного діапазону, якого мережа ніколи не чекала на цьому шляху, зворотний трафік не має маршруту назад, і з’єднання зависає або скидається.
Довідник зі сокетів IP у Linux описує семантику прив’язки. Половина про маршрутизацію живе в ip-rule і ip-route, і це окремі довідники не випадково.
Переконайтеся, що адреса належить цьому простору імен
Адреса, до якої можна прив’язатися, має існувати на інтерфейсі всередині мережевого простору імен, у якому працює застосунок. Адресу партнера, адресу шлюзу або адресу, що існує лише в іншому просторі імен, прив’язати не можна, і виклик завершується помилкою EADDRNOTAVAIL.
ip -br addr show
ip netns identify <pid>
ss -tanp | grep <port>Виконайте ці три команди в тому самому контексті, що й застосунок: той самий простір імен і, якщо вдасться, той самий користувач. Стара схема net30 не доводить, яку адресу поточна топологія призначила клієнту. Читайте інтерфейс, який справді піднятий.
Прочитайте пошук для цього джерела й призначення
Одна команда відповідає на питання, на яке прив’язка не відповіла:
ip route get 203.0.113.10 from 10.8.0.2
ip rule showПерший рядок друкує маршрут, яким піде пакет від цього джерела до цього призначення, включно з вихідним інтерфейсом і бажаним джерелом. Якщо там названо фізичний інтерфейс, прив’язка й маршрут суперечать одне одному, і пакет вийде з джерелом, до якого шлях не може повернутися.
Далі ip rule show підкаже, чи якесь правило вибрало б іншу таблицю. Пріоритети тут важливі, бо перемагає перше відповідне правило, а правило, що ловить усе вище за ваше, робить ваше правило невидимим.
Установлюйте правило політики, лише якщо це задум
Маршрутизація за джерелом — це свідомий задум, а не лагодження для одного застосунку. Якщо власник політики хоче, щоб трафік із підмережі тунелю використовував тунель, правило належить до його конфігурації, а не до одноразової команди на вашому ноутбуці.
Робоча форма — окрема таблиця з маршрутом за замовчуванням через тунель плюс правило, що надсилає діапазон джерел VPN у цю таблицю. Додайте винятки, потрібні задуму, бо таблиця лише з тунельним маршрутом за замовчуванням перехопить призначення, які мають залишатися локальними або доступними фізичним шляхом.
ip route add default dev tun0 table 100
ip rule add from 10.8.0.2 table 100 priority 100
ip route get 203.0.113.10 from 10.8.0.2Відкотіть через ip rule del і ip route flush table 100. Усе, додане в такий спосіб, зникає після перезавантаження, якщо його не запише менеджер; це водночас властивість безпеки й причина не тримати єдину копію в історії своєї оболонки.
Перевірте трьома спостереженнями
Запишіть джерело, яке запитав застосунок, маршрут, який вибрав пошук, і джерело, яке сервер справді побачив.
Ці три можуть розходитися, і кожна розбіжність указує в інше місце. Захоплення на інтерфейсі тунелю доводить, що пакет вийшов із правильним джерелом. Захоплення на фізичному інтерфейсі доводить, що він вийшов не тим шляхом. Лише вигляд із боку сервера доводить шлях від початку до кінця.
Якщо застосунок пропонує прив’язку до пристрою або режим маршрутизації для кожного застосунку, розглядайте це як інший механізм з іншими обмеженнями. Схожі на вигляд налаштування не всі ведуть до того самого рішення ядра.