Kill-switch după trecerea de la Wi-Fi la rețeaua mobilă: ce se strică
Un kill-switch este scris față de numele de interfață pe care o schimbare de rețea le înlocuiește. Verifică traseul exterior, familiile de adrese și resolverul înainte de a te baza pe el.
Într-o clipă laptopul este în Wi-Fi-ul biroului, în următoarea este legat la un telefon, iar indicatorul tunelului este din nou verde înainte să termini schimbarea ferestrelor. Lumina verde raportează doar că tunelul s-a reconectat; ce a făcut politica de rutare și blocare în acel interval este altă întrebare. Acea politică este un set de condiții de potrivire compilate la ultima instalare și numește o interfață, o adresă și o familie de adrese pe care transferul tocmai le-a eliminat. Aceeași comutare produce așadar trei rezultate care arată identic: blocarea continuă, politica își blochează propria revenire, sau se deschide o cale pe care nimic nu o acoperă.
Nimic de pe ecran nu desparte aceste trei stări, așa că întreabă la ce identificatori erau fixate regulile, nu ce culoare arată indicatorul. În Linux o regulă poate numi o interfață sau un ipset umplut din ea; în Android i se poate spune unui VpnService ce rețele subiacente să urmeze prin setUnderlyingNetworks. Fiecare legătură indică un enlace care urmează să fie înlocuit, și fiecare trebuie reevaluat după aceea.
Ce rescrie de fapt transferul
Când vechiul enlace dispare, nucleul îi elimină adresele, retrage rutele care treceau prin el și reconstruiește selecția adresei sursă din ce a rămas. Ruta implicită se mută pe noul gateway, iar indexul de interfață la care se refereau regulile vechi a dispărut sau a fost reciclat pentru alt dispozitiv. Se reîmprospătează și resolverii pe enlace, dar nu în aceeași clipă cu rutele. Toate acestea se întâmplă sub clientul VPN, așa că un client care urmărește doar starea propriului tunel nu vede nimic din ele.
Problema este că o regulă codează un identificator concret în locul intenției din spate. O regulă care aruncă tot ce nu iese prin interfața tunelului codează un nume de interfață; o regulă care permite punctul final codează o adresă pe care noua rețea o poate rutări altundeva. Când identificatorul dispare, regula nu devine vizibil greșită: fie încetează să se potrivească cu ceva, fie începe să se potrivească cu lucrul greșit.
Reconstruirea tunelului exterior fără a face o gaură
Transportul exterior era legat de vechea adresă sursă, așa că trebuie să deschidă un socket nou din cea nouă. Când punctul final este un nume de gazdă și nu o adresă literală, o căutare trebuie să reușească în timp ce blocarea este încă în vigoare. Aceasta este capcana ordinii: o politică suficient de strictă încât să arunce tot în afară de punctul final va arunca și căutarea necesară pentru a-l găsi, dacă rezolvarea nu are loc înainte de ridicarea blocării sau nu este purtată printr-un tunel încă viu. Ambele ordini pot funcționa, dar numai dacă clientul știe în care se află.
Clienții diferă aici într-un mod care contează la diagnosticare. Unii rezolvă mai întâi și instalează regulile după, așa că un transfer costă o întrerupere vizibilă și apoi se recuperează singur; alții țin blocarea sus și se bazează pe tunelul supraviețuitor pentru a duce căutarea, ceea ce eșuează complet când tunelul a murit odată cu enlace-ul. Adăugarea unei rute implicite directe late pentru a restabili conectivitatea lasă testul să treacă întotdeauna și lasă întotdeauna scurgerea pe care o împiedicai.
O rută care încă indică vechiul gateway dă aceeași recuperare blocată dintr-o altă cauză, așa că citește tabelul înainte de a da vina pe client. Comenzile de mai jos numesc interfața și adresa sursă pe care nucleul le-ar folosi într-adevăr, iar asta hotărăște într-o singură linie dacă vechea cale este încă instalată.
ip route get 1.1.1.1
ip -6 route get 2606:4700:4700::1111Când noul enlace aduce IPv6, iar regulile nu
Rețelele mobile și de oaspeți acordă adesea un prefix IPv6 global chiar dacă LAN-ul cu cablu al biroului nu a făcut-o niciodată. O politică scrisă doar ca reguli IPv4, forma implicită a majorității rețetelor făcute manual de iptables și nftables, nu acoperă nimic din asta. Tunelul rămâne conectat, aplicațiile cu acces IPv6 ies în afara lui, iar indicatorul nu poate arăta diferența pentru că tunelul chiar este activ. Cazul oglindă este la fel de obișnuit: un set de reguli doar pentru IPv6 nu face nimic într-o rețea care nu oferă v6.
Compară ce oferă enlace-ul cu ce menționează politica, pe ambele părți ale transferului. Aceste comenzi tipăresc aceleași fapte cu care lucrează clientul:
ip -4 route show default
ip -6 route show default
sudo nft list ruleset | grep -c 'ip6 'Dacă a doua comandă tipărește o rută implicită în timp ce a treia returnează zero, noul enlace poate scoate mașina prin IPv6 fără ca vreo regulă să o supravegheze. Rulează din nou toate trei după comutare, pentru că numărul interesant este diferența dintre cele două rulări. Dacă a doua nu tipărește nimic, se aplică cazul invers și orice politică încărcată de v6 este acolo doar decor.
Resolverul schimbă mâinile la mijlocul sesiunii
În sistemele moderne resolverii sunt atașați enlace-urilor, așa că un enlace nou vine cu un set nou de resolveri și poate cu o vedere split-DNS diferită. systemd-resolved ține un domeniu pe enlace și alege între ele după rută, în timp ce macOS citește resolveri cu domeniu din depozitul dinamic și respectă ordinea interfețelor. Un client care își instalează propriul resolver concurează cu cel al enlace-ului, iar regulile de prioritate pe care nimeni nu le urmărește decid câștigătorul. Atunci rezolvarea numelor poate ceda, în timp ce filtrarea pachetelor face exact ceea ce a fost scrisă să facă.
Citește resolverul care este activ, nu pe cel configurat. Pe un host systemd subcomanda status arată din ce enlace a venit fiecare domeniu și dacă un nume private-DNS este în vigoare:
resolvectl status --no-pager
resolvectl query intranet.example.comDacă interogarea iese prin enlace-ul fizic în locul tunelului, clientul a pierdut competiția de prioritate și nicio reglare a firewall-ului nu va repara denumirea. Compară traseul interogării pe ambele părți ale transferului pentru a vedea care s-a mișcat. Un nume care se rezolvă la o adresă privată pe care noua rețea nu o poate rutări este un al treilea caz și se prezintă ca expirare, nu ca eroare.
Exersează transferul și păstrează înregistrarea
Reproduce schimbarea intenționat, în loc să o aștepți. Ridică tunelul pe primul enlace, pornește un transfer de durată și o căutare repetată, apoi schimbă enlace-ul și urmărește care supraviețuiește. Notează intervalul dintre dispariția enlace-ului vechi și raportarea de către tunel că este conectat, pentru că în acea fereastră politica a rezistat sau nu. Rulează secvența și în cealaltă direcție, ca rezultatul să nu fie unilateral.
Excepțiile au nevoie de propria trecere, pentru că o ocolire justificată în rețeaua veche nu este automat justificată în cea nouă. O imprimantă, un NAS sau un portal captiv în LAN-ul de acasă nu au echivalent în rețeaua mobilă, iar excepția care ajungea la ele devine o regulă fără echivalent.
Notează numele interfețelor, familiile oferite, resolverul în vigoare și durata întreruperii pentru fiecare direcție. O reconectare dovedește că transportul s-a refăcut, nu că blocarea a rezistat în interval, iar acestea sunt afirmații separate pentru un tichet. Cu acea înregistrare următorul transfer este comparat cu o stare cunoscută, nu cu memoria.