Розділені маршрути L2TP на Mac: чому адреса хоста не працює
setadditionalroutes вимагає пар мережі й маски, замінює весь список і потребує точного імені служби. Перевірте таблицю, перш ніж звинувачувати шлюз.
VPN підключається, рядок меню це показує, а внутрішній хост усе одно не відповідає. У такій ситуації є три можливі причини, і яка з них діє, залежить від того, як було налаштовано тунель. Або команда маршруту використала адресу хоста там, де потрібна була адреса мережі, або сам профіль встановлює маршрут за замовчуванням, який ковтає рішення, або клієнт — це тунель PPP, якому потрібен гачок, а не ключ профілю. Перевірте їх у цьому порядку, бо першу причину найдешевше виключити.
Призначення — це адреса мережі, маска описує префікс
networksetup -setadditionalroutes приймає трійки з призначення, маски підмережі та шлюзу. Виклик, що надсилає одну внутрішню підмережу через тунель, виглядає так:
sudo networksetup -setadditionalroutes "VPN (L2TP)" 192.168.1.0 255.255.255.0 10.2.0.0
Зверніть увагу, що таке призначення: адреса мережі, а не адреса сервера, до якого ви намагаєтеся потрапити. У випадку, що породив цю статтю, ідентична команда з 192.168.1.20 на цьому місці не зробила нічого корисного, а заміна його на 192.168.1.0 спрацювала одразу. Та сама маска, той самий шлюз, одне інше число. Це і є вся помилка в мініатюрі.
Причина — арифметика, а не політика. Адреса хоста в парі з маскою /24 не описує 192.168.1.0/24; вона описує щось, що таблиця маршрутизації не може корисно втримати, тому запис відхиляється або ігнорується, і тунель зрештою несе менше, ніж ви планували.
Коли вам потрібен рівно один хост, використовуйте адресу хоста з маскою 255.255.255.255. Помилка саме у змішаних парах, а не у використанні адреси хоста як такої. /32, побудована з однієї адреси, — законний маршрут; /24, побудована з однієї адреси, — помилка.
Виклик замінює список, а ім'я — буквальне
Дві поведінки дивують людей із першої спроби. Команда встановлює повний список додаткових маршрутів, а не додає до нього, тому виклик, що додає один префікс, тихо видаляє інші, які були там раніше. Складіть увесь набір одним викликом.
Ім'я служби також не та мітка, яку ви вигадали. Прочитайте його з інструмента й скопіюйте точно, включно з суфіксом типу:
networksetup -listallnetworkservices
А ім'я, що відрізняється на один символ, не дає ні помилки, вартої читання, ні маршруту. Копіювання й вставлення — правильна техніка тут, а не передруковування з пам'яті.
Коли профіль претендує на маршрут за замовчуванням
Розділені маршрути програють маршруту за замовчуванням для будь-якого призначення, яке вони явно не покривають, а профіль L2TP, налаштований на повний тунель, встановлює саме це. Якщо профіль каже, що все йде через тунель, список додаткових маршрутів змінюється дуже мало. Ваш запис не помилковий; він просто не стосується призначень, які він ніколи не називає. Керування цим зазвичай міститься в налаштуванні профілю про надсилання всього трафіку, а не в якійсь команді маршруту.
Вирішіть, яка модель вам справді потрібна, перш ніж редагувати нові записи. Повний тунель із винятками — це інша конфігурація, ніж розділений тунель із конкретними префіксами, а змішування двох дає таблицю, яку ніхто не може передбачити.
Якщо організація вимагає повний тунель, припиніть намагатися розділити його локально й віднесіть вимогу тому, хто володіє політикою. Локально доданий маршрут, що їй суперечить, усе одно буде видалено наступним оновленням профілю.
Тунелям PPP потрібен гачок замість ключа
Для тунелів на основі PPP defaultroute — це ключ профілю, що створює маршрут за замовчуванням; приберіть його, і клієнт перестане претендувати на кожне призначення. Потім маршрути додаються після появи інтерфейсу, зазвичай із /etc/ppp/ip-up:
#!/bin/sh
/sbin/route add -net 192.168.1.0 -interface ppp0
Тримайте скрипт у власності root і виконуваним, і додайте захист на ім'я інтерфейсу, коли на машині існує більше одного профілю тунелю. Гачок, що запускається для кожного з'єднання PPP і припускає одне ім'я пристрою, — маленька помилка з довгим життям.
Перевірте розділення трьома запитами
Зніміть таблицю, доки ви підключені, і зазначте, який інтерфейс обслуговує тунель. Потім перевірте конкретне призначення, а не довіряйте коду виходу команди, що його створила. Код виходу повідомляє, чи інструмент прийняв аргументи, а не те, чи трафік іде потрібним вам шляхом.
Завершіть трьома запитами, що доводять розділення: один внутрішній хост за адресою, одне внутрішнє ім'я через внутрішній резолвер і один публічний сайт, який досі має використовувати локальне з'єднання. Якщо публічний сайт тепер теж іде через тунель, розділення не відбулося, хоч би що казав список маршрутів.
Підключіться ще раз і повторіть внутрішній запит, бо маршрути, додані вручну, можуть пережити інтерфейс, який зробив їх чинними і тихо перетворити трафік на чорну діру після падіння тунелю.