Сервис се покрене, прочита профил без примедби и затим падне на линији која изгледа неповезано: не може да отвори ca.crt. Ништа на сертификату се није променило, а путања профила у unit датотеци је апсолутна. Управо та комбинација је знак. Путања коју сте дали лоцира једну датотеку, а имена унутар те датотеке решавају се сасвим другде, па покретање које изгледа потпуно квалификовано ипак може да чита своје кључеве из директоријума који нико није предвидео.

Неуспех има мало узрока и вреди их раздвојити по реду: основни директоријум који је процес заиста имао, контекст покретања сервиса и дозволе или sandbox око датотеке када је путања већ тачна. Сваки оставља другачији траг — у unit датотеци, у процесу и на фајл систему.

Путања профила није основни директоријум

Замислите процес који почиње у /tmp и добија /etc/vpn/prod/tenant-a.ovpn. Унутар тог профила линија ca ca.crt наводи релативну путању. Ништа у аргументу који је лоцирао профил не преписује то име, па процес тражи /tmp/ca.crt и пријављује датотеку која недостаје.

Збуњује редослед грешака. OpenVPN прво парсира конфигурацију и отвара наведене датотеке како до њих долази, па се грешка у куцању у профилу пријављује пре него што се дотакне било који кључ, док се сертификат који недостаје појављује тек када парсирање догура дотле. Зато је профил који се учита доказ да је синтакса исправна, а не да су датотеке које наводи пронађене.

Шта приручник раздваја: --config и --cd

Приручник за OpenVPN 2.6 описује две различите опције. Једна учитава конфигурациону датотеку. Друга мења директоријум процеса пре него што се прочитају конфигурација, кључ, скрипта и остале датотеке, и захтева апсолутни директоријум без икаквог осврта на текући.

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

Тај позив је облик, а не упутство да покренете туђи профил. Оно што даје јесте детерминизам: основа за свако релативно име у ланцу наведена је у команди уместо да се наслеђује из било које шкољке или менаџера који је покренуо процес. Алтернатива је једнако ваљана и за сервис често боља: оставите радни директоријум на миру и учините сваку наведену датотеку апсолутном унутар профила.

Шта год да изаберете, прегледајте цео ланац, а не први неуспех. Профил може да увуче другу конфигурациону датотеку, а релативна имена укључене датотеке решавају се према истом директоријуму процеса, не према директоријуму датотеке која их је укључила. Путање дневника, датотеке аутентикације и помоћне скрипте следе исто правило.

Сервис почиње негде другде

Интерактивна шкољка у директоријуму профила не доказује ништа о спакованом unit-у. Менаџери постављају сопствени радни директоријум, а омотачна скрипта га може поново променити пре него што се бинарни фајл покрене. Unit који пада једино је покретање о коме вреди размишљати.

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

Друга команда показује директоријум који живи процес заиста држи, и то је поузданије од unit датотеке када је укључен омотач. Ако се њих двоје не слажу, омотач је ваш одговор, а unit је лажни траг.

После тражења: дозволе, chroot и sandbox

Исправан основни директоријум ипак може дати исту поруку, јер су решавање и приступ одвојени кораци. Процесу треба дозвола за извршавање на сваком родитељском директоријуму и дозвола за читање датотеке, а unit сервиса који скрива део фајл система мења шта процес уопште може да види.

Три уобичајене варијанте дају идентичну грешку. Датотека је читљива само за root, док сервис одустаје од привилегија пре него што је отвори. Unit поставља заштитни поглед на фајл систем који не укључује директоријум профила. Демон ради са chroot-ом, па путања која постоји на хосту не постоји унутар тог погледа.

Дијагностикујте по власништву датотеке и идентитету процеса, а не попуштањем дозвола. Учинити приватни кључ читљивим свима да бисте утишали ову грешку замењује гласан неуспех тихим, а кључ је управо део директоријума који најмање желите да изложите.

Докажите исправку сопственим покретањем

Поново покрените прави unit из директоријума неповезаног са профилом и посматрајте исту линију покретања. Затим потврдите да процес током рада држи предвиђени директоријум и да је учитани сертификат онај који очекујете.

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

Када учитавање путања успе, аутентикација и рутирање су и даље одвојене фазе са сопственим неуспесима, а веза која се подигне али не пропушта саобраћај је друго истраживање. Исправка овде тиче се само тога из ког директоријума су датотеке дошле, и требало би да буде видљива у позиву, уместо да је памти онај који ју је последњи покренуо ручно.

Ако профил распоређује менаџер конфигурације, ставите тамо и основни директоријум или апсолутна имена датотека. Ручна исправка на једном хосту верзија је овог проблема која се враћа после следеће поновне изградње.

Повезани чланци