Vakar tunelis veikė, o šį rytą unit miręs, žurnale yra Failed at step EXEC spawning /usr/local/bin/vpnclient. Kredencialai, maršrutai ir paskyra niekada nepatenka į tą sakinį. systemd išsprendė ExecStart į kelią, paprašė branduolio jį įvykdyti, o branduolys atsisakė, dažniausiai todėl, kad tame kelyje nieko nėra arba failas nevykdomas. Traktuokite gedimą kaip failo ir argv problemą, kol išanalizuota komanda neįrodys priešingai.

Kodėl EXEC nepavyksta dar neprasidėjus autentifikacijai

systemd nevykdo ExecStart per apvalkalą. Jis padaro fork, iš eilutės sukuria argumentų vektorių ir iškviečia execve pirmajam elementui. Jei tas iškvietimas nepavyksta, paslauga niekada nepasiekia paties VPN kliento kodo, todėl profilio redagavimas ar kredencialų tikrinimas nepadės.

Būsenos kodas atskiria šią šeimą nuo įprastų strigimų. Unit, kuris baigiasi su status=203/EXEC, niekada nepaleido proceso; unit, kuris paleidžiamas ir tada baigiasi su status=1 galėjo nepavykti autentifikacijoje, DNS ar maršrutizavime. Skaitykite kodą prieš kliento žurnalą, nes pirmuoju atveju kliento žurnalas bus tuščias.

Kelias žurnale yra tas, kurį naudojo systemd, o ne būtinai tas, kurį redagavote. Drop-in failai ir generatoriaus išvestis gali pakeisti tiekėjo failą, o pasenęs daemon-reload palieka seną eilutę atmintyje. Todėl pirmoji diagnostika yra paklausti systemd, ką jis laiko komanda, o ne atidaryti failą, kurį prisimenate keitę.

Trys vietos, kur užrašytas binarinio failo kelias

VPN klientas, įdiegtas iš platinimo paketo, tiekėjo scenarijaus ir leidimo tarball, gali atsidurti trijuose skirtinguose priešdeliuose. Unit, privilegijų taisyklė ir diegėjas užrašė po vieną iš tų priešdelių, o gedimas pasirodo, kai du iš trijų nesutampa.

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/

Konkretus neatitikimas atrodo taip: tiekėjo scenarijus įdiegia į /usr/local/bin, tarball išskleistas po /opt, o unit vis dar nurodo seną /usr/bin kelią iš ankstesnio paketo. Egzistuoja tik vienas iš tų failų, ir retai tai yra failas, esantis ExecStart.

Prieš keisdami bet kurį failą nuspręskite, kuris kelias yra kanoninis. Jei binarinį failą valdo platinimo paketas, kanoninis yra paketo kelias, ir unit turi juo sekti. Jei jį valdo tiekėjo scenarijus, ta pati taisyklė galioja tiekėjo priešdeliui. Binarinio failo kopijavimas tarp priešdelių sukuria dvi kopijas, kurios kito atnaujinimo metu išsiskirs.

Kai komanda kabutėse tampa failo vardu

Antrasis gedimo būdas slepiasi už tos pačios žurnalo eilutės. Kažkas įrašo tai į unit ir tikisi, kad klientas prisijungs įkrovimo metu:

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

systemd suskaido reikšmę į žodžius, todėl pirmasis žodis tampa /usr/bin/vpnclient connect office, o kabutės pašalinamos kaip grupavimo sintaksė. Tada branduolys ieško failo, kurio pavadinime yra tarpų, o tokio nėra. Klaida tokia pati kaip trūkstamo binarinio failo, nors failas įdiegtas.

Palaikoma forma yra tikras vykdomasis failas, po kurio eina atskiri argumentai, pavyzdžiui ExecStart=/usr/bin/vpnclient connect office. Jei darbo eigai tikrai reikia vamzdyno ar grandinės, įdėkite ją į scenarijų ir iškvieskite scenarijų, nes ExecStart neturi &&, neturi vamzdžių ir neturi glob išplėtimo.

Taisykite unit, o ne failų sistemą

Viliojantis taisymas yra simbolinė nuoroda iš laukiamo kelio į tikrą binarinį failą. Ji veikia tol, kol paketas atnaujinamas ir nuoroda nukreipia į pašalintą failą, arba kol SELinux žymė nebeatitinka tikslo. Verčiau redaguokite unit per drop-in, kad tiekėjo failas liktų nepaliestas, o atnaujinimai išliktų nuspėjami.

Privilegijų taisyklė turi atitikti tą patį kelią ir tas pačias subkomandas. sudoers įrašas /usr/local/bin/vpnclient neįgalina /usr/bin/vpnclient, o įrašas, leidžiantis bet kurį argumentą, leidžia bet kuriam vietiniam procesui perkonfigūruoti ar sustabdyti tunelį. Suteikite du veiksmažodžius, kurių reikia unit, ir laikykite išardymą už jo ribų, jei paslaugos sustabdymas jau uždaro sąsają.

Štai kur palyginimas atsiperka: unit, paketų duomenų bazė ir sudoers turėtų nurodyti vieną kelią. Kai taip yra, EXEC klaida išnyksta be perkrovimo ir be binarinio failo kopijos trečioje vietoje.

Įrodykite išanalizuotą komandą prieš perkrovimą

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 yra lemiama išvestis, nes ji išspausdina argv, kurį systemd tikrai išanalizavo, įskaitant bet kurį drop-in. systemd-analyze verify pagauna trūkstamą ar nevykdomą kelią prieš perkraudami, o būsenos komanda po perkrovimo pasako, ar procesas dabar egzistuoja.

Jei unit paleidžiamas ir tada nepavyksta, palikote EXEC šeimą ir patekote į paties kliento klaidų apdorojimą. Žurnale ieškokite kliento pranešimo, o ne dar vieno execve nepavykimo. Laikykite unit diff ir sudoers diff kartu pakeitimų įraše, kad kitas atnaujinimas tyliai negrąžintų suskaidyto kelio.

Susiję straipsniai