Hur Apples VPN On Demand-domänregler utlöser en tunnel
En domänregel avgör bara när tunneln öppnas. Hur connect-if-needed-DNS-sonderingen fungerar, varför rutter fortfarande väljer trafik och hur profilen testas.
Tunneln öppnas när du begär ett internt namn och förblir stängd när nästa app behöver det lika mycket. Det är inte en bugg i appen; det är formen av en domänregel. Apples on-demand-konfiguration beskriver villkor för att upprätta en anslutning, och domänformen av dessa villkor ställer en fråga till systemets resolver innan ett enda paket rör sig. Två frågor blandas ständigt ihop: när tunneln ska komma upp och vad tunneln bär när den väl finns. Den första är en utlösare, den andra är en rutt- och resolverpolicy, och en profil sätter oftast båda i samma payload, vilket är varför en korrekt domänregel ändå kan lämna dig på fel nätverk.
Utlösare och trafikval ligger i olika lager
En on-demand-regel bor i on-demand-ordboken i en VPN-payload: en ordnad lista med regler, var och en med en åtgärd och en uppsättning matchningsvillkor. Systemet utvärderar dem när anslutningen ändras eller när något försöker nå nätverket, och åtgärden avgör om tunneln höjs, utvärderas, kopplas från eller ignoreras. Allt detta sker i plattformens nätverkslager, innan din app har en socket.
Det som följer är en separat grupp nycklar: tunnelns IPv4- och IPv6-inställningar, dess inkluderade och exkluderade rutter, DNS-serveradresserna och på iOS och iPadOS mappningen per app som avgör vilka appar som överhuvudtaget får använda tunneln. En profil kan para en bred utlösare med en smal rutt, eller en smal utlösare med en standardrutt. Läs bara den ena halvan och den andra ser ut som ett fel.
Jag har en laboratorieprofil som ansluter närhelst något under en intern domän begärs men bara dirigerar en /16 in i tunneln. Den gör exakt vad dess payload säger, och den är också den typ av profil som genererar ärenden: folk antar att en ansluten tunnel betyder att deras trafik finns i den.
Vad en domänregel egentligen frågar resolvern
Domänformen av regeln, ofta kallad connect-if-needed, inspekterar inte paketpayloads och övervakar inte URL:er. När ett namn löses upp jämför systemet det med domänerna i regeln och frågar vid en träff om namnet kan lösas upp via de DNS-servrar som tunneln tillhandahåller. Om tunnelns resolver svarar räknas namnet som internt och anslutningen startas. Om den lokala resolvern svarar i stället behandlas namnet som externt och ingen tunnel dyker upp. Apples översikt över utrullning beskriver detta som nätverksdetektering följt av anslutningsutvärdering.
Två konsekvenser följer. Profilen måste namnge DNS-servrar inne i tunneln; en domänregel utan tunnelresolver har inget att jämföra med, så utvärderingen kan inte ge den träff du förväntar dig. Och uppslaget måste nå systemets resolver. En app eller webbläsare som kör sin egen krypterade DNS, ett tillägg som svarar lokalt eller en anslutning till en bokstavlig adress ger aldrig den namnmatchning som regeln väntade på. En av de längsta eftermiddagar jag tillbringat slutade när jag upptäckte att klienten framför tunneln använde DNS over HTTPS.
Cachelagring tar också bort utlösaren. Ett namn som redan finns i cachen kan besvaras utan den sondering som skulle ha startat tunneln, så en regel som fungerade i går misslyckas efter en omstart eller efter att tunneln varit uppe en stund. På macOS återställer sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder tillståndet; på iOS ger det att slå flygplansläge av och på eller starta om enheten en jämförbar ren start.
Matchningsomfång: namn, appar och nätverk
Domänmatchning är en typ bland flera. En regel kan också matcha gränssnittstypen (Wi-Fi, mobil, Ethernet) och ett specifikt SSID, och poster per app eller Safari-domän binder en tunnel till ett arbetsflöde. Den bindningen förklarar den märkliga upplevelsen där bara en app beter sig annorlunda än allt annat: de andra apparna ligger utanför tunnelns omfång, så de fortsätter använda den lokala vägen även när tunnelikonen säger ansluten.
Ordningen betyder mer än folk förväntar sig. Regler utvärderas i följd och den första som matchar ger åtgärden, så en bred regel anslut-på-vilket-Wi-Fi-som-helst placerad ovanför en smal domänregel vinner tyst och gör domänregeln omöjlig att testa. Innan du skriver om domänlistan, bekräfta att ingen tidigare regel redan har matchat.
Därför är always-on inte bara en strängare on-demand-regel. Tillämpning av always-on är ett separat utrullningsläge med egna krav på övervakning och administration; det håller en tunnel öppen i stället för att reagera på ett namn. Om det du behöver är en tunnel som aldrig faller är en domänregel fel verktyg.
Fellägen som imiterar en trasig regel
De flesta rapporter om att en domänregel inte fungerar hamnar på en av fem platser, och bara den sista av dem är regeltexten.
| 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-portaler förtjänar en egen rad, eftersom Wi-Fi på hotell och flygplatser fångar upp precis det uppslag som regeln är beroende av. Tills portalen släpper in enheten är tunnelns DNS-server oåtkomlig, sonderingen misslyckas, och felet ser ut som en felstavad domän. Autentisering är det andra tysta fallet: regeln kan utlösas, tunneln kan börja ansluta, och anslutningen dör på ett utgånget certifikat eller en uppmaning som dyker upp på en annan skärm.
IPv6 skapar en variant som är lätt att feldiagnostisera. Ett namn med båda adressfamiljerna kan besvaras först från en AAAA-post, medan tunnelns ruttlista bara bär IPv4. En webbläsare lyckas, en annan misslyckas, och domänlistan är helt oskyldig.
Testa med en riktig begäran, i den här ordningen
Läs policyn innan du gissar. På macOS skriver sudo profiles show -type configuration ut installerade profiler inklusive VPN-payloaden, scutil --nc list visar tjänstestatus och scutil --nc show <service> skriver ut den on-demand-ordbok som systemet använder. På en hanterad iPhone eller iPad kommer samma payload från hanteringskonsolen eller en MDM-rapport. Nätverksloggar finns med log stream --predicate 'subsystem == "com.apple.networkextension"' på macOS, och via enhetskonsolen när telefonen är ansluten.
Testa sedan med ett värdnamn som inte efterfrågades tidigare i sessionen. Välj ett namn i tunnelns DNS-zon som du vet löses internt, begär det en gång och se om tunneln dyker upp. Kör samma uppslag två gånger: det andra försöket tränar cachevägen, och skillnaden mellan de två säger om utlösaren är upplösningen eller routningen.
När tunneln är uppe, verifiera de två lagren separat. netstat -rn -f inet och netstat -rn -f inet6 visar vart varje prefix pekar, scutil --dns visar resolverordningen och vilket gränssnitt som äger varje resolver, och nettop -m route visar vilket gränssnitt som bar byten. Om tunneln är uppe och resolvern är korrekt men resursen fortfarande misslyckas, sluta redigera regeln; kontrollera auktorisering på serversidan och returrutten.
När regeln tillhör någon annan
Om tunneln dyker upp igen efter att du kopplat från den tillhör regeln vanligtvis en profil och inte en app: en konfiguration som skjutits ut via MDM, en kvarvarande personlig profil eller en profil installerad av en annan klient. sudo profiles show -type configuration plus en sökning efter on-demand-nycklarna begränsar det, och borttagningsvägen är profilen, inte reglaget i menyraden. Om du raderar tjänsteposten eller appen ligger regeln kvar, och nästa installation ärver den igen.
Ett enda test avgör ägarskapet: koppla från, vänta, begär det interna namnet igen. Om tunneln kommer tillbaka fungerar utlösaren som avsett och den öppna frågan är vem som hanterar den och om det omfånget är det du vill ha.
Innan du rapporterar detta som en bugg, gå igenom samma fem kontroller: tunnelresolverns adresser finns i payloaden, ett namn som inte var cachat, ingen tidigare regel som redan matchade, en AAAA-väg som ruttlistan täcker, och appen inom tunnelns omfång. När alla fem håller gör regeln sitt jobb och felet ligger längre fram på vägen.