Kill switch įsijungia: kas nutinka atviroms TCP sesijoms?
Užblokuotas paketas nėra uždaryta jungtis. Nuspręskite, ar sesija turi išgyventi pertrauką, tada atskirai patikrinkite blokavimą ir atkūrimą.
Tunelis nutrūksta, kill switch įsijungia, o tris ketvirtadalius atsisiuntimo arba sustingsta, arba iš karto nepavyksta. Šie du rezultatai kyla iš skirtingų vykdymo pasirinkimų, o ne iš skirtingų apsaugos lygių. Išmestas paketas palieka jungtį laukiančią, o atmestas paketas ją uždaro ir praneša programai. Nuspręsti, kokio elgesio norite, yra dizaino klausimas, o jo tikrinimas yra atskiras pratimas.
Išmetimas, atmetimas ir atstatymas skiriasi
Ugniasienės taisyklė, kuri išmeta srautą, išmeta paketą ir nieko negrąžina, todėl siuntėjas toliau siunčia iš naujo pagal savo laikmačius. Taisyklė, kuri atmeta su TCP reset, iš karto uždaro jungtį, ir programa mato klaidą. Dauguma kill switch išmeta, nes atmetimas atskleistų politiką ir nes išmetimas primena mirusio tinklo elgesį.
Blokavimas nėra tas pats, kas soketo uždarymas. Programa vis dar laiko deskriptorių nustatytoje būsenoje, trūksta tik paketų. Todėl puslapis gali minutėmis sėdėti ant suktuko, kol operacinė sistema tvirtina, kad jungtis egzistuoja. Skaitykite dokumentuotą vykdymą, o ne spėkite jį iš programos pranešimo, nes abu elgesiai atrodo kaip sugedęs tinklas.
Ką programa daro, kol pertrauka trunka
TCP siunčia iš naujo didėjant vėlavimams, o numatytasis Linux bandymų biudžetas baigiasi ne per sekundes, o maždaug per ketvirtį valandos. Iki tol socketas nėra nei naudingai atidarytas, nei uždarytas. Programos su savo keepalive ar užklausų laiko limitu dažnai pasiduoda anksčiau, todėl du procesai toje pačioje mašinoje vieno gedimo metu elgiasi skirtingai.
Kai tunelis grįžta, vietinis socketas nepasikeitęs, bet maršrutas gali būti kitas. Naujas viešas šaltinio adresas serveryje sukuria kitą ketvertą, todėl tolimojoje pusėje esanti būsenos ugniasienė nebeatitinka sesijos. Ryšys miręs, nors klientas niekada nematė klaidos.
Nuspręskite, ar reikia atkūrimo
Rinkitės iš dviejų sutarčių. Arba sesija turi išgyventi trumpą pertrauką, tam reikia stabilaus adresavimo ir būseną išlaikančio serverio, arba programa turi švariai prisijungti iš naujo, tam reikia pakartoti saugios bandymų logikos. Bet kas per vidurį duoda blogiausią rezultatą: klientas, kuris iš naujo siunčia tai, ką serveris jau užfiksavo, arba toks, kuris praneša apie sėkmę sesijai, kurios niekas negali matyti.
Stabilus adresavimas yra ta dalis, kurią žmonės pamiršta, nes prisijungimas iš naujo, nusileidęs kitu viešu adresu, panaikina serverio pusės būseną net tada, kai kliento socketas atrodo sveikas. Užsirašykite, kuri iš dviejų sutarčių galioja kiekvienai programai, nes retai visos sutampa.
Blokavimą ir atkūrimą tikrinkite atskirai
Nuotėkio apsaugą ir sesijos išgyvenimą traktuokite kaip dvi savybes, nes vienos įveikimas nieko nesako apie kitą. Išgyvenusi sesija neįrodo, kad tiesioginis srautas buvo užblokuotas, o žuvusi sesija neįrodo, kad buvo užblokuotas kiekvienas tiesioginis maršrutas.
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'
Stebėdami atkūrimą naudokite nekenksmingą bandymo veiksmą, kad pasikartojęs siuntimas netaptų incidentu. Užrašykite gedimo būdą, kurį iš tikrųjų matėte: ką parodė programa, ar socketas išgyveno ir kada jis atsistatė pats.
Užrašykite tikėtiną elgesį šalia vykdymo taisyklės ir pažymėkite datą. Kitas žmogus, kuris pakeis tą taisyklę, turi žinoti, kurią iš dviejų sutarčių pažadėjo diegimas.