Tunelul cade, kill switch-ul se activează, iar un download care era trei sferturi gata fie îngheață, fie eșuează imediat. Aceste două rezultate provin din alegeri de aplicare diferite, nu din niveluri de protecție diferite. Un pachet aruncat lasă conexiunea în așteptare, în timp ce un pachet respins o închide și anunță aplicația. A decide ce comportament doriți este o întrebare de proiectare, iar testarea lui este un exercițiu separat.

Aruncat, respins și resetat sunt lucruri diferite

O regulă de firewall care aruncă traficul elimină pachetul și nu trimite nimic înapoi, așa că expeditorul continuă să retrimită după propriile temporizatoare. O regulă care respinge cu un TCP reset închide imediat conexiunea, iar aplicația vede o eroare. Majoritatea kill switch-urilor aruncă, pentru că o respingere ar dezvălui politica și pentru că aruncarea seamănă cu comportamentul unei rețele moarte.

Blocarea nu este același lucru cu închiderea socketului. Aplicația mai deține un descriptor în stare stabilită, iar doar pachetele lipsesc. De aceea o pagină poate sta pe un spinner minute întregi în timp ce sistemul de operare insistă că conexiunea există. Citiți aplicarea documentată în loc să o deduceți din mesajul aplicației, deoarece ambele comportamente arată ca o rețea căzută.

Ce face aplicația cât timp durează întreruperea

TCP retransmite cu întârzieri crescânde, iar bugetul implicit de reîncercări al Linux expiră în jur de un sfert de oră, nu în câteva secunde. Până atunci socketul nu este nici util deschis, nici închis. Aplicațiile cu keepalive-uri proprii sau cu limite de timp pentru cereri renunță adesea mai devreme, de aceea două programe de pe aceeași mașină se comportă diferit în timpul unei singure căderi.

Când tunelul revine, socketul local este neschimbat, dar calea poate să nu fie. O nouă adresă publică de sursă produce un alt cvadruplu pe server, așa că un firewall cu stare de pe cealaltă parte nu mai corespunde sesiunii. Conexiunea este moartă chiar dacă clientul nu a văzut niciodată o eroare.

Decideți dacă recuperarea este necesară

Alegeți între două contracte. Fie sesiunea trebuie să supraviețuiască unei întreruperi scurte, ceea ce necesită adresare stabilă și un server care își păstrează starea, fie aplicația trebuie să se reconecteze curat, ceea ce necesită logică de reîncercare sigură de repetat. Orice între acestea produce cel mai rău rezultat: un client care retrimite ceea ce serverul a înregistrat deja, sau unul care raportează succes pentru o sesiune pe care nimeni nu o poate vedea.

Adresarea stabilă este partea pe care oamenii o uită, pentru că o reconectare care aterizează pe o altă adresă publică invalidează starea din partea serverului chiar și când socketul clientului pare sănătos. Notați care dintre cele două contracte se aplică fiecărei aplicații, deoarece rareori se potrivesc toate.

Verificați blocarea și recuperarea separat

Tratați protecția împotriva scurgerilor și supraviețuirea sesiunii ca două proprietăți, pentru că trecerea uneia nu spune nimic despre cealaltă. O sesiune care supraviețuiește nu este dovada că traficul direct a fost blocat, iar o sesiune care moare nu este dovada că fiecare rută directă a fost blocată.

ss -tnp state established '( dport = :443 )'
sudo conntrack -L -p tcp --dport 443
sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'

Folosiți o operațiune de test inofensivă când observați recuperarea, astfel încât o trimitere duplicată să nu devină incidentul. Înregistrați modul de eșec pe care l-ați văzut efectiv: ce a afișat aplicația, dacă socketul a supraviețuit și când și-a revenit singur.

Scrieți comportamentul așteptat lângă regula de aplicare și puneți o dată. Următoarea persoană care va schimba acea regulă trebuie să știe care dintre cele două contracte le-a promis implementarea.

Articole similare