OpenVPN не намира ca.crt, макар профилът да се зарежда
Пътят до профила не е базата за файловете в него. Вижте защо абсолютен --config пак се проваля на ca.crt и как стартирането решава отговора.
Услугата стартира, прочита профила без оплакване и след това умира на ред, който изглежда несвързан: не може да отвори ca.crt. Нищо в сертификата не се е променило, а пътят до профила в unit файла е абсолютен. Тази комбинация е издайството. Пътят, който сте подали, сочи един файл, а имената вътре в него се решават съвсем другаде, така че стартиране, което изглежда напълно квалифицирано, може да чете ключовете си от директория, която никой не е имал предвид.
Провалът има малко на брой причини и си струва да ги разделим по ред: базовата директория, която процесът действително е имал, контекстът на стартиране на услугата и разрешенията или пясъчника около файла, след като пътят е правилен. Всяка оставя различна следа — в 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 и пясъчник
Правилната базова директория може да даде същото съобщение, защото решаването и достъпът са отделни стъпки. Процесът се нуждае от право на изпълнение за всяка родителска директория и право на четене за файла, а 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
Когато зареждането на пътища успее, удостоверяването и маршрутизацията са все още отделни етапи със свои провали, а връзка, която се вдига, но не пропуска трафик, е друго разследване. Поправката тук е само за това от коя директория са дошли файловете и трябва да се вижда в извикването, вместо да се помни от този, който последно го е пускал на ръка.
Ако профилът се разгръща от мениджър за конфигурация, сложете базовата директория или абсолютните имена на файловете и там. Ръчна поправка на един хост е версията на този проблем, която се връща след следващото преизграждане.