Kai client-connect scenarijus baigiasi nuliniu kodu, OpenVPN atmeta klientą, o administratoriai paprastai mano, kad atitinkamas client-disconnect scenarijus viską sutvarkys. Dažnai jis apskritai nepasileidžia, nes disconnect apdorojimas priklauso nuo to, ką connect etapas spėjo užbaigti. Atmetimo ir atsukimo traktavimas kaip vieno mechanizmo yra tai, kas nepavykusį prisijungimą paverčia nutekėjusia ugniasienės taisykle arba našlaičiu įrašu. Tai dvi atskiros prievolės, ir tik viena jų yra automatinė. Perskaitykite paties hook išėjimo kelią, prieš kaltindami serverį palikus būseną.

Nulinis išėjimas atmeta klientą, bet neatšaukia jūsų darbo

client-connect išėjimo būsena yra priėmimo sprendimas. Nulis reiškia priimti, bet kuri kita reikšmė reiškia išardyti egzempliorių prieš jam visiškai įsitvirtinant. Niekas toje sutartyje netikrina, ką scenarijus jau padarė išoriniame pasaulyje. Jei scenarijus pridėjo iptables taisyklę, įrašė eilutę ar padidino skaitiklį, tie pakeitimai išlieka po atmetimo.

Ta pati asimetrija galioja papildiniams, kur vienam egzemplioriui gali veikti keli connect funkcijos. Vėlesnė klaida neatšaukia ankstesnės sėkmės atgaline data, o ankstesnė funkcija neturi būdo sužinoti, kad seserinė funkcija nepavyko.

Atmetimas automatinis, valymas ne

OpenVPN 2.6 vadove client-disconnect apdorojimas susietas su ankstesnio connect apdorojimo sėkme. Dokumentuota išimtis apima kaskadines grandines: jei vienas connect žingsnis jau grąžino sėkmę, atitinkami disconnect žingsniai vis tiek vykdomi ardant egzempliorių, net jei vėlesnis connect žingsnis nepavyko. Ta išimtis siaura ir priklauso nuo to, kiek callback sukonfigūruota, todėl vieno shell scenarijaus testavimas nieko nepasako apie grandinę.

Susiekite tikrąją konfigūraciją, prieš projektuodami aplink ją: kuris scenarijus, kuris papildinys ir kokia tvarka jie vykdomi. Toliau pateiktoje lentelėje išvardyta, ką palieka nebaigtas nustatymas.

What the hook did before failingWhat the client seesWhat stays behind
Created a firewall entryA rejection, with no tunnelA rule matching an address nobody owns
Wrote a state rowA rejection, with no tunnelA record of a session that never started
Allocated a tunnel addressA rejection, with no tunnelAn address marked busy until something releases it

Kiekviena eilutė baigiasi vienodai klientui ir kitaip hostui. Klientas negali pasakyti, kuris atvejis įvyko, todėl hook turi atsukti tai, ką padarė, prieš grąžindamas klaidos būseną.

Kompensuokite nepavykusiame scenarijuje

Patikrinkite viską, ką galite, prieš liesdami bendrą būseną: sertifikato laukus, adreso prieinamumą, grupę, kuriai priklauso klientas. Pigiausias atmetimas yra tas, kuris įvyksta prieš bet kokį priskyrimą. Kai nustatymas apima kelias išorines operacijas, veskite apskaitą, kurios baigtos, ir prieš grąžindami klaidos būseną atsukite jas atvirkštine tvarka.

Konkretus atvejis: scenarijus sukuria ugniasienės įrašą kiekvienam klientui, o paskui nepavyksta įrašyti jį apibūdinančios būsenos eilutės. Nepavykusi šaka turėtų pašalinti ką tik sukurtą įrašą ir tada baigtis nuliniu kodu. Laukimas disconnect įvykio, kuris galbūt niekada nebus suplanuotas, yra būdas, kuriuo taisyklė pergyvena sesiją, kuriai buvo skirta.

Padarykite kompensaciją idempotentišką ir turinčią savininką

Valymas turi būti saugus vykdyti du kartus ir tikslus dėl to, ką gali ištrinti. Vėlyvas ankstesnio bandymo įvykis neturėtų pašalinti naujesnės sesijos priskyrimo vien todėl, kad abu turi bendrą pavadinimą ar perdirbtą tunelio adresą. Įrašykite konkretų rankenėlę arba operacijos ID kartu su ištekliumi ir trinkite pagal tą raktą, o ne pagal pavadinimą. Duomenų bazės transakcijos padeda tik su pačios duomenų bazės pakeitimais; ugniasienės taisyklė už šios ribos reikalauja aiškaus kompensacijos žingsnio.

Tarkime, kad procesas gali mirti tarp pakeitimo ir valymo, ir pridėkite derintoją, kuris pagal grafiką lygina išorinę būseną su priimtų klientų sąrašu.

Išbandykite tris tikrai skirtingus kelius

Praktikuokite tris atvejus: atmetimą prieš ką nors priskiriant, atmetimą po dalinio priskyrimo ir įprastą priimtą sesiją, kuri vėliau baigiasi. Šie trys duoda skirtingas žurnalo eilutes ir skirtingus likučius. Patikrinkite išorinę būseną po kiekvieno, o ne tik kliento klaidos pranešimą, nes kliento nepavykimas yra laukiamas rezultatas dviem iš trijų atvejų.

Registruokite hook etapą, išėjimo būseną ir tai, kas buvo priskirta ar atleista, be prisijungimo duomenų. Hook žurnalas, kuriame nurodytas jo sukurtas išteklius, yra tai, kas nutekėjusią taisyklę padaro randamą po šešių mėnesių.

Susiję straipsniai