De tunnel gaat open wanneer je één interne naam opvraagt en blijft dicht wanneer de volgende app hem net zo hard nodig heeft. Dat is geen bug in de app; het is de vorm van een domeinregel. Apples on-demand-configuratie beschrijft voorwaarden om een verbinding tot stand te brengen, en de domeinvorm van die voorwaarden stelt de systeemresolver een vraag voordat er één pakket beweegt. Twee vragen worden voortdurend verward: wanneer de tunnel omhoog moet, en wat de tunnel vervoert zodra hij bestaat. Het eerste is een trigger, het tweede is een route- en resolverbeleid, en één profiel zet meestal beide in dezelfde payload, waardoor een correcte domeinregel je alsnog op het verkeerde netwerk kan achterlaten.

Trigger en verkeersselectie zitten op verschillende lagen

Een on-demand-regel woont in het on-demand-woordenboek van een VPN-payload: een geordende lijst regels, elk met een actie en een set matchvoorwaarden. Het systeem evalueert ze wanneer de connectiviteit verandert of wanneer iets het netwerk probeert te bereiken, en de actie bepaalt of de tunnel omhoog gaat, wordt geëvalueerd, wordt verbroken of wordt genegeerd. Dat alles gebeurt in de netwerklaag van het platform, voordat je app een socket heeft.

Wat daarna komt is een aparte groep sleutels: de IPv4- en IPv6-instellingen van de tunnel, de in- en uitgesloten routes, de DNS-serveradressen en op iOS en iPadOS de toewijzing per app die bepaalt welke apps de tunnel mogen gebruiken. Een profiel kan een brede trigger koppelen aan een smalle route, of een smalle trigger aan een standaardroute. Lees maar één helft en de andere helft lijkt op een storing.

Ik heb een laboratoriumprofiel dat verbindt zodra iets onder een intern domein wordt opgevraagd, maar slechts één /16 de tunnel in routeert. Het doet precies wat de payload zegt, en het is ook het soort profiel dat tickets oplevert: mensen nemen aan dat een verbonden tunnel betekent dat hun verkeer erin zit.

Wat een domeinregel de resolver echt vraagt

De domeinvorm van de regel, vaak connect-if-needed genoemd, inspecteert geen packetpayloads en let niet op URL’s. Wanneer een naam wordt opgelost, vergelijkt het systeem die met de domeinen in de regel en vraagt bij een match of die naam via de DNS-servers van de tunnel kan worden opgelost. Als de resolver van de tunnel antwoordt, geldt de naam als intern en begint de verbinding. Als in plaats daarvan de lokale resolver antwoordt, wordt de naam als extern behandeld en verschijnt er geen tunnel. Apples implementatieoverzicht beschrijft dit als netwerkdetectie gevolgd door verbindingsevaluatie.

Daaruit volgen twee gevolgen. Het profiel moet DNS-servers binnen de tunnel noemen; een domeinregel zonder tunnelresolver heeft niets om te vergelijken, dus de evaluatie kan de verwachte match niet opleveren. En de opzoeking moet de systeemresolver bereiken. Een app of browser die zijn eigen versleutelde DNS draait, een extensie die lokaal antwoordt, of een verbinding naar een letterlijk adres levert nooit de naamresolutie op waarop de regel wachtte. Een van de langste middagen die ik heb doorgebracht eindigde toen ik ontdekte dat de client voor de tunnel DNS over HTTPS gebruikte.

Caching haalt de trigger er ook uit. Een naam die al in de cache zit, kan worden beantwoord zonder de probe die de tunnel zou hebben gestart, dus een regel die gisteren werkte, faalt na een herstart of nadat de tunnel een tijdje omhoog stond. Op macOS reset sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder de toestand; op iOS geeft het aan- en uitzetten van vliegtuigmodus of het herstarten van het apparaat je een vergelijkbare schone lei.

Matchbereik: namen, apps en netwerken

Domeinmatching is één type naast verschillende andere. Een regel kan ook het interfacetype (Wi-Fi, mobiel, Ethernet) en een specifieke SSID matchen, en vermeldingen per app of Safari-domein binden een tunnel aan één werkstroom. Die binding verklaart de vreemde ervaring waarbij slechts één app zich anders gedraagt dan al het andere: de andere apps vallen buiten het bereik van de tunnel, dus blijven ze het lokale pad gebruiken, zelfs wanneer het tunnelpictogram verbonden zegt.

Volgorde is belangrijker dan mensen verwachten. Regels worden op volgorde geëvalueerd en de eerste die matcht levert de actie, dus een brede regel verbind-op-elk-Wi-Fi boven een smalle domeinregel wint stil en maakt de domeinregel ontestbaar. Bevestig voordat je de domeinlijst herschrijft dat geen eerdere regel al heeft gematcht.

Daarom is always-on niet zomaar een strengere on-demand-regel. Het afdwingen van always-on is een aparte implementatiemodus met eigen eisen aan toezicht en beheer; het houdt een tunnel open in plaats van op een naam te reageren. Als je een tunnel nodig hebt die nooit wegvalt, is een domeinregel het verkeerde gereedschap.

Storingen die een kapotte regel nabootsen

De meeste meldingen dat een domeinregel niet werkt, belanden op een van vijf plaatsen, en alleen de laatste daarvan is de tekst van de regel.

What you seeLayerFirst check
Tunnel comes up, internal site still failsroute or resolver after connectnetstat -rn, scutil --dns
Tunnel never comes up for that nametrigger pathfresh lookup, cache flush, private DNS
Tunnel comes up for every appscope, or an earlier rulerule order, per-app mapping
Tunnel drops and will not return on the same Wi-Fiinterface or SSID match, admissioncaptive portal, SSID string, auth prompt
Tunnel returns after you disconnect itprofile ownershipprofiles show

Captive portals verdienen een eigen regel, omdat hotel- en luchthaven-Wi-Fi precies de opzoeking onderschept waarvan de regel afhangt. Totdat de portal het apparaat toelaat, is de DNS-server van de tunnel onbereikbaar, mislukt de probe, en ziet de storing eruit als een verkeerd gespeld domein. Authenticatie is het andere stille geval: de regel kan afgaan, de tunnel kan beginnen met verbinden, en de verbinding sterft op een verlopen certificaat of een prompt die op een ander scherm verschijnt.

IPv6 zorgt voor een variant die makkelijk verkeerd wordt gediagnosticeerd. Een naam met beide adresfamilies kan eerst uit een AAAA-record worden beantwoord, terwijl de routelijst van de tunnel alleen IPv4 bevat. De ene browser slaagt, de andere faalt, en de domeinlijst is volledig onschuldig.

Test met een echt verzoek, in deze volgorde

Lees het beleid voordat je gaat gokken. Op macOS print sudo profiles show -type configuration geïnstalleerde profielen inclusief de VPN-payload, scutil --nc list toont de servicestatus, en scutil --nc show <service> print het on-demand-woordenboek dat het systeem gebruikt. Op een beheerde iPhone of iPad komt dezelfde payload uit de beheerconsole of een MDM-rapport. Netwerklogs zijn beschikbaar met log stream --predicate 'subsystem == "com.apple.networkextension"' op macOS, en via de apparaatconsole wanneer de telefoon is aangesloten.

Test daarna met een hostnaam die eerder in de sessie niet is opgevraagd. Kies een naam in de DNS-zone van de tunnel waarvan je weet dat hij intern oplost, vraag hem één keer op, en kijk of de tunnel verschijnt. Voer dezelfde opzoeking twee keer uit: de tweede poging oefent het cachepad, en het verschil tussen beide vertelt je of de trigger de resolutie of de routering is.

Controleer nadat de tunnel omhoog is de twee lagen apart. netstat -rn -f inet en netstat -rn -f inet6 tonen waar elk prefix naartoe wijst, scutil --dns toont de resolvervolgorde en welke interface elke resolver bezit, en nettop -m route toont welke interface de bytes heeft gedragen. Als de tunnel omhoog is en de resolver klopt maar de bron nog steeds faalt, stop dan met het bewerken van de regel; controleer de autorisatie aan de serverkant en de retourroute.

Wanneer de regel van iemand anders is

Als de tunnel terugkomt nadat je hem hebt verbroken, hoort de regel meestal bij een profiel en niet bij een app: een via MDM gepushte configuratie, een achtergebleven persoonlijk profiel, of een profiel dat door een andere client is geïnstalleerd. sudo profiles show -type configuration plus een zoekopdracht naar de on-demand-sleutels beperkt het, en het verwijderpad is het profiel, niet de schakelaar in de menubalk. Het verwijderen van de servicevermelding of de app laat de regel achter, en de volgende installatie erft hem weer.

Eén test beslist het eigenaarschap: verbreek, wacht, vraag de interne naam opnieuw op. Als de tunnel terugkomt, werkt de trigger zoals bedoeld en is de open vraag wie hem beheert en of dat bereik is wat je wilt.

Voordat je dit als bug meldt, doorloop je dezelfde vijf controles: resolveradressen van de tunnel aanwezig in de payload, een naam die niet in de cache zat, geen eerdere regel die al matchte, een AAAA-pad dat de routelijst dekt, en de app binnen het bereik van de tunnel. Als alle vijf kloppen, doet de regel zijn werk en ligt de fout verderop in het pad.

Gerelateerde artikelen