OpenVPN hittar inte ca.crt trots att profilen laddas
Profilens sökväg är inte basen för filerna i den. Se varför en absolut --config ändå misslyckas på ca.crt och hur starten avgör svaret.
Tjänsten startar, läser profilen utan klagomål och dör sedan på en rad som verkar ointressant: den kan inte öppna ca.crt. Ingenting i certifikatet har ändrats, och profilsökvägen i unit-filen är absolut. Just den kombinationen är ledtråden. Sökvägen du angav pekar ut en fil, och namnen inuti den filen löses helt någon annanstans, så en start som ser fullständigt kvalificerad ut kan fortfarande läsa sina nycklar från en katalog som ingen avsåg.
Felet har få orsaker, och de är värda att skilja åt i ordning: baskatalogen som processen faktiskt hade, tjänstens startkontext och behörigheterna eller sandlådan runt filen när sökvägen väl är rätt. Var och en lämnar ett olikt spår — i unit-filen, i processen och på filsystemet.
Profilsökvägen är inte en baskatalog
Föreställ dig en process som startar i /tmp och får /etc/vpn/prod/tenant-a.ovpn. Inuti den profilen namnger raden ca ca.crt en relativ sökväg. Ingenting i argumentet som hittade profilen skriver om det namnet, så processen letar efter /tmp/ca.crt och rapporterar en saknad fil.
Det förvirrande är ordningen på felen. OpenVPN tolkar konfigurationen först och öppnar refererade filer när det når dem, så ett skrivfel i profilen rapporteras innan någon nyckel rörs, medan ett saknat certifikat dyker upp först när tolkningen kommer dit. En profil som laddas är därför bevis på att syntaxen är riktig, inte på att filerna den namnger hittades.
Vad handboken skiljer på: --config och --cd
Handboken för OpenVPN 2.6 beskriver två olika alternativ. Det ena laddar en konfigurationsfil. Det andra byter processens katalog innan konfiguration, nyckel, skript och andra filer läses, och kräver en absolut katalog utan hänvisning till den nuvarande.
openvpn --cd /etc/vpn/prod --config tenant-a.ovpn
Det anropet är en form, inte en instruktion att starta någon annans profil. Det du får är determinism: basen för varje relativt namn i kedjan står i kommandot i stället för att ärvas från vilket skal eller vilken hanterare som helst som startade processen. Alternativet är lika giltigt och ofta bättre för en tjänst: låt arbetskatalogen vara och gör varje refererad fil absolut inne i profilen.
Vad du än väljer, granska hela kedjan och inte det första felet. En profil kan dra in en annan konfigurationsfil, och de relativa namnen i den inkluderade filen löses mot samma processkatalog, inte mot katalogen för filen som inkluderade dem. Loggsökvägar, autentiseringsfiler och hjälpskript följer samma regel.
Tjänsten startar någon annanstans
Ett interaktivt skal i profilkatalogen bevisar ingenting om en paketerad unit. Hanterare sätter sin egen arbetskatalog, och ett omslagsskript kan ändra den igen innan binären körs. Den unit som misslyckas är den enda start det är värt att resonera om.
systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd
Det andra kommandot visar katalogen som den levande processen faktiskt håller, och det är mer tillförlitligt än unit-filen när ett omslag är inblandat. Om de två inte stämmer överens är omslaget ditt svar och unit-filen ett villospår.
Efter sökningen: behörigheter, chroot och sandlåda
En korrekt baskatalog kan ändå ge samma meddelande, eftersom upplösning och åtkomst är separata steg. Processen behöver körbehörighet på varje överordnad katalog och läsbehörighet på filen, och en tjänsteunit som döljer en del av filsystemet ändrar vad processen överhuvudtaget kan se.
Tre vanliga varianter ger samma fel. Filen är bara läsbar för root medan tjänsten släpper privilegier innan den öppnar den. Unit-filen sätter en skyddande filsystemsvy som inte omfattar profilkatalogen. Daemonen kör med chroot, så sökvägen som finns på värden finns inte inne i den vyn.
Diagnostisera med filens ägarskap och processens identitet, inte genom att lätta på behörigheterna. Att göra en privat nyckel läsbar för alla för att tysta detta fel byter ett högljutt fel mot ett tyst, och nyckeln är just den del av katalogen du minst vill exponera.
Bevisa rättelsen med din egen start
Starta om den riktiga uniten från en katalog utan koppling till profilen och följ samma startrad. Bekräfta sedan att processen håller den avsedda katalogen medan den kör, och att certifikatet den laddade är det du förväntar dig.
systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager
När inläsningen av sökvägar lyckas är autentisering och routning fortfarande separata steg med egna fel, och en anslutning som kommer upp men inte släpper igenom trafik är en annan undersökning. Rättelsen här gäller bara vilken katalog filerna kom från, och den bör synas i anropet i stället för att kommas ihåg av den som senast körde det för hand.
Om profilen distribueras av en konfigurationshanterare, lägg baskatalogen eller de absoluta filnamnen där också. En manuell rättelse på en enda värd är versionen av detta problem som kommer tillbaka efter nästa ombyggnad.