Окремий вихід: пул VPN на usb0, трафік шлюзу на eth0
Переспрямовані клієнти VPN можуть виходити через usb0, а шлюз зберігає свій маршрут за замовчуванням на eth0. Побудуйте повну вибрану таблицю, а потім зробіть так, щоб збій закривав, а не пропускав.
Клієнти підключаються й автентифікуються, а потім їхній трафік виходить через неправильний висхідний канал, бо єдиний маршрут за замовчуванням на машині належить самому шлюзу. Заміна цього маршруту зламала б власні оновлення машини й доступ до керування, тож вибір має бути вужчим за «весь трафік». Робоча форма — правило політики, прив'язане до внутрішньої адреси джерела пулу клієнтів і спрямоване на другу таблицю маршрутизації, якій належить альтернативний WAN. Далі контрольний список стосується повноти й поведінки під час збою, а не самого правила.
Переконайтеся, що адреса джерела доживає до рішення про маршрутизацію
Правило політики, що відповідає діапазону джерела, спрацьовує лише тоді, коли пакет у момент пошуку ще несе це джерело. Переспрямований клієнтський трафік робить так, доки щось вище не переписало його до маршрутизації. Трафік, який створює сам шлюз, цього не робить, і саме тому власний маршрут шлюзу за замовчуванням може залишатися на місці.
Тут локальні тести вводять в оману. Запущений на шлюзі curl — це локально створений потік з адресою шлюзу, тож він бере основну таблицю й нічого не доводить про шлях клієнта. Перевіряйте з підключеного клієнта або створюйте трафік із джерелом, яке справді належить пулу.
Почніть із запису реальних значень: префікса пулу, інтерфейсу тунелю, який його несе, адреси й наступного стрибка другого WAN, а також номера таблиці, яку ви збираєтеся використовувати. Очистьте старі правила будь-якої попередньої спроби, перш ніж додавати нові, бо дубльовані правила з різними пріоритетами дають збої, що виглядають випадковими.
Побудуйте вибрану таблицю, яка є повною
Таблиця — це не маршрут за замовчуванням із другом. Їй потрібно достатньо маршрутів, щоб кожен пошук розв'язувався всередині неї, включно з підключеним маршрутом для підмережі WAN, щоб наступний стрибок був досяжним. Для пулу 10.77.0.0/24 на tun1, адреси WAN 203.0.113.20/24 з наступним стрибком 203.0.113.1 і таблиці 600:
ip -4 route replace 203.0.113.0/24 dev usb0 src 203.0.113.20 table 600
ip -4 route replace 10.77.0.0/24 dev tun1 table 600
ip -4 route replace default via 203.0.113.1 dev usb0 table 600
ip -4 rule add priority 1500 from 10.77.0.0/24 lookup 600
Правило стоїть на пріоритеті нижче за будь-яке наявне правило, що перехоплює все, тож відповідні клієнти спершу потрапляють до таблиці 600, а все інше провалюється до основної таблиці. Довідник ip-rule повністю описує модель упорядкованого пошуку й синтаксис селектора.
Потім подумайте, чого таблиця не містить. Призначення, що має маршрут лише в основній таблиці, наприклад підмережа керування, доступна через eth0, не буде знайдене в таблиці 600 і не повернеться до основної, щойно там з'явиться маршрут за замовчуванням. Якщо ці шляхи важливі, додайте їх до вибраної таблиці явно, що зазвичай і є правильною відповіддю для таблиці виходу VPN.
Тримайте власний трафік слухача поза політикою
Слухач OpenVPN має власне зовнішнє з'єднання, яке йде тим висхідним каналом, яким клієнт до нього дістався. Цей трафік має зберегти зворотний шлях, з яким прийшов, а широке правило, що охоплює публічну адресу сервера або весь інтерфейс тунелю, може затягти його до альтернативної таблиці. Обмежте правило внутрішнім пулом і більше нічим.
Фільтрація зворотного шляху заслуговує на погляд із тієї ж причини. Коли відповіді клієнтам виходять через usb0, а запит прийшов іншим каналом, суворе налаштування rp_filter може відкинути пакети, які політика маршрутизації вважає чинними. Перевірте чинні значення sysctl на обох інтерфейсах, перш ніж робити висновок, що правило не спрацювало.
Порядок важливий і щодо всього іншого на машині. Мости Docker, другий VPN і будь-які наявні правила з образу постачальника додають пріоритети, тож прочитайте повний список правил, а не припускайте, що пріоритет 100 сам.
Узгодьте пересилання й трансляцію з маршрутом
Маршрутизація обирає висхідний канал; вона не дає дозволу на пересилання. У ядрі має бути ввімкнене пересилання IPv4, а міжмережевий екран має приймати напрямок від клієнта до WAN і зворотний трафік. Правильна таблиця з ланцюжком FORWARD, що відкидає потік, дає той самий симптом, що й відсутній маршрут, тому обидва перевіряють в одному проході.
Якщо другий WAN не маршрутизуватиме приватний пул назад до вас, транслюйте джерело на цьому виході. Для інтерфейсу з динамічною адресою звичайним вибором є вузьке правило masquerade, обмежене пулом та інтерфейсом:
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -o usb0 -j MASQUERADE
Тут охоплення важливіше за мету. Правило masquerade, що відповідає будь-якому вихідному інтерфейсу, перепише й трафік, який правильно виходить через eth0, а це приховує помилки маршрутизації замість того, щоб їх виправити. Трансляція виконується після рішення про маршрутизацію, тож вона ніколи не зможе виправити пакет, надісланий не тим висхідним каналом.
Накладні витрати тунелю теж потребують уваги, коли шляхи різняться. Якщо клієнти узгоджують великий TCP MSS, а альтернативний WAN має нижчий MTU або тунель усередині, великі сегменти застрягають, а малі працюють. Обмеження MSS на шляху пересилання перетворює це на передбачувану поведінку замість періодичного зависання.
Вирішіть, що станеться, коли usb0 зникне
Порожня таблиця — це не стан закриття під час збою. Якщо відповідний маршрут зникає, пошук продовжується наступним правилом, доходить до основної таблиці й бере маршрут за замовчуванням eth0. Трафік, який мав вийти через другий WAN, тихо виходить через перший, що під час розгортання з маршрутизацією за політикою зазвичай є найменш бажаним результатом.
Там, де такий відкат неприйнятний, додайте до таблиці 600 явний термінальний маршрут, наприклад маршрут за замовчуванням blackhole, або відкиньте пул у міжмережевому екрані, поки інтерфейс вимкнено. Кожен із двох варіантів — це рішення, яке можна записати; мовчання ним не є.
Стійкість — останній пункт. Хто б не володів обома каналами, чи це мережевий менеджер, скрипт надсилання чи життєвий цикл з'єднання, він має під час кожного повторного підключення створювати маршрути й правило заново, не додаючи дублікатів. Перевірте запитом від реального клієнта й окремим запитом зі шлюзу, підтвердьте спостережуваний вихід в обох випадках, потім витягніть другий WAN і подивіться, який із двох спроєктованих результатів справді відбувається. IPv6 потребує власних таблиці, правила й трансляції; наведене вище правило IPv4 нічого про це не каже.