Як доменні правила Apple VPN On Demand запускають тунель
Доменне правило вирішує лише те, коли відкривається тунель. Як працює DNS-перевірка connect-if-needed, чому маршрути досі вибирають трафік і як тестувати профіль.
Тунель відкривається, коли ви запитуєте одне внутрішнє ім’я, і залишається закритим, коли наступному застосунку воно потрібне так само сильно. Це не помилка застосунку; це форма доменного правила. Конфігурація on-demand від Apple описує умови встановлення з’єднання, і доменна форма цих умов ставить системному резолверу запитання ще до того, як зрушить хоч один пакет. Два питання постійно плутають: коли тунель має піднятися і що тунель несе, коли вже існує. Перше — тригер, друге — політика маршрутів і резолвера, і один профіль зазвичай задає обидва в тому самому payload, тому правильне доменне правило все одно може залишити вас у неправильній мережі.
Тригер і вибір трафіку лежать у різних шарах
Правило on-demand живе в словнику on-demand VPN-payload: упорядкований список правил, кожне з дією та набором умов збігу. Система оцінює їх, коли змінюється з’єднання або коли щось намагається досягти мережі, а дія вирішує, чи тунель піднімається, оцінюється, відключається чи ігнорується. Усе це відбувається в мережевому шарі платформи, до того як ваш застосунок отримає сокет.
Далі йде окрема група ключів: налаштування IPv4 і IPv6 тунелю, його включені та виключені маршрути, адреси DNS-серверів і на iOS та iPadOS зіставлення за застосунками, яке вирішує, які застосунки взагалі можуть користуватися тунелем. Профіль може поєднати широкий тригер із вузьким маршрутом або вузький тригер із маршрутом за замовчуванням. Прочитайте лише половину, і друга половина виглядатиме як несправність.
У мене є лабораторний профіль, який підключається щоразу, коли запитується щось під внутрішнім доменом, але спрямовує в тунель лише одну /16. Він робить саме те, що написано в його payload, і це також тип профілю, який породжує заявки: люди припускають, що підключений тунель означає, що їхній трафік усередині.
Що доменне правило насправді питає в резолвера
Доменна форма правила, яку часто називають connect-if-needed, не перевіряє payload пакетів і не спостерігає за URL. Коли ім’я розв’язується, система порівнює його з доменами в правилі і за збігу запитує, чи можна розв’язати це ім’я через DNS-сервери, які надає тунель. Якщо резолвер тунелю відповідає, ім’я вважається внутрішнім і з’єднання починається. Якщо натомість відповідає локальний резолвер, ім’я вважається зовнішнім і тунель не з’являється. Огляд розгортання Apple описує це як виявлення мережі з подальшим оцінюванням з’єднання.
Звідси випливають два наслідки. Профіль має вказати DNS-сервери всередині тунелю; доменному правилу без резолвера тунелю немає з чим порівнювати, тому оцінювання не дасть очікуваного збігу. І запит має дійти до системного резолвера. Застосунок або браузер, який запускає власний зашифрований DNS, розширення, що відповідає локально, або з’єднання з буквальною адресою ніколи не створюють того розв’язання імені, якого чекало правило. Один із найдовших моїх пообідніх часів закінчився, коли я виявив, що клієнт перед тунелем використовував DNS over HTTPS.
Кешування також прибирає тригер. Ім’я, яке вже є в кеші, може бути розв’язане без перевірки, яка запустила б тунель, тому правило, що працювало вчора, збійно завершується після перезавантаження або після того, як тунель якийсь час був піднятий. У macOS sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder скидає стан; в iOS перемикання авіарежиму або перезавантаження пристрою дає порівнянний чистий старт.
Обсяг збігу: імена, застосунки та мережі
Збіг за доменом — один тип із кількох. Правило може також збігатися з типом інтерфейсу (Wi-Fi, стільниковий, Ethernet) і конкретним SSID, а записи за застосунком або доменом Safari прив’язують тунель до одного робочого процесу. Ця прив’язка пояснює дивний досвід, коли лише один застосунок поводиться інакше, ніж усе інше: інші застосунки поза обсягом тунелю, тому вони далі використовують локальний шлях, навіть коли значок тунелю каже «підключено».
Порядок важливіший, ніж люди очікують. Правила оцінюються послідовно, і перший збіг дає дію, тому широке правило «підключатися до будь-якої Wi-Fi», розміщене над вузьким доменним правилом, тихо перемагає і робить доменне правило неперевірюваним. Перш ніж переписувати список доменів, переконайтеся, що жодне попереднє правило вже не збіглося.
Саме тому always-on — не просто суворіше правило on-demand. Примусове застосування always-on — окремий режим розгортання з власними вимогами до нагляду й керування; він тримає тунель відкритим, а не реагує на ім’я. Якщо вам потрібен тунель, який ніколи не падає, доменне правило — неправильний інструмент.
Режими збою, що імітують зламане правило
Більшість повідомлень про те, що доменне правило не працює, потрапляють в одне з п’яти місць, і лише останнє з них — текст правила.
| What you see | Layer | First check |
|---|---|---|
| Tunnel comes up, internal site still fails | route or resolver after connect | netstat -rn, scutil --dns |
| Tunnel never comes up for that name | trigger path | fresh lookup, cache flush, private DNS |
| Tunnel comes up for every app | scope, or an earlier rule | rule order, per-app mapping |
| Tunnel drops and will not return on the same Wi-Fi | interface or SSID match, admission | captive portal, SSID string, auth prompt |
| Tunnel returns after you disconnect it | profile ownership | profiles show |
Captive-портали заслуговують окремого рядка, бо Wi-Fi у готелях та аеропортах перехоплює саме той запит, від якого залежить правило. Доки портал не пропустить пристрій, DNS-сервер тунелю недосяжний, перевірка не вдається, і збій виглядає як неправильно написаний домен. Автентифікація — інший тихий випадок: правило може спрацювати, тунель може почати підключатися, а з’єднання вмирає на простроченому сертифікаті або на запиті, що з’являється на іншому екрані.
IPv6 створює варіант, який легко діагностувати неправильно. Імені з обома родинами адрес можуть спершу відповісти із запису AAAA, тоді як список маршрутів тунелю несе лише IPv4. Один браузер справляється, інший ні, і список доменів цілком невинний.
Перевіряйте реальним запитом, у такому порядку
Прочитайте політику, перш ніж гадати. У macOS sudo profiles show -type configuration друкує встановлені профілі, включно з VPN-payload, scutil --nc list показує стан служби, а scutil --nc show <service> друкує словник on-demand, який використовує система. На керованому iPhone або iPad той самий payload надходить із консолі керування або звіту MDM. Мережеві журнали доступні з log stream --predicate 'subsystem == "com.apple.networkextension"' у macOS і через консоль пристрою, коли телефон підключений.
Потім перевірте з іменем хоста, яке не запитувалося раніше в сеансі. Виберіть ім’я в DNS-зоні тунелю, про яке ви знаєте, що воно розв’язується внутрішньо, запитайте його один раз і подивіться, чи з’явиться тунель. Виконайте той самий запит двічі: друга спроба задіює шлях кешу, і різниця між ними скаже, тригер — це розв’язання чи маршрутизація.
Після підняття тунелю перевірте два шари окремо. netstat -rn -f inet і netstat -rn -f inet6 показують, куди веде кожен префікс, scutil --dns показує порядок резолверів і який інтерфейс володіє кожним резолвером, а nettop -m route показує, який інтерфейс переніс байти. Якщо тунель піднятий і резолвер правильний, але ресурс усе ще недоступний, припиніть редагувати правило; перевірте авторизацію на боці сервера і зворотний маршрут.
Коли правило належить комусь іншому
Якщо тунель з’являється знову після відключення, правило зазвичай належить профілю, а не застосунку: конфігурація, надіслана через MDM, залишковий особистий профіль або профіль, встановлений іншим клієнтом. sudo profiles show -type configuration плюс пошук за ключами on-demand звузить це, і шлях видалення — це профіль, а не перемикач у рядку меню. Видалення запису служби або застосунку залишає правило, і наступне встановлення знову його успадковує.
Один тест вирішує питання власності: відключіть, зачекайте, знову запитайте внутрішнє ім’я. Якщо тунель повертається, тригер працює як задумано, і відкрите питання — хто ним керує і чи той це обсяг, який вам потрібен.
Перш ніж повідомляти про це як про помилку, пройдіть ті самі п’ять перевірок: адреси резолвера тунелю присутні в payload, ім’я не було в кеші, жодне попереднє правило вже не збіглося, шлях AAAA покритий списком маршрутів, і застосунок у межах обсягу тунелю. Коли всі п’ять виконуються, правило робить свою роботу, а несправність — далі на шляху.