OpenVPN client-connect kļūda: vai tīrīšana pie disconnect ir garantēta?
Noraidīts klients neatceļ ugunsmūra noteikumu vai ierakstu. Salīdziniet callback līgumu ar atritināšanu, kas jūsu hook jāveic pašam.
Kad client-connect skripts beidzas ar kodu, kas nav nulle, OpenVPN noraida klientu, un administratori parasti pieņem, ka atbilstošais client-disconnect skripts visu sakārtos. Bieži tas nemaz nepalaižas, jo disconnect apstrāde ir atkarīga no tā, ko connect posms paspēja pabeigt. Noraidījuma un atritināšanas uzskatīšana par vienu mehānismu ir tas, kas neizdevušos pieteikšanos pārvērš noplūdušā ugunsmūra noteikumā vai bāreņa ierakstā. Tie ir divi atsevišķi pienākumi, un tikai viens no tiem ir automātisks. Izlasiet paša hook iziešanas ceļu, pirms vainojat serveri atstātā stāvoklī.
Izeja, kas nav nulle, noraida klientu; tā neatceļ jūsu darbu
client-connect iziešanas statuss ir uzņemšanas lēmums. Nulle nozīmē uzņemt, jebkas cits nozīmē nojaukt instanci pirms tās pilnīgas izveides. Nekas šajā līgumā nepārbauda, ko skripts jau ir izdarījis ārējā pasaulē. Ja skripts pievienoja iptables noteikumu, ierakstīja rindu vai palielināja skaitītāju, šīs izmaiņas pārdzīvo noraidījumu.
Tā pati asimetrija attiecas uz spraudņiem, kur vienai instancei var darboties vairākas connect funkcijas. Vēlāka kļūda ar atpakaļejošu spēku neatceļ agrāku panākumu, un agrākajai funkcijai nav veida uzzināt, ka māsas funkcija neizdevās.
Noraidījums ir automātisks, tīrīšana nav
OpenVPN 2.6 rokasgrāmata saista client-disconnect apstrādi ar iepriekšējās connect apstrādes panākumiem. Dokumentēts izņēmums attiecas uz kaskādes ķēdēm: ja viens connect solis jau ir atgriezis panākumus, atbilstošie disconnect soļi tomēr darbojas, kad instance tiek nojaukta, pat ja vēlāks connect solis neizdevās. Šis izņēmums ir šaurs un atkarīgs no tā, cik callback ir konfigurēti, tāpēc viena shell skripta testēšana neko nepasaka par ķēdi.
Kartējiet faktisko konfigurāciju, pirms projektējat ap to: kurš skripts, kurš spraudnis un kādā secībā tie darbojas. Tālāk esošā tabula uzskaita, ko atstāj pusgatavs iestatījums.
| What the hook did before failing | What the client sees | What stays behind |
|---|---|---|
| Created a firewall entry | A rejection, with no tunnel | A rule matching an address nobody owns |
| Wrote a state row | A rejection, with no tunnel | A record of a session that never started |
| Allocated a tunnel address | A rejection, with no tunnel | An address marked busy until something releases it |
Katra rinda beidzas vienādi klientam un citādi resursdatoram. Klients nevar pateikt, kurš no tiem notika, tāpēc hook ir jāatritina tas, ko tas izdarīja, pirms atgriež kļūdas statusu.
Kompensējiet neizdevušajā skriptā
Pārbaudiet visu, ko varat, pirms pieskaraties koplietotajam stāvoklim: sertifikāta laukus, adreses pieejamību, grupu, kurai klients pieder. Lētākais noraidījums ir tas, kas notiek pirms jebkādas piešķiršanas. Kad iestatījums aptver vairākas ārējas darbības, reģistrējiet, kuras tika pabeigtas, un atritiniet tās apgrieztā secībā, pirms atgriežat kļūdas statusu.
Konkrēts gadījums: skripts izveido ugunsmūra ierakstu katram klientam un pēc tam nespēj ierakstīt stāvokļa rindu, kas to apraksta. Neizdevušajai atzarojumam vajadzētu noņemt tikko izveidoto ierakstu un pēc tam iziet ar kodu, kas nav nulle. Gaidīšana uz disconnect notikumu, kas varbūt nekad netiks ieplānots, ir veids, kā noteikums pārdzīvo sesiju, kurai tas bija paredzēts.
Padariet kompensāciju idempotentu un ar īpašnieku
Tīrīšanai jābūt drošai divreiz un precīzai par to, ko tā drīkst dzēst. Vēls notikums no agrāka mēģinājuma nedrīkst noņemt jaunākas sesijas piešķīrumu tikai tāpēc, ka abiem ir kopīgs nosaukums vai pārstrādāta tuneļa adrese. Reģistrējiet konkrēto rokturi vai darbības ID kopā ar resursu un dzēsiet pēc šīs atslēgas, nevis pēc nosaukuma. Datu bāzes transakcijas palīdz tikai ar pašas datu bāzes izmaiņām; ugunsmūra noteikumam ārpus šīs robežas ir vajadzīgs skaidrs kompensācijas solis.
Pieņemiet, ka process var nomirt starp izmaiņām un tīrīšanu, un pievienojiet saskaņotāju, kas pēc grafika salīdzina ārējo stāvokli ar uzņemto klientu sarakstu.
Pārbaudiet trīs ceļus, kas patiešām atšķiras
Praktizējiet trīs gadījumus: noraidījumu pirms kaut kas tiek piešķirts, noraidījumu pēc daļējas piešķiršanas un parastu uzņemtu sesiju, kas vēlāk beidzas. Šie trīs rada atšķirīgas žurnāla rindas un atšķirīgus atlikumus. Pārbaudiet ārējo stāvokli pēc katra no tiem, ne tikai klienta kļūdas ziņojumu, jo klienta neizdošanās ir gaidītais rezultāts divos no trim.
Reģistrējiet hook posmu, iziešanas statusu un to, kas tika piešķirts vai atbrīvots, bez akreditācijas datiem. Hook žurnāls, kas nosauc tā izveidoto resursu, ir tas, kas noplūdušo noteikumu padara atrodamu sešus mēnešus vēlāk.