OpenVPN client-connect-fiasko: ĉu la purigo ĉe disconnect estas garantiita?
Rifuzita kliento ne malfaras fajroŝirman regulon nek skribitan rikordon. Komparu la kontrakton de la retroalvoko kun la retroigo, kiun via hoko devas fari mem.
Kiam skripto client-connect eliras per ne-nula kodo, OpenVPN rifuzas la klienton, kaj administrantoj kutime supozas, ke la responda skripto client-disconnect ordigas ĉion. Ofte ĝi neniam ruliĝas, ĉar la prilaborado de disconnect dependas de tio, kion la fazo connect sukcesis fini. Trakti rifuzon kaj retroigon kiel unu mekanismon estas tio, kio igas malsukcesan ensaluton likinta fajroŝirma regulo aŭ orfa rikordo. Temas pri du apartaj devoj, kaj nur unu el ili estas aŭtomata. Legu la propran eliran vojon de la hoko antaŭ ol kulpigi la servilon pro lasita stato.
Ne-nula eliro rifuzas la klienton; ĝi ne malfaras vian laboron
La elira statuso de client-connect estas akcepta decido. Nulo signifas akcepti, io ajn alia signifas malkonstrui la kazon antaŭ ol ĝi plene establiĝos. Nenio en tiu kontrakto inspektas, kion la skripto jam faris al la ekstera mondo. Se la skripto aldonis iptables-regulon, skribis vicon aŭ pliigis nombrilon, tiuj ŝanĝoj postvivas la rifuzon.
La sama asimetrio validas por kromaĵoj, kie pluraj funkcioj connect povas ruliĝi por unu kazo. Pli malfrua fiasko ne retrokancelas pli fruan sukceson, kaj la pli frua funkcio havas neniun rimedon ekscii, ke ĝemela funkcio fiaskis.
Rifuzo estas aŭtomata, purigo ne
La manlibro de OpenVPN 2.6 ligas la prilaboradon de client-disconnect al antaŭa sukcesa prilaborado de connect. Dokumentita escepto kovras kaskadajn ĉenojn: se unu paŝo connect jam redonis sukceson, la respondaj paŝoj disconnect tamen ruliĝas kiam la kazo estas malkonstruata, eĉ se pli malfrua paŝo connect fiaskis. Tiu escepto estas mallarĝa kaj dependas de tio, kiom da retroalvokoj estas agorditaj, do testado de unu ŝela skripto diras al vi nenion pri ĉeno.
Mapu la efektivan agordon antaŭ ol desegni ĉirkaŭ ĝi: kiu skripto, kiu kromaĵo kaj laŭ kiu ordo ili ruliĝas. La suba tabelo listigas, kion duonfinita agordo lasas malantaŭe.
| 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 |
Ĉiu vico finiĝas same por la kliento kaj malsame por la gastiganto. La kliento ne povas scii, kiu el ili okazis, do la hoko devas malfari tion, kion ĝi faris, antaŭ ol redoni la fiaskan statuson.
Kompensu ene de la skripto, kiu fiaskis
Validigu ĉion eblan antaŭ ol tuŝi kunhavatan staton: atestilajn kampojn, haveblecon de la adreso, la grupon, al kiu apartenas la kliento. La plej malmultekosta rifuzo estas tiu, kiu okazas antaŭ ajna atribuo. Post kiam la agordo enhavas plurajn eksterajn operaciojn, tenu registron pri tio, kiuj finiĝis, kaj malfaru ilin en inversa ordo antaŭ ol redoni la fiaskan statuson.
Konkreta kazo: la skripto kreas fajroŝirman enskribon por ĉiu kliento, poste fiaskas skribi la statan vicon, kiu priskribas ĝin. La fiaska branĉo devus forigi la ĵus kreitan enskribon kaj poste eliri per ne-nula kodo. Atendi disconnect-eventon, kiu eble neniam estos planita, estas kiel regulo postvivas la sesion, por kiu ĝi estis celita.
Igu la kompenson idempota kaj posedata
Purigo devas esti sekura por duobla rulado kaj preciza pri tio, kion ĝi rajtas forigi. Malfrua evento el pli frua provo ne devus forigi la atribuon de pli nova sesio nur ĉar ambaŭ kunhavas komunan nomon aŭ recikligitan tunelan adreson. Registru la specifan tenilon aŭ operacian identigilon kun la rimedo, kaj forigu laŭ tiu ŝlosilo anstataŭ laŭ nomo. Datumbazaj transakcioj helpas nur pri la propraj ŝanĝoj de la datumbazo; fajroŝirma regulo ekster tiu limo bezonas eksplicitan kompensan paŝon.
Supozu, ke la procezo povas morti inter la ŝanĝo kaj la purigo, kaj aldonu repacigilon, kiu laŭ horaro komparas la eksteran staton kun la listo de akceptitaj klientoj.
Testu la tri vojojn, kiuj vere malsamas
Ekzercu tri kazojn: rifuzon antaŭ ol io ajn estas atribuita, rifuzon post parta atribuo, kaj normalan akceptitan sesion, kiu poste finiĝas. Tiuj tri produktas malsamajn protokolajn liniojn kaj malsamajn restaĵojn. Kontrolu la eksteran staton post ĉiu el ili, ne nur la fiaskan mesaĝon de la kliento, ĉar la fiasko de la kliento estas la atendata rezulto en du el la tri.
Registru la hokan fazon, la eliran statuson kaj tion, kio estis atribuita aŭ liberigita, sen la legitimiloj. Hoka protokolo, kiu nomas la rimedon, kiun ĝi kreis, estas tio, kio igas likintan regulon trovebla ses monatojn poste.