Palvelu käynnistyy, lukee profiilin valittamatta ja kuolee sitten rivillä, joka näyttää asiattomalta: se ei voi avata tiedostoa ca.crt. Sertifikaatissa ei ole muuttunut mikään, ja profiilin polku unit-tiedostossa on absoluuttinen. Juuri se yhdistelmä on vihje. Antamasi polku paikantaa yhden tiedoston, ja sen tiedoston sisällä olevat nimet ratkaistaan aivan muualla, joten täysin kelpuutetulta näyttävä käynnistys voi silti lukea avaimensa hakemistosta, jota kukaan ei tarkoittanut.

Epäonnistumisella on vähän syitä, ja ne kannattaa erottaa järjestyksessä: perushakemisto, joka prosessilla todella oli, palvelun käynnistyskonteksti sekä tiedoston ympärillä olevat oikeudet tai hiekkalaatikko, kun polku on oikein. Jokainen jättää erilaisen jäljen — unit-tiedostoon, prosessiin ja tiedostojärjestelmään.

Profiilin polku ei ole perushakemisto

Kuvittele prosessi, joka käynnistyy hakemistossa /tmp ja saa /etc/vpn/prod/tenant-a.ovpn. Profiilin sisällä rivi ca ca.crt nimeää suhteellisen polun. Mikään profiilin paikantaneessa argumentissa ei kirjoita sitä nimeä uudelleen, joten prosessi etsii polkua /tmp/ca.crt ja ilmoittaa puuttuvasta tiedostosta.

Hämmentävää on virheiden järjestys. OpenVPN jäsentää ensin kokoonpanon ja avaa viitatut tiedostot niihin päästyään, joten profiilin kirjoitusvirhe ilmoitetaan ennen kuin yhteenkään avaimeen kosketaan, kun taas puuttuva sertifikaatti ilmaantuu vasta kun jäsennys etenee sinne asti. Latautuva profiili on siis todiste syntaksin kunnosta, ei siitä, että sen nimeämät tiedostot löytyivät.

Mitä käsikirja erottaa: --config ja --cd

OpenVPN 2.6:n käsikirja kuvaa kaksi eri vaihtoehtoa. Toinen lataa kokoonpanotiedoston. Toinen vaihtaa prosessin hakemiston ennen kuin kokoonpano, avain, skripti ja muut tiedostot luetaan, ja vaatii absoluuttisen hakemiston ilman viittausta nykyiseen.

openvpn --cd /etc/vpn/prod --config tenant-a.ovpn

Tuo kutsu on muoto, ei ohje käynnistää jonkun toisen profiilia. Se antaa determinismiä: ketjun jokaisen suhteellisen nimen perusta sanotaan komennossa sen sijaan, että se perittäisiin kuoresta tai hallinnasta, joka prosessin käynnisti. Vaihtoehto on yhtä kelvollinen ja palvelulle usein parempi: jätä työhakemisto rauhaan ja tee jokaisesta viitatusta tiedostosta absoluuttinen profiilin sisällä.

Minkä valitsetkin, tarkasta koko ketju äläkä ensimmäistä epäonnistumista. Profiili voi vetää mukaan toisen kokoonpanotiedoston, ja sisällytetyn tiedoston suhteelliset nimet ratkaistaan samaa prosessihakemistoa vasten, eivät sen tiedoston hakemistoa vasten, joka ne sisällytti. Lokipolut, todennustiedostot ja apuskriptit noudattavat samaa sääntöä.

Palvelu käynnistyy muualla

Interaktiivinen kuori profiilihakemistossa ei todista mitään paketoidusta unit-tiedostosta. Hallinnat asettavat oman työhakemistonsa, ja kääreskripti voi muuttaa sitä uudelleen ennen kuin binääri käynnistyy. Epäonnistuva unit on ainoa käynnistys, jonka yli kannattaa järkeillä.

systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd

Toinen komento näyttää hakemiston, jota elävä prosessi todella pitää, ja se on luotettavampi kuin unit-tiedosto, kun kääre on mukana. Jos ne kaksi ovat eri mieltä, kääre on vastauksesi ja unit on harhautus.

Haun jälkeen: oikeudet, chroot ja hiekkalaatikko

Oikea perushakemisto voi silti tuottaa saman viestin, koska ratkaisu ja pääsy ovat erillisiä vaiheita. Prosessi tarvitsee suoritusoikeuden jokaiseen ylähakemistoon ja lukuoikeuden tiedostoon, ja palvelun unit, joka kätkee osan tiedostojärjestelmästä, muuttaa sitä, mitä prosessi ylipäätään voi nähdä.

Kolme tavallista varianttia tuottavat saman virheen. Tiedosto on luettavissa vain rootille, kun taas palvelu luopuu oikeuksistaan ennen sen avaamista. Unit asettaa suojaavan tiedostojärjestelmänäkymän, joka ei sisällä profiilihakemistoa. Daemon toimii chrootissa, joten isännällä oleva polku ei ole olemassa tuon näkymän sisällä.

Diagnosoi tiedoston omistajan ja prosessin identiteetin avulla, älä höllentämällä oikeuksia. Yksityisen avaimen tekeminen kaikkien luettavaksi tämän virheen vaientamiseksi vaihtaa äänekkään epäonnistumisen hiljaiseen, ja avain on juuri se hakemiston osa, jonka paljastamista vähiten haluat.

Todista korjaus omalla käynnistykselläsi

Käynnistä oikea unit uudelleen hakemistosta, jolla ei ole yhteyttä profiiliin, ja seuraa samaa käynnistysriviä. Vahvista sitten, että prosessi pitää käydessään aiottua hakemistoa ja että lataamasi sertifikaatti on odottamasi.

systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager

Kun polkujen lataus onnistuu, todennus ja reititys ovat yhä erillisiä vaiheita omine epäonnistumisineen, ja yhteys, joka nousee mutta ei välitä liikennettä, on toinen tutkinta. Korjaus tässä koskee vain sitä, mistä hakemistosta tiedostot tulivat, ja sen pitäisi näkyä kutsussa sen sijaan, että joku muistaisi sen, joka viimeksi ajoi sen käsin.

Jos profiili jaellaan kokoonpanonhallinnalla, laita perushakemisto tai absoluuttiset tiedostonimet myös sinne. Käsin tehty korjaus yhdellä isännällä on tämän ongelman versio, joka palaa seuraavan uudelleenrakennuksen jälkeen.

Aiheeseen liittyvät artikkelit