Voiko OpenVPN:n koukkuskripti käyttää tunnelia, jonka se juuri rakensi?
OpenVPN ajaa koukut oman käynnistyksensä sisällä, joten tunnelia tarvitseva skripti odottaa tunnelia, joka odottaa sitä. Irrota työ ja valitse koukku tapahtuman mukaan.
Se, yltääkö koukkuskripti tunnelin toiselle puolelle, riippuu kolmesta ehdosta: mihin tapahtumaan se on liitetty, onko OpenVPN skriptin ajaessa vielä käynnistysjaksossaan ja onko työ irrotettu siitä jaksosta. Useimmat skriptit epäonnistuvat kolmannessa. Nukkumisen lisääminen kohtelee elinkaariongelmaa ajoitusongelmana, ja se toimii juuri riittävän usein harhauttaakseen.
Päätä ensin tapahtuma, sitten työn lykkäämisen mekanismi, sitten paikka, jossa lykätty työ ajetaan. Nämä kolme päätöstä ovat toisistaan riippumattomia, ja niiden sekoittaminen on syy siihen, miksi kahden rivin koukusta tulee kokonainen iltapäivä.
Miksi koukku odottaa tunnelia, joka odottaa sitä
OpenVPN kutsuu koukkujaan synkronisesti samassa prosessissa, joka siirtää paketteja. up laukeaa, kun tun- tai tap-laite on olemassa mutta ennen minkään reitin lisäämistä, ja route-up reittien jälkeen; kumpikaan hetki ei lupaa, että vastapuoli vastaa. Kun kumman tahansa koukun skripti vielä ajaa, taustapalvelu ei välitä, joten komento, joka odottaa liikenteen kulkevan tunnelin läpi, odottaa tunnelia, joka odottaa komentoa. Tämä kehämäinen odotus on syy siihen, että käsin ajaminen onnistuu ja koukku aikakatkaistaan.
Ilmeinen paikkaus, muutaman sekunnin nukkuminen, toimii joskus siksi, että kaukopää nousi itsestään, ei siksi että nukkuminen korjasi jotain. Valmiutta kysyvä apuri on toinen vastaus: koukku palaa, välitys alkaa ja apuri saa tarvitsemansa, kun se todella on siellä.
Valitse koukku tapahtuman, älä mukavuuden mukaan
Liitä up työhön, joka tarvitsee vain laitteen, route-up työhön, joka tarvitsee reitit, ja säästä client-connect ja client-disconnect palvelinpuolen asiakaskohtaisiin tehtäviin. Yhteyden katkaisun siivous on tehtävä kestämään kahdesti ajaminen, koska pysyvän liitännän kautta tapahtuvat uudelleenyhdistämiset eivät noudata samaa jaksoa kuin täysi uudelleenkäynnistys. Palvelimella client-connect laukeaa, kun asiakas todentaa itsensä, ei kun taustapalvelu käynnistyy, mikä kannattaa vahvistaa ennen logiikan siirtämistä sinne. Jos työ kuuluu palvelun elinkaareen eikä yhteen yhteyteen, systemd-yksikkö on parempi koti kuin mikään koukku.
Koukkukomennot suorittaa suoraan taustapalvelu ilman välissä olevaa kuorta, joten up-rivillä oleva ifconfig_remote saapuu kirjaimellisena tekstinä. Kääri komento nimenomaiseen kuoreen tai pidä logiikka skriptissä, joka lukee ympäristön. ipchange on yksi direktiivi, joka lisää omat argumenttinsa: se antaa komennolle osoitteen ja portin, joten kenellekään kirjoitettu skripti näkee kaksi odottamatonta.
Kolme tapaa irrottaa työ
Ensimmäinen vaihtoehto on lähettää apuri taustalle koukun sisältä: käynnistä se setsid tai systemd-run --scope avulla, sulje perityt kuvaajat ja poistu heti nollalla. Toinen on antaa koukun kirjoittaa pieni tilatiedosto ja antaa systemd-ajastimen tai polkuyksikön toimia sen perusteella, mikä pitää koukun triviaalina ja sijoittaa uudelleenyrityskäytännön sinne, missä on lokit. Kolmas on hylätä koukku kokonaan ja siirtää työ yksikköön, joka on järjestetty VPN-palvelun jälkeen, mikä on oikea vastaus, kun työ ei ole lainkaan yhteyskohtaista. Kaikki kolme jakavat yhden säännön: koukun on palattava ennen kuin se tarvitsee tunnelia.
Minkä tahansa valitsetkin, tee apurista idempotentti ja havaittava. Kahden päällekkäisen kutsun ei pitäisi suorittaa samaa peruuttamatonta toimintoa kahdesti, ja epäonnistuvan apurin on jätettävä jotain, mitä ihminen voi lukea.
Erota hiekkalaatikon viat elinkaarivioista
Kun skripti ajetaan root-kehotteesta ja epäonnistuu palveluna, syy on yleensä hiekkalaatikko eikä verkko. Rajoittava ProtectHome, vain luku -tilassa oleva ProtectSystem tai työhakemisto, jota ei ole voivat jättää skriptin tai sen tiedot ulottumattomiin, ja SELinux-isännässä tiedosto tarvitsee myös kontekstin, joka sallii suorittamisen. Lue yksikkö komennolla systemctl cat openvpn-server@server ja loki komennolla journalctl -u openvpn-server@server -n 80, etsi sitten käyttöoikeus- tai kontekstivirhettä yhteyden aikakatkaisun sijaan. Hiekkalaatikon poistaminen käytöstä pitäisi olla viimeinen liike, ei ensimmäinen.
Elinkaarivika näyttää erilaiselta: koukku käynnistyy, apuri ajaa, eikä pistoke yksinkertaisesti ole vielä siellä. Kirjoita aikaleimattu rivi itse koukusta, katkaise ja yhdistä uudelleen, ja lue tapahtumat järjestyksessä. Kun apuri todella tarvitsee tunnelin, anna sen kysyä valmiutta sen sijaan että se nukkuu kiinteän ajan.
Kolme kenttää tekevät seuraavasta raportista hyödyllisen: mikä koukku ajoi, mitä tiliä se käytti ja mihin se pysähtyi. Ilman niitä jokainen myöhempi tutkinta alkaa alusta.