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 заедно во записот за промена, за да не ја врати следното надградување тивко разделената патека.