Kun client-connect-skripti päättyy nollasta poikkeavaan koodiin, OpenVPN hylkää asiakkaan, ja ylläpitäjät olettavat yleensä, että vastaava client-disconnect-skripti siivoaa. Usein se ei koskaan käynnisty, koska disconnectin käsittely riippuu siitä, mitä connect-vaihe onnistui saamaan valmiiksi. Hylkäyksen ja palautuksen pitäminen yhtenä mekanismina muuttaa epäonnistuneen kirjautumisen vuotaneeksi palomuurisäännöksi tai orvoksi jääneeksi tietueeksi. Ne ovat kaksi erillistä velvollisuutta, ja vain toinen niistä on automaattinen. Lue hookin oma poistumispolku ennen kuin syytät palvelinta tilan jättämisestä.

Nollasta poikkeava poistuminen hylkää asiakkaan; se ei peru työtäsi

client-connectin poistumistila on hyväksymispäätös. Nolla tarkoittaa hyväksy, mikä tahansa muu tarkoittaa instanssin purkamista ennen kuin se on täysin vakiintunut. Mikään siinä sopimuksessa ei tarkasta, mitä skripti on jo tehnyt ulkomaailmalle. Jos skripti lisäsi iptables-säännön, kirjoitti rivin tai kasvatti laskuria, ne muutokset jäävät hylkäyksestä huolimatta voimaan.

Sama epäsymmetria koskee laajennuksia, joissa yhdelle instanssille voi käynnistyä useita connect-funktioita. Myöhempi epäonnistuminen ei peruuta takautuvasti aiempaa onnistumista, eikä aiemmalla funktiolla ole keinoa tietää, että sisarfunktio epäonnistui.

Hylkäys on automaattinen, siivous ei

OpenVPN 2.6 -käsikirja sitoo client-disconnectin käsittelyn aiemman connect-käsittelyn onnistumiseen. Dokumentoitu poikkeus kattaa kaskadiketjut: jos yksi connect-vaihe on jo palauttanut onnistumisen, vastaavat disconnect-vaiheet ajetaan silti instanssia purettaessa, vaikka myöhempi connect-vaihe epäonnistui. Poikkeus on kapea ja riippuu siitä, kuinka monta callbackia on määritetty, minkä vuoksi yhden shell-skriptin testaaminen ei kerro ketjusta mitään.

Kartoita todellinen kokoonpano ennen kuin suunnittelet sen ympärille: mikä skripti, mikä laajennus ja missä järjestyksessä ne ajetaan. Alla oleva taulukko luettelee, mitä puolivalmis asennus jättää jälkeensä.

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

Jokainen rivi päättyy asiakkaalle samalla tavalla ja isännälle eri tavalla. Asiakas ei voi tietää, mikä niistä tapahtui, joten hookin on purettava tekemänsä ennen virhetilan palauttamista.

Kompensoi epäonnistuneen skriptin sisällä

Validoi kaikki mahdollinen ennen jaetun tilan koskettamista: varmennekentät, osoitteen saatavuus, ryhmä, johon asiakas kuuluu. Halvin hylkäys on se, joka tapahtuu ennen mitään varausta. Kun asennus kattaa useita ulkoisia toimintoja, pidä kirjaa siitä, mitkä valmistuivat, ja peru ne käänteisessä järjestyksessä ennen virhetilan palauttamista.

Konkreettinen tapaus: skripti luo asiakaskohtaisen palomuurimerkinnän ja epäonnistuu sitten kirjoittamaan sitä kuvaavan tilan rivin. Epäonnistuvan haaran pitäisi poistaa juuri luotu merkintä ja poistua sitten nollasta poikkeavalla koodilla. Sellaisen disconnect-tapahtuman odottaminen, jota ei ehkä koskaan ajasteta, on tapa, jolla sääntö elää pidempään kuin istunto, jota varten se oli tarkoitettu.

Tee kompensaatiosta idempotentti ja omistettu

Siivouksen on oltava turvallista ajaa kahdesti ja täsmällinen siitä, mitä se saa poistaa. Aiemman yrityksen myöhäinen tapahtuma ei saisi poistaa uudemman istunnon varausta vain siksi, että molemmilla on yhteinen nimi tai kierrätetty tunneliosoite. Tallenna tarkka kahva tai toimintotunniste resurssin yhteyteen ja poista sen avaimen perusteella nimen sijaan. Tietokantatransaktiot auttavat vain tietokannan omissa muutoksissa; palomuurisääntö tuon rajan ulkopuolella tarvitsee erillisen kompensointivaiheen.

Oleta, että prosessi voi kuolla muutoksen ja siivouksen välissä, ja lisää täsmäyttäjä, joka vertaa ulkoista tilaa hyväksyttyjen asiakkaiden luetteloon aikataulun mukaan.

Testaa kolme polkua, jotka todella eroavat

Harjoittele kolme tapausta: hylkäys ennen kuin mitään on varattu, hylkäys osittaisen varauksen jälkeen ja normaali hyväksytty istunto, joka päättyy myöhemmin. Nämä kolme tuottavat erilaisia lokirivejä ja erilaisia jäänteitä. Varmista ulkoinen tila jokaisen jälkeen, älä vain asiakkaan virheilmoitusta, koska asiakkaan epäonnistuminen on odotettu tulos kahdessa kolmesta.

Kirjaa hookin vaihe, poistumistila ja mitä varattiin tai vapautettiin, ilman tunnuksia. Hookin loki, joka nimeää luodun resurssin, on se, mikä tekee vuotaneesta säännöstä löydettävän kuusi kuukautta myöhemmin.

Aiheeseen liittyvät artikkelit