Služba se spustí, přečte profil bez stížnosti a pak spadne na řádku, která vypadá nesouvisejícím: nemůže otevřít ca.crt. Na certifikátu se nic nezměnilo a cesta k profilu v unit souboru je absolutní. Právě ta kombinace je vodítko. Cesta, kterou jste předali, určuje jeden soubor, a jména uvnitř tohoto souboru se řeší úplně jinde, takže spuštění, které vypadá plně kvalifikovaně, může stále číst své klíče z adresáře, který nikdo nezamýšlel.

Selhání má málo příčin a vyplatí se je oddělit popořadě: základní adresář, který proces skutečně měl, kontext spuštění služby a oprávnění či sandbox kolem souboru, jakmile je cesta správná. Každá zanechává jinou stopu — v unit souboru, v procesu a na souborovém systému.

Cesta k profilu není základní adresář

Představte si proces, který startuje v /tmp a dostane /etc/vpn/prod/tenant-a.ovpn. Uvnitř tohoto profilu řádek ca ca.crt označuje relativní cestu. Nic v argumentu, který profil lokalizoval, toto jméno nepřepisuje, takže proces hledá /tmp/ca.crt a hlásí chybějící soubor.

Matek je pořadí chyb. OpenVPN nejprve parsuje konfiguraci a otevírá odkazované soubory, jak k nim dochází, takže překlep v profilu se ohlásí dřív, než se dotkne jakýkoli klíč, zatímco chybějící certifikát se objeví až když parsování dojde tak daleko. Profil, který se načte, je tedy důkaz, že syntaxe je v pořádku, ne že soubory, které pojmenovává, byly nalezeny.

Co manuál odděluje: --config a --cd

Manuál OpenVPN 2.6 popisuje dvě odlišné volby. Jedna načítá konfigurační soubor. Druhá mění adresář procesu předtím, než se přečte konfigurace, klíč, skript a další soubory, a vyžaduje absolutní adresář bez odkazu na aktuální.

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

Toto volání je tvar, ne pokyn spustit cizí profil. Co vám dává, je determinismus: základ pro každé relativní jméno v řetězci je uveden v příkazu místo toho, aby se dědil z nějakého shellu nebo správce, který proces spustil. Alternativa je stejně platná a pro službu často lepší: nechte pracovní adresář být a každý odkazovaný soubor udělejte uvnitř profilu absolutním.

Ať už zvolíte cokoli, projděte celý řetězec, ne první selhání. Profil může přitáhnout jiný konfigurační soubor a relativní jména vloženého souboru se řeší proti stejnému adresáři procesu, ne proti adresáři souboru, který je vložil. Cesty k logům, autentizační soubory a pomocné skripty se řídí stejným pravidlem.

Služba startuje někde jinde

Interaktivní shell v adresáři profilu nic nedokazuje o zabaleném unit souboru. Správci nastavují vlastní pracovní adresář a obalový skript ho může před spuštěním binárky změnit znovu. Unit, který selhává, je jediné spuštění, o kterém má smysl uvažovat.

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

Druhý příkaz ukazuje adresář, který živý proces skutečně drží, což je spolehlivější než unit soubor, když je ve hře obal. Pokud se oba neshodují, odpovědí je obal a unit je falešná stopa.

Po hledání: oprávnění, chroot a sandbox

Správný základní adresář může přesto vydat stejnou zprávu, protože řešení a přístup jsou samostatné kroky. Proces potřebuje právo spuštění na každém nadřazeném adresáři a právo čtení souboru, a unit služby, který skrývá část souborového systému, mění, co proces vůbec může vidět.

Tři běžné varianty dávají totožnou chybu. Soubor je čitelný jen pro root, zatímco služba se před jeho otevřením vzdá privilegií. Unit nastavuje ochranný pohled na souborový systém, který adresář profilu nezahrnuje. Démon běží s chrootem, takže cesta, která existuje na hostiteli, v tomto pohledu neexistuje.

Diagnostikujte podle vlastnictví souboru a identity procesu, ne povolováním oprávnění. Udělat soukromý klíč čitelným pro všechny, aby tato chyba ztichla, vyměňuje hlasité selhání za tiché, a klíč je právě ta část adresáře, kterou chcete ukázat nejméně.

Dokažte opravu vlastním spuštěním

Restartujte skutečný unit z adresáře nesouvisejícího s profilem a sledujte stejný řádek při startu. Pak potvrďte, že proces za běhu drží zamýšlený adresář a že certifikát, který načetl, je ten, který očekáváte.

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

Když načtení cest uspěje, autentizace a směrování jsou stále oddělené fáze s vlastními selháními a spojení, které se naváže, ale nepropustí provoz, je jiné vyšetřování. Oprava zde se týká jen toho, ze kterého adresáře soubory přišly, a měla by být vidět ve volání, ne si ji pamatovat podle toho, kdo ji naposledy spustil ručně.

Pokud je profil nasazován správcem konfigurace, dejte tam i základní adresář nebo absolutní jména souborů. Ruční oprava na jednom hostiteli je verze tohoto problému, která se vrací po příštím rebuildu.

Související články