VPN услуга пада на EXEC: упоредите unit, бинарну датотеку и sudoers
Пад на кораку EXEC значи да systemd није могао да покрене бинарну датотеку. Упоредите путању у unit-у, инсталирану путању и дозволу у sudoers пре него што било шта измените.
Јуче је тунел радио, а јутрос је unit мртав са Failed at step EXEC spawning /usr/local/bin/vpnclient у журналу. Акредитиви, руте и налог никада не улазе у ту реченицу. systemd је разрешио ExecStart у путању, замолио кернел да је изврши, а кернел је одбио, најчешће зато што на тој путањи ништа не постоји или датотека није извршна. Третирајте квар као проблем датотеке и argv док анализирана команда не докаже супротно.
Зашто EXEC пада пре него што почне аутентикација
systemd не покреће ExecStart кроз шкољку. Он прави fork, гради вектор аргумената из линије и позива execve на први елемент. Ако тај позив не успе, услуга никада не стиже до сопственог кода VPN клијента, па никакво уређивање профила ни провера акредитива не може да помогне.
Статусни код одваја ову породицу од обичних падова. Unit који изађе са status=203/EXEC никада није покренуо процес; unit који се покрене и затим изађе са status=1 можда је пао на аутентикацији, DNS-у или рутирању. Прочитајте код пре дневника клијента, јер ће у првом случају дневник клијента бити празан.
Путања у журналу је она коју је користио systemd, а не нужно она коју сте изменили. Drop-in датотеке и излаз генератора могу да надјачају датотеку добављача, а застарео daemon-reload оставља стари ред у меморији. Зато је прва дијагностика да питате systemd шта он сматра командом, уместо да отворите датотеку за коју се сећате да сте је мењали.
Три места на којима је записана путања до бинарне датотеке
VPN клијент инсталиран из пакета дистрибуције, скрипте добављача и tarball-а издања може да заврши у три различита префикса. Unit, правило привилегија и инсталатер су сваки забележили један од тих префикса, а квар се појављује када се два од три не слажу.
| Record | Common value | How to read it |
|---|---|---|
| Unit or drop-in | /usr/local/bin/vpnclient | systemctl cat vpnclient.service |
| Installed binary | /usr/bin/vpnclient | command -v vpnclient, then ls -l the result |
| Sudoers grant | /opt/vpnclient/bin/vpnclient | sudo grep -r vpnclient /etc/sudoers.d/ |
Конкретно неслагање изгледа овако: скрипта добављача инсталира у /usr/local/bin, tarball је распакован под /opt, а unit још наводи стару путању /usr/bin из претходног пакета. Само једна од тих датотека постоји, и ретко је то она у ExecStart-у.
Одлучите која је путања канонска пре него што промените било коју датотеку. Ако бинарна датотека припада пакету дистрибуције, канонска је путања пакета и unit треба да је прати. Ако припада скрипти добављача, исто правило важи за префикс добављача. Копирање бинарне датотеке између префикса ствара две копије које се разилазе при следећем ажурирању.
Када команда под наводницима постане назив датотеке
Други режим квара крије се иза истог реда у журналу. Неко ово упише у unit и очекује да се клијент повеже током подизања:
ExecStart=/usr/bin/"vpnclient connect office"systemd дели вредност на речи, па прва реч постаје /usr/bin/vpnclient connect office, а наводници се уклањају као синтакса за груписање. Затим кернел тражи датотеку чији назив садржи размаке, а таква не постоји. Грешка је иста као код датотеке која недостаје, иако је датотека инсталирана.
Подржани облик је стварна извршна датотека за којом следе одвојени аргументи, на пример ExecStart=/usr/bin/vpnclient connect office. Ако радни ток заиста захтева цевовод или ланац, ставите га у скрипту и позовите скрипту, јер ExecStart нема &&, нема цевоводе и нема glob проширење.
Поправите unit, а не датотечни систем
Примамљива поправка је симболичка веза од очекиване путање до стварне бинарне датотеке. Она ради док се пакет не ажурира и веза не покаже на уклоњену датотеку, или док SELinux ознака не престане да се поклапа са циљем. Радије уредите unit кроз drop-in, тако да датотека добављача остане нетакнута и ажурирања остану предвидива.
Правило привилегија мора да одговара истој путањи и истим подкомандама. Унос у sudoers за /usr/local/bin/vpnclient не овлашћује /usr/bin/vpnclient, а унос који дозвољава сваки аргумент омогућава било ком локалном процесу да преконфигурише или заустави тунел. Дајте два глагола која су unit-у потребна и држите растављање изван њега ако заустављање услуге већ затвара интерфејс.
Ту се поређење исплати: unit, база пакета и sudoers треба да наведу једну путању. Када то ураде, EXEC грешка нестаје без рестарта и без копије бинарне датотеке на трећем месту.
Докажите анализирану команду пре рестарта
sudo systemctl daemon-reload
sudo systemctl cat vpnclient.service
systemctl show -p ExecStart vpnclient.service
systemd-analyze verify /etc/systemd/system/vpnclient.service
sudo systemctl restart vpnclient.service
systemctl status vpnclient.service --no-pagersystemctl show је одлучујући излаз јер исписује argv који је systemd заиста анализирао, укључујући сваки drop-in. systemd-analyze verify хвата путању која недостаје или није извршна пре него што рестартујете, а статусна команда после рестарта каже да ли процес сада постоји.
Ако се unit покрене и затим падне, напустили сте EXEC породицу и ушли у сопствену обраду грешака клијента. У журналу потражите поруку клијента, а не још један execve неуспех. Држите diff unit-а и diff sudoers-а заједно у запису о промени, да следеће ажурирање тихо не врати раздвојену путању.