Постійні маршрути для VPN на Mac: networksetup чи хук підключення?
Маршрут, який вводять після кожного перепідключення, — не політика. Вирішіть, чи префікс належить службі VPN, тимчасовому тесту або хуку для адрес, відомих лише після узгодження.
Маршрут, який вводять після кожного підключення, вирішує момент, а не тиждень. У macOS сталий вибір зазвичай — префікс, збережений разом зі службою VPN, бо служба перевстановлює його при кожному підключенні й видаляє, коли служба вимкнена. Альтернативи — тимчасовий route add для тестування і хук підключення для адрес, відомих лише після узгодження.
Вирішіть, чи маршрут належить службі чи сеансу
Запитайте, від чого залежить префікс. Якщо це фіксована приватна мережа за власною службою VPN, маршрут належить цій службі. Якщо він залежить від адреси партнера, що змінюється при кожному підключенні, хук або завдання, кероване станом, може бути кращим власником. Якщо ви перевіряєте шлях лише на наступні п'ять хвилин, тимчасового маршруту достатньо.
Маршрут, прив'язаний до служби, має найчистіший життєвий цикл. Він з'являється разом зі службою і зникає, коли служба не підключена, тому не може пережити тунель, на який указує. Ця властивість цінніша за зручність однорядкової команди.
Маршрут, прив'язаний до сеансу, належить інтерфейсу, і цей номер змінюється без попередження. Перепідключення може дати тунелю інше ім'я utun, ніж використовував попередній сеанс, і це перетворює жорстко задану команду на маршрут, який не вказує нікуди або, гірше, на інший тунель.
Прочитайте поточний стан маршруту і служби
Почніть з імен, які система справді використовує. Ім'я служби в налаштуваннях мережі — ідентифікатор для команд нижче, а поточна таблиця маршрутів показує, що встановив підключений клієнт. Прочитайте обидві, поки тунель активний.
scutil --nc list
networksetup -listnetworkserviceorder
netstat -rn | head -30
route get 10.20.5.5
Цей пошук показує, який шлюз і інтерфейс ядро вибрало б для цієї адреси в цей момент. Якщо воно вже вибирає тунель, префікс покрито і новий маршрут був би зайвим. Якщо воно вибирає локальний маршрутизатор, тунелю бракує цього префікса.
Запишіть адресу партнера, поки підключені. Вона стає значенням шлюзу в маршруті, прив'язаному до служби, і зазвичай це пункт призначення, показаний для маршруту за замовчуванням тунелю в netstat -rn.
Збережіть префікс за допомогою networksetup
Інструмент networksetup приєднує додаткові маршрути до мережевої служби. Для служби з іменем OfficeVPN і приватного префікса, доступного через партнера тунелю, форма така:
sudo networksetup -setadditionalroutes OfficeVPN 10.20.0.0 255.255.0.0 10.8.0.6
networksetup -getadditionalroutes OfficeVPN
Кожна трійка після імені служби задає пункт призначення, його мережеву маску і партнера тунелю як шлюз. Один виклик може нести кілька префіксів, а порожній виклик очищає збережений список. Читач — це крок перевірки; якщо список порожній, налаштування не застосувалося до тієї служби, про яку ви думаєте.
Шлюз має бути партнером тунелю, а не фізичним маршрутизатором. Маршрут, який називає локальний шлюз, надсилає приватний префікс через фізичний інтерфейс — це початкова невдача з зайвими кроками. Застарілий партнер — найчастіша причина, чому зовні правильний маршрут ніколи не передає трафік. Перечитайте партнера з підключеного стану, а не копіюйте адресу зі старої нотатки.
Використовуйте route add лише для тесту
Прямий маршрут корисний, щоб довести, що префікс працює, перш ніж зробити його постійним. Форма з інтерфейсом уникає пошуку шлюзу:
sudo route -n add -net 10.20.0.0/16 -interface utun4
Маршрут зникає при наступному перепідключенні й залежить від номера інтерфейсу, який існує сьогодні. Це робить його діагностикою, а не розгортанням. Якщо тест працює, а маршрут, прив'язаний до служби, ні, спершу порівняйте значення шлюзу; це поле найчастіше буває неправильним.
Остерігайтеся порад, які замінюють маршрут за замовчуванням VPN, щоб нав'язати розділення. Клієнт, який застосовує повний тунель, може перевстановити свої маршрути після перепідключення або оновлення політики, тому ручна зміна тихо скасовується. Кілька приватних префіксів — це проблема маршрутизації; тримати весь інтернет-трафік локально всупереч політиці повного тунелю — рішення на боці сервера.
Вибирайте хук лише тоді, коли адреса узгоджується
Для з'єднань на основі PPP, як-от L2TP, macOS виконує /etc/ppp/ip-up після встановлення з'єднання. Скрипт отримує ім'я інтерфейсу та узгоджені локальну й віддалену адреси, тож може додати маршрут, що залежить від партнера, призначеного сервером. Це саме той випадок, який фіксований маршрут служби не може виразити.
IKEv2 і клієнти виробників можуть узагалі не використовувати цей шлях PPP, а отже, скрипт може мовчати весь сеанс. Коли це відбувається, завдання launchd, яке опитує scutil --nc status і реагує на зміну стану, — еквівалентний механізм, із невеликою затримкою.
Який би хук ви не використовували, зробіть його ідемпотентним і дозвольте йому видаляти лише створені ним маршрути. Скрипт, який видаляє кожен маршрут, що згадує тунель, зрештою видалить маршрут, який підтримує доступність VPN-сервера, і з'єднання впаде, щойно це вдасться.
Завершіть перевіркою приватного пункту призначення, звичайного перегляду та циклу перепідключення або сну. Потім перегляньте scutil --dns, бо розв'язання імен — окрема політика, і робочий маршрут не доводить, що приватні імена розв'язуються.