Услугата стартува, го чита профилот без поплаки и потоа умира на ред што изгледа неповрзан: не може да ја отвори 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

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

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

Поврзани статии