Додатковим маршрутам VPN на Mac потрібен власник, а не скрипт входу
Маршрут, доданий один раз під час входу, — не політика перепідключення. Дайте віддаленим префіксам власника і вирішіть, як вони з'являються, змінюються та зникають разом із цим з'єднанням.
Досягти приватного префікса через VPN — це вимога з тривалістю: вона діє, поки це з'єднання придатне, і закінчується, коли закінчується з'єднання. Скрипт входу не може це виразити, бо вхід і підняття тунелю — різні моменти, і тунель, що існує при вході, може бути не тим, який за хвилину несе трафік. Перше рішення — не яку команду виконати. А який компонент володіє префіксом.
Префіксу потрібен власник, а не момент
Почніть з того, що запишете вимогу як речення з підметом: досягніть 10.77.0.0/24 через офісний VPN, поки це з'єднання підняте. Це речення називає префікс, з'єднання й умову і одразу виключає дві популярні заміни: хук входу та ім'я інтерфейсу на кшталт ppp0 або utun2.
Імена інтерфейсів призначаються під час виконання і не є стабільними між перепідключеннями. Хук, що збігається з ім'ям, яке він бачив минулого тижня, або не спрацює, або спрацює на чужому інтерфейсі. Обидва результати виглядають як помилка маршрутизації, а не як застаріле припущення, яким вони є. Те саме заперечення стосується будь-якого скрипта, прив'язаного до імені, яке існує лише поки піднято один конкретний тунель.
Використовуйте підтримане джерело наміру маршруту
Шлюз, керований профіль або документований механізм маршрутів клієнта-власника — правильне місце, коли цей механізм може виразити вимогу. Який саме застосовується, залежить від протоколу й постачальника, і ключі між ними не переносяться, тому значення, що налаштовує профіль OpenVPN нічого не каже про вбудований клієнт L2TP або IKEv2.
| Mechanism | Can carry extra prefixes | Who owns the lifetime |
|---|---|---|
| Gateway-pushed routes | Often, if the gateway is configured for it | The connection |
| Managed profile settings | Depends on the client and profile format | The profile |
| Provider tunnel settings | Yes, as included and excluded routes | The provider process |
| Manual command | Yes, once | Nobody |
Для розробників пакетних тунелів налаштування тунелю IPv4 від Apple явно показують включені та виключені маршрути, і IPv6 має свій відповідник. Це API, які використовує постачальник, а не доказ того, що кожна вбудована панель VPN пропонує адміністраторові довільний список маршрутів. Якщо поточна комбінація не може виразити потрібні префікси, наступний крок — підтриманий шлях налаштування від оператора, а не інший застосунок, встановлений у надії, що він поводитиметься краще.
Термін служби включає очищення
Іноді зовнішній помічник справді потрібен, і тоді «додай маршрут» — найменша частина його роботи. Він має знати, якому з'єднанню служить і який інтерфейс використовує це з'єднання, дочекатися, поки відповідний стан мережі вляжеться, залишатися ідемпотентним при двох запусках поспіль, і не очищати нічого, чого він сам не встановив.
Остання умова — та, що болить. Помічник, який видаляє кожен маршрут, що відповідає офісному префіксу, рано чи пізно видалить маршрут, якого він не додавав. Виниклий збій списують на VPN-клієнт, бо клієнт — це частина, яку бачить користувач. Вирішити, чим володіє помічник, до його написання дешевше, ніж потім пояснювати, чому локальна підмережа перестала відповідати.
Гонка при перепідключенні
Уявіть швидке перепідключення. Сеанс A падає, сеанс B піднімається і встановлює свій маршрут, а потім нарешті запускається відкладене очищення A. Якщо це очищення видаляє маршрути за префіксом, воно забирає з собою чинний стан B, і з'єднання, що працювало секунду тому, тепер маршрутизується в нікуди.
Це гонка володіння, і додавання паузи до скрипта змінює лише те, яка сторона її виграє. Рішення — зробити очищення залежним від ідентичності: порівняйте інтерфейс і сеанс, встановлені помічником, з тими, що ще чинні, і видаляйте лише за збігом.
Що тестувати і чого маршрут не може
Приймання має охоплювати чотири переходи: перше з'єднання, перепідключення на інший інтерфейс, невдалу спробу підключення та остаточне від'єднання. Після кожного читайте маршрут, який система фактично обрала для адреси на дальньому боці, а не той, якого ви очікували.
route -n get 10.77.0.5
netstat -rn -f inet
Включіть і незручні випадки в той самий прохід: IPv6 там, де він потрібен, локальний префікс, що перекривається з дальнім, і маршрут до самого публічного кінцевого пункту VPN, який має продовжувати працювати, поки тунель піднято. Потім запишіть, чим маршрут не є. Він вибирає пакети; він не дає дозволу на дальньому боці і не створює зворотного шляху, і це залишається окремими вимогами з окремими власниками.
Результат, який ви хочете, — це префікс, що йде за своїм підтриманим власником з'єднання через кожен перехід, а не команда, яка випадково один раз спрацювала на машині, де її було написано.