OpenVPN client-connect-virhe: onko disconnectin siivous taattu?
Hylätty asiakas ei peru palomuurisääntöä eikä kirjoitettua tietuetta. Vertaa callback-sopimusta siihen palautukseen, jonka hookisi on tehtävä itse.
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 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 |
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.