Tjenesten starter, leser profilen uten klager og dør så på en linje som virker urelatert: den kan ikke åpne ca.crt. Ingenting ved sertifikatet er endret, og profilbanen i unit-filen er absolutt. Nettopp den kombinasjonen er hintet. Banen du oppga, lokaliserer én fil, og navnene inne i den filen løses helt andre steder, så en oppstart som ser fullt kvalifisert ut, kan fortsatt lese nøklene sine fra en katalog ingen hadde tenkt seg.

Feilen har få årsaker, og de er verdt å skille i rekkefølge: basiskatalogen prosessen faktisk hadde, oppstartskonteksten til tjenesten og tillatelsene eller sandkassen rundt filen når banen først er riktig. Hver av dem etterlater et ulikt spor — i unit-filen, i prosessen og på filsystemet.

Profilstien er ikke en basiskatalog

Se for deg en prosess som starter i /tmp og får /etc/vpn/prod/tenant-a.ovpn. Inne i den profilen navngir linjen ca ca.crt en relativ bane. Ingenting i argumentet som fant profilen, skriver om det navnet, så prosessen leter etter /tmp/ca.crt og rapporterer en manglende fil.

Det forvirrende er rekkefølgen på feilene. OpenVPN parser konfigurasjonen først og åpner refererte filer etter hvert som det når dem, så en skrivefeil i profilen rapporteres før noen nøkkel berøres, mens et manglende sertifikat først dukker opp når parsingen kommer dit. En profil som lastes, er derfor bevis på at syntaksen er riktig, ikke at filene den navngir, ble funnet.

Hva håndboken skiller: --config og --cd

Håndboken for OpenVPN 2.6 beskriver to ulike valg. Det ene laster en konfigurasjonsfil. Det andre bytter katalogen til prosessen før konfigurasjon, nøkkel, skript og andre filer leses, og krever en absolutt katalog uten henvisning til den gjeldende.

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

Det kallet er en form, ikke en instruks om å starte noen andres profil. Det du får, er determinisme: basisen for hvert relative navn i kjeden står i kommandoen i stedet for å arves fra hvilken som helst shell eller håndterer som startet prosessen. Alternativet er like gyldig og ofte bedre for en tjeneste: la arbeidskatalogen være og gjør hver referert fil absolutt inne i profilen.

Uansett hva du velger, revider hele kjeden og ikke den første feilen. En profil kan trekke inn en annen konfigurasjonsfil, og de relative navnene i den inkluderte filen løses mot samme prosesskatalog, ikke mot katalogen til filen som inkluderte dem. Loggbaner, autentiseringsfiler og hjelpeskript følger samme regel.

Tjenesten starter et annet sted

Et interaktivt skall i profilkatalogen beviser ingenting om en pakket unit. Håndterere setter sin egen arbeidskatalog, og et innpakningsskript kan endre den igjen før binæren kjører. Unit-en som feiler, er den eneste oppstarten det er verdt å resonnere om.

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

Den andre kommandoen viser katalogen den levende prosessen faktisk holder, og det er mer pålitelig enn unit-filen når en innpakning er involvert. Hvis de to er uenige, er innpakningen svaret ditt, og unit-filen er et villspor.

Etter oppslaget: tillatelser, chroot og sandkasse

En riktig basiskatalog kan fortsatt gi samme melding, fordi oppslag og tilgang er separate trinn. Prosessen trenger kjøretillatelse på hver overordnet katalog og lesetillatelse på filen, og en tjeneste-unit som skjuler en del av filsystemet, endrer hva prosessen i det hele tatt kan se.

Tre vanlige varianter gir samme feil. Filen er bare lesbar for root, mens tjenesten gir slipp på privilegier før den åpner den. Unit-en setter et beskyttende filsystemsyn som ikke omfatter profilkatalogen. Daemonen kjører med chroot, så banen som finnes på verten, finnes ikke inne i det synet.

Diagnostiser med filens eierskap og prosessens identitet, ikke ved å lempe på tillatelsene. Å gjøre en privat nøkkel lesbar for alle for å dempe denne feilen, bytter en høylytt feil mot en stille, og nøkkelen er nettopp den delen av katalogen du minst vil eksponere.

Bevis rettelsen med din egen oppstart

Start den ekte unit-en på nytt fra en katalog uten forbindelse til profilen og følg den samme oppstartslinjen. Bekreft deretter at prosessen holder den tiltenkte katalogen mens den kjører, og at sertifikatet den lastet, er det du forventer.

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

Når innlasting av baner lykkes, er autentisering og ruting fortsatt separate trinn med sine egne feil, og en tilkobling som kommer opp men ikke slipper trafikk gjennom, er en annen undersøkelse. Rettelsen her gjelder bare hvilken katalog filene kom fra, og den bør være synlig i kallet i stedet for å huskes av den som sist kjørte det for hånd.

Hvis profilen rulles ut av en konfigurasjonshåndterer, legg basiskatalogen eller de absolutte filnavnene der også. En manuell rettelse på én vert er versjonen av dette problemet som kommer tilbake etter neste gjenoppbygging.

Relaterte artikler