Juče je tunel radio, a jutros je unit mrtav s Failed at step EXEC spawning /usr/local/bin/vpnclient u dnevniku. Akreditivi, rute i račun nikada ne ulaze u tu rečenicu. systemd je razriješio ExecStart u putanju, zamolio kernel da je izvrši, a kernel je odbio — najčešće zato što na toj putanji ništa ne postoji ili datoteka nije izvršna. Tretirajte kvar kao problem datoteke i argv-a dok analizirana naredba ne dokaže suprotno.

Zašto EXEC pada prije nego što počne autentifikacija

systemd ne pokreće ExecStart kroz shell. On pravi fork, gradi vektor argumenata iz reda i poziva execve na prvom elementu. Ako taj poziv ne uspije, servis nikada ne stiže do vlastitog koda VPN klijenta, pa nikakvo uređivanje profila ni provjera akreditiva ne može pomoći.

Statusni kôd odvaja ovu porodicu od običnih padova. Unit koji izađe sa status=203/EXEC nikada nije pokrenuo proces; unit koji se pokrene i zatim izađe sa status=1 možda je pao na autentifikaciji, DNS-u ili rutiranju. Pročitajte kôd prije klijentskog dnevnika, jer će u prvom slučaju klijentski dnevnik biti prazan.

Putanja u dnevniku je ona koju je systemd koristio, a ne nužno ona koju ste uredili. Drop-in datoteke i izlaz generatora mogu nadjačati datoteku dobavljača, a zastario daemon-reload ostavlja stari red u memoriji. Zato je prva dijagnostika pitati systemd šta on misli da je naredba, umjesto otvaranja datoteke za koju se sjećate da ste je mijenjali.

Tri mjesta na kojima je zapisana putanja do binarne datoteke

VPN klijent instaliran iz paketa distribucije, skripte dobavljača i tarball-a izdanja može završiti u tri različita prefiksa. Unit, pravilo privilegija i instalater svaki su zabilježili jedan od tih prefiksa, a kvar se pojavljuje kada se dva od tri ne slažu.

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/

Konkretno neslaganje izgleda ovako: skripta dobavljača instalira u /usr/local/bin, tarball je raspakovan pod /opt, a unit još navodi staru putanju /usr/bin iz prethodnog paketa. Samo jedna od tih datoteka postoji, i rijetko je to ona u ExecStart-u.

Odlučite koja je putanja kanonska prije nego što promijenite bilo koju datoteku. Ako paket distribucije posjeduje binarnu datoteku, putanja paketa je kanonska i unit je treba slijediti. Ako je posjeduje skripta dobavljača, isto pravilo vrijedi za prefiks dobavljača. Kopiranje binarne datoteke između prefiksa stvara dvije kopije koje se razilaze pri sljedećem ažuriranju.

Kada citirana naredba postane naziv datoteke

Drugi način kvara skriva se iza istog reda u dnevniku. Neko ovo upiše u unit i očekuje da se klijent poveže tokom podizanja sistema:

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

systemd dijeli vrijednost na riječi, pa prva riječ postaje /usr/bin/vpnclient connect office, a navodnici se uklanjaju kao sintaksa za grupisanje. Zatim kernel traži datoteku čiji naziv sadrži razmake, a takva ne postoji. Greška je identična onoj kod nedostajuće binarne datoteke, iako je datoteka instalirana.

Podržani oblik je stvarna izvršna datoteka praćena odvojenim argumentima, na primjer ExecStart=/usr/bin/vpnclient connect office. Ako radni tok zaista traži pipeline ili lanac, stavite ga u skriptu i pozovite skriptu, jer ExecStart nema &&, nema pipe-ova i nema glob proširenja.

Popravite unit, ne datotečni sistem

Primamljiv popravak je simbolički link od očekivane putanje do stvarne binarne datoteke. On radi dok se paket ne ažurira i link ne pokaže na uklonjenu datoteku, ili dok se SELinux oznaka više ne bude slagala s ciljem. Radije uredite unit kroz drop-in, tako da datoteka dobavljača ostane netaknuta i ažuriranja ostanu predvidiva.

Pravilo privilegija mora odgovarati istoj putanji i istim podnaredbama. Sudoers unos za /usr/local/bin/vpnclient ne ovlašćuje /usr/bin/vpnclient, a unos koji dozvoljava svaki argument omogućava bilo kojem lokalnom procesu da prekonfiguriše ili zaustavi tunel. Dajte dva glagola koja unit traži i držite teardown izvan njega ako zaustavljanje servisa već zatvara interfejs.

Tu se poređenje isplati: unit, baza paketa i sudoers treba da navedu jednu putanju. Kada to urade, EXEC greška nestaje bez restarta i bez kopije binarne datoteke na trećem mjestu.

Dokažite analiziranu naredbu prije restarta

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 je odlučujući izlaz jer ispisuje argv koji je systemd zaista analizirao, uključujući svaki drop-in. systemd-analyze verify hvata nedostajuću ili neizvršnu putanju prije nego što restartujete, a status naredba nakon restarta kaže da li proces sada postoji.

Ako se unit pokrene i zatim padne, napustili ste EXEC porodicu i ušli u klijentovo vlastito rukovanje greškama. Provjerite dnevnik za klijentovu poruku, a ne za još jedan execve neuspjeh. Držite diff unit-a i diff sudoers-a zajedno u zapisu o promjeni, da sljedeće ažuriranje tiho ne vrati razdvojenu putanju.

Povezani članci