OpenVPN client-connect-feil: er opprydding ved disconnect garantert?
Ein avvist klient rullar ikkje tilbake ein brannmurregel eller ein skriven post. Samanlikn callback-kontrakten med tilbakerullinga hooken din sjølv må utføre.
Når eit client-connect-skript avsluttar med ein kode som ikkje er null, avviser OpenVPN klienten, og driftsansvarlege går vanlegvis ut frå at det tilhøyrande client-disconnect-skriptet ryddar opp. Ofte køyrer det aldri, fordi disconnect-handsaminga er avhengig av kva connect-fasen rakk å fullføre. Å handsame avvising og tilbakerulling som éin mekanisme er det som gjer ei mislukka innlogging til ein lekt brannmurregel eller ein foreldrelaus post. Det er to separate plikter, og berre éi av dei er automatisk. Les den eigne utgangsstien til hooken før du klandrar tenaren for å ha late att tilstand.
Ein utgang som ikkje er null avviser klienten; han rullar ikkje tilbake arbeidet ditt
Utgangsstatusen for client-connect er ei tilgangsavgjerd. Null tyder sleppe inn, alt anna tyder rive instansen ned før han er fullt etablert. Ingenting i den kontrakten undersøkjer kva skriptet alt har gjort mot omverda. Viss skriptet la til ein iptables-regel, skreiv ei rad eller auka ein teljar, overlever desse endringane avvisinga.
Den same asymmetrien gjeld for programtillegg, der fleire connect-funksjonar kan køyre for éin instans. Ein seinare feil annullerer ikkje ein tidlegare suksess med tilbakeverkande kraft, og den tidlegare funksjonen har ingen måte å få vite at ein systerfunksjon feila.
Avvising er automatisk, opprydding er det ikkje
OpenVPN 2.6-handboka knyter handsaminga av client-disconnect til at den førre connect-handsaminga lukkast. Eit dokumentert unntak dekkjer kaskadekjeder: viss eitt connect-steg alt har returnert suksess, køyrer dei tilhøyrande disconnect-stega likevel når instansen blir riven ned, sjølv om eit seinare connect-steg feila. Unntaket er smalt og avhengig av kor mange callbacks som er konfigurerte, og difor seier testing av eitt shell-skript deg ingenting om ei kjede.
Kartlegg den faktiske konfigurasjonen før du designar rundt han: kva skript, kva programtillegg og i kva rekkjefølgje dei køyrer. Tabellen nedanfor viser kva eit halvferdig oppsett lèt att.
| 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 |
Kvar rad endar likt for klienten og ulikt for verten. Klienten kan ikkje sjå kva av dei som hende, så hooken må rulle tilbake det han gjorde før han returnerer feilstatusen.
Kompensér inne i skriptet som feila
Valider alt du kan før du rører delt tilstand: sertifikatfelt, tilgjenge på adressa, gruppa klienten høyrer til. Den billegaste avvisinga er den som skjer før noka tildeling. Når oppsettet spenner over fleire eksterne operasjonar, før oversyn over kva som vart fullførte, og rull dei tilbake i omvend rekkjefølgje før du returnerer feilstatusen.
Eit konkret tilfelle: skriptet opprettar ein brannmurpost per klient og feilar deretter med å skrive tilstandsrada som skildrar han. Den feilande greina bør fjerne posten han nettopp oppretta og deretter avslutte med ein kode som ikkje er null. Å vente på ei disconnect-hending som kanskje aldri blir planlagd, er korleis ein regel overlever økta han var meint for.
Gjer kompensasjonen idempotent og eigd
Opprydding må vere trygg å køyre to gonger og presis på kva han kan slette. Ei sein hending frå eit tidlegare forsøk bør ikkje fjerne tildelinga til ei nyare økt berre fordi begge deler eit felles namn eller ei gjenbrukt tunelladresse. Registrer det konkrete handtaket eller operasjons-ID-en saman med ressursen, og slett etter den nøkkelen i staden for etter namn. Databasetransaksjonar hjelper berre med databasen sine eigne endringar; ein brannmurregel utanfor den grensa treng eit eksplisitt kompensasjonsteg.
Gå ut frå at prosessen kan døy mellom endringa og oppryddinga, og legg til ein avstemmar som etter ein plan samanliknar ekstern tilstand med lista over godkjende klientar.
Test dei tre stiane som faktisk er ulike
Øv på tre tilfelle: ei avvising før noko som helst er tildelt, ei etter ei delvis tildeling, og ei normal godkjend økt som seinare blir avslutta. Dei tre gir ulike logglinjer og ulike restar. Stadfest ekstern tilstand etter kvar av dei, ikkje berre feilmeldinga til klienten, fordi feilen til klienten er det forventa resultatet i to av dei tre.
Logg fasen til hooken, utgangsstatusen og kva som vart tildelt eller frigitt, utan påloggingsdetaljar. Ein hook-logg som namngir ressursen han oppretta, er det som gjer ein lekt regel finnbar seks månader seinare.