Tegnap a tunel működött, ma reggel pedig a unit halott, a naplóban Failed at step EXEC spawning /usr/local/bin/vpnclient áll. A hitelesítő adatok, az útvonalak és a fiók soha nem kerülnek bele ebbe a mondatba. A systemd az ExecStartot egy útvonallá oldotta fel, megkérte a kernelt, hogy hajtsa végre, a kernel pedig elutasította, többnyire azért, mert azon az útvonalon semmi nem létezik, vagy a fájl nem futtatható. Kezelje a hibát fájl- és argv-problémaként, amíg az elemzett parancs az ellenkezőjét nem bizonyítja.

Miért hasal el az EXEC, mielőtt a hitelesítés elkezdődne

A systemd nem shellen keresztül futtatja az ExecStartot. Forkol, argumentumvektort épít a sorból, és meghívja az execve-t az első elemre. Ha ez a hívás meghiúsul, a szolgáltatás soha nem éri el a VPN-kliens saját kódját, így sem a profil szerkesztése, sem a hitelesítő adatok ellenőrzése nem segít.

Az állapotkód választja el ezt a családot a szokásos összeomlásoktól. Az a unit, amely status=203/EXEC-kel lép ki, soha nem indított folyamatot; az a unit, amely elindul, majd status=1 -gyel lép ki, talán a hitelesítésnél, a DNS-nél vagy az útválasztásnál hasalt el. A kódot a kliens naplója előtt olvassa el, mert az első esetben a kliens naplója üres lesz.

A naplóban szereplő útvonal az, amelyet a systemd használt, nem feltétlenül az, amelyet Ön szerkesztett. A drop-in fájlok és a generátor kimenete felülírhatja a szállító fájlját, a régi daemon-reload pedig a régi sort hagyja a memóriában. Ezért az első diagnózis az, hogy megkérdezzük a systemd-t, mit tekint parancsnak, ahelyett hogy megnyitnánk a fájlt, amelyet módosítottunk.

Három hely, ahol a bináris útvonala le van írva

A disztribúciós csomagból, szállítói szkriptből és kiadási tarballból telepített VPN-kliens három különböző előtagba kerülhet. A unit, a jogosultsági szabály és a telepítő egy-egy ilyen előtagot rögzített, és a hiba akkor jelenik meg, amikor a háromból kettő nem egyezik.

RecordCommon valueHow to read it
Unit or drop-in/usr/local/bin/vpnclientsystemctl cat vpnclient.service
Installed binary/usr/bin/vpnclientcommand -v vpnclient, then ls -l the result
Sudoers grant/opt/vpnclient/bin/vpnclientsudo grep -r vpnclient /etc/sudoers.d/

Egy konkrét eltérés így néz ki: a szállítói szkript a /usr/local/bin könyvtárba telepít, a tarballt a /opt alatt bontották ki, a unit pedig még mindig a korábbi csomag régi /usr/bin útvonalát nevezi meg. Ezek közül a fájlok közül csak egy létezik, és ritkán éppen az, amelyik az ExecStartban szerepel.

Döntse el, melyik útvonal a kanonikus, mielőtt bármelyik fájlt módosítaná. Ha a bináris a disztribúciós csomagé, a csomag útvonala a kanonikus, és a unitnak azt kell követnie. Ha a szállítói szkripté, ugyanez a szabály érvényes a szállító előtagjára. A bináris előtagok közötti másolása két példányt hoz létre, amelyek a következő frissítéskor eltávolodnak.

Amikor az idézőjelbe tett parancs fájlnévvé válik

Egy második hiba mód a napló ugyanazon sora mögött rejtőzik. Valaki ezt írja a unitba, és azt várja, hogy a kliens a rendszerindítás alatt csatlakozik:

ExecStart=/usr/bin/"vpnclient connect office"

A systemd szavakra bontja az értéket, így az első szó /usr/bin/vpnclient connect office lesz, miközben az idézőjelek csoportosítási szintaxisként eltűnnek. Ezután a kernel olyan fájlt keres, amelynek nevében szóközök vannak, és ilyen nem létezik. A hiba pontosan ugyanaz, mint egy hiányzó bináris esetében, pedig a bináris telepítve van.

A támogatott forma egy valódi futtatható fájl, amelyet külön argumentumok követnek, például ExecStart=/usr/bin/vpnclient connect office. Ha a munkafolyamatnak valóban csővezetékre vagy láncra van szüksége, tegye azt egy szkriptbe, és hívja meg a szkriptet, mert az ExecStartnak nincs &&, nincsenek csövek és nincs glob-kiterjesztés.

A unitot javítsa, ne a fájlrendszert

A csábító javítás egy szimbolikus hivatkozás a várt útvonalról a valódi binárisra. Addig működik, amíg a csomag frissül, és a hivatkozás egy eltávolított fájlra mutat, vagy amíg egy SELinux-címke már nem illeszkedik a célhoz. Inkább drop-in segítségével szerkessze a unitot, hogy a szállító fájlja érintetlen maradjon, és a frissítések kiszámíthatók legyenek.

A jogosultsági szabálynak ugyanahhoz az útvonalhoz és ugyanazokhoz az alparancsokhoz kell illeszkednie. A /usr/local/bin/vpnclient útvonalhoz tartozó sudoers-bejegyzés nem jogosítja a /usr/bin/vpnclient útvonalat, az pedig, amely minden argumentumot engedélyez, bármely helyi folyamatnak lehetővé teszi a tunel újrakonfigurálását vagy leállítását. Adja meg a két igét, amelyre a unitnak szüksége van, és tartsa a bontást azon kívül, ha a szolgáltatás leállítása már bezárja az interfészt.

Itt kifizetődik az összehasonlítás: a unitnak, a csomagadatbázisnak és a sudoersnek ugyanazt az egy útvonalat kellene megneveznie. Amikor így tesznek, az EXEC-hiba újraindítás nélkül és a bináris harmadik helyen lévő másolata nélkül eltűnik.

Bizonyítsa az elemzett parancsot újraindítás előtt

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-pager

systemctl show a döntő kimenet, mert azt az argv-t írja ki, amelyet a systemd valóban elemzett, beleértve bármely drop-int. A systemd-analyze verify még az újraindítás előtt elkapja a hiányzó vagy nem futtatható útvonalat, az újraindítás utáni status parancs pedig megmondja, létezik-e most a folyamat.

Ha a unit elindul, majd elhasal, elhagyta az EXEC családot, és a kliens saját hibakezelésébe lépett. A naplóban a kliens üzenetét keresse, ne egy újabb execve-hibát. Tartsa a unit diffjét és a sudoers diffjét együtt a változásrekordban, hogy a következő frissítés ne vezesse vissza csendben a megosztott útvonalat.

Kapcsolódó cikkek