ഇന്നലെ ടണൽ പ്രവർത്തിച്ചിരുന്നു, ഇന്ന് രാവിലെ unit മരിച്ചു, ജേണലിൽ Failed at step EXEC spawning /usr/local/bin/vpnclient ഉണ്ട്. ക്രെഡൻഷ്യലുകളും റൂട്ടുകളും അക്കൗണ്ടും ആ വാക്യത്തിൽ ഒരിക്കലും വരുന്നില്ല. systemd ExecStart-നെ ഒരു പാതയായി പരിഹരിച്ചു, അത് പ്രവർത്തിപ്പിക്കാൻ കേർണലിനോട് ആവശ്യപ്പെട്ടു, കേർണൽ നിരസിച്ചു, മിക്കവാറും ആ പാതയിൽ ഒന്നും ഇല്ലാത്തതിനാലോ ഫയൽ പ്രവർത്തിപ്പിക്കാനാകാത്തതിനാലോ ആണ്. പാഴ്സ് ചെയ്ത കമാൻഡ് വിപരീതം തെളിയിക്കുന്നതുവരെ ഈ തകരാറിനെ ഫയലിന്റെയും argv-യുടെയും പ്രശ്നമായി കാണുക.

ഓതന്റിക്കേഷൻ തുടങ്ങുന്നതിന് മുമ്പ് EXEC പരാജയപ്പെടുന്നത് എന്തുകൊണ്ട്

systemd ExecStart ഒരു ഷെൽ വഴി പ്രവർത്തിപ്പിക്കുന്നില്ല. അത് fork ചെയ്യുന്നു, വരിയിൽ നിന്ന് ആർഗ്യുമെന്റ് വെക്ടർ നിർമ്മിക്കുന്നു, ആദ്യ ഘടകത്തിൽ execve വിളിക്കുന്നു. ആ വിളി പരാജയപ്പെട്ടാൽ, സേവനം ഒരിക്കലും VPN ക്ലയന്റിന്റെ സ്വന്തം കോഡിൽ എത്തുന്നില്ല, അതിനാൽ പ്രൊഫൈൽ എഡിറ്റ് ചെയ്യുന്നതോ ക്രെഡൻഷ്യൽ പരിശോധിക്കുന്നതോ സഹായിക്കില്ല.

സ്റ്റാറ്റസ് കോഡ് ഈ കുടുംബത്തെ സാധാരണ ക്രാഷുകളിൽ നിന്ന് വേർതിരിക്കുന്നു. status=203/EXEC-യോടെ പുറത്തുപോകുന്ന unit ഒരിക്കലും പ്രോസസ്സ് തുടങ്ങിയിട്ടില്ല; തുടങ്ങി പിന്നീട് status=1 -നോടെ പുറത്തുപോകുന്ന unit ഓതന്റിക്കേഷനിലോ DNS-ലോ റൂട്ടിംഗിലോ പരാജയപ്പെട്ടിരിക്കാം. ക്ലയന്റ് ലോഗ് വായിക്കുന്നതിന് മുമ്പ് കോഡ് വായിക്കുക, കാരണം ആദ്യ സാഹചര്യത്തിൽ ക്ലയന്റ് ലോഗ് ശൂന്യമായിരിക്കും.

ജേണലിലെ പാത systemd ഉപയോഗിച്ചതാണ്, നിങ്ങൾ എഡിറ്റ് ചെയ്തത് ആയിരിക്കണമെന്നില്ല. Drop-in ഫയലുകളും ജനറേറ്ററിന്റെ ഔട്ട്പുട്ടും വെണ്ടറുടെ ഫയൽ അതിലംഘിക്കാം, പഴയ daemon-reload പഴയ വരി മെമ്മറിയിൽ വിടുന്നു. അതിനാൽ ആദ്യ ഡയഗ്നോസ്റ്റിക്സ്, നിങ്ങൾ മാറ്റിയതായി ഓർക്കുന്ന ഫയൽ തുറക്കുന്നതല്ല, systemd-നോട് കമാൻഡ് എന്താണെന്ന് കരുതുന്നു എന്ന് ചോദിക്കുന്നതാണ്.

ബൈനറിയുടെ പാത എഴുതപ്പെടുന്ന മൂന്ന് സ്ഥലങ്ങൾ

ഡിസ്ട്രിബ്യൂഷൻ പാക്കേജിൽ നിന്നും വെണ്ടർ സ്ക്രിപ്റ്റിൽ നിന്നും റിലീസ് tarball-ൽ നിന്നും ഇൻസ്റ്റാൾ ചെയ്ത VPN ക്ലയന്റ് മൂന്ന് വ്യത്യസ്ത പ്രിഫിക്സുകളിൽ എത്താം. unit, പ്രിവിലേജ് നിയമം, ഇൻസ്റ്റാളർ എന്നിവയിൽ ഓരോന്നും അവയിൽ ഓരോ പ്രിഫിക്സ് രേഖപ്പെടുത്തി, മൂന്നിൽ രണ്ടെണ്ണം യോജിക്കാത്തപ്പോൾ തകരാർ പ്രത്യക്ഷപ്പെടുന്നു.

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/

നിർദ്ദിഷ്ട പൊരുത്തക്കേട് ഇങ്ങനെയാണ്: വെണ്ടർ സ്ക്രിപ്റ്റ് /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 വഴി എഡിറ്റ് ചെയ്യുന്നതാണ് നല്ലത്, അപ്പോൾ വെണ്ടറുടെ ഫയൽ തൊടാതെ നിൽക്കും, അപ്ഗ്രേഡുകൾ പ്രവചനീയമായിരിക്കും.

പ്രിവിലേജ് നിയമം അതേ പാതയോടും അതേ ഉപകമാൻഡുകളോടും യോജിക്കണം. /usr/local/bin/vpnclient-നുള്ള sudoers എൻട്രി /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-pager

systemctl show നിർണ്ണായക ഔട്ട്പുട്ടാണ്, കാരണം systemd യഥാർത്ഥത്തിൽ പാഴ്സ് ചെയ്ത argv, ഏത് drop-in ഉൾപ്പെടെ പ്രിന്റ് ചെയ്യുന്നു. systemd-analyze verify നിങ്ങൾ റീസ്റ്റാർട്ട് ചെയ്യുന്നതിന് മുമ്പ് കാണാത്തതോ പ്രവർത്തിപ്പിക്കാനാകാത്തതോ ആയ പാത പിടിക്കുന്നു, റീസ്റ്റാർട്ടിന് ശേഷമുള്ള status കമാൻഡ് പ്രോസസ്സ് ഇപ്പോൾ ഉണ്ടോ എന്ന് പറയുന്നു.

unit തുടങ്ങി പിന്നീട് പരാജയപ്പെട്ടാൽ, നിങ്ങൾ EXEC കുടുംബം വിട്ട് ക്ലയന്റിന്റെ സ്വന്തം പിശക് കൈകാര്യം ചെയ്യലിൽ പ്രവേശിച്ചു. ജേണലിൽ ക്ലയന്റിന്റെ സന്ദേശം തിരയുക, മറ്റൊരു execve പരാജയമല്ല. unit diff-ഉം sudoers diff-ഉം മാറ്റ രേഖയിൽ ഒരുമിച്ച് സൂക്ഷിക്കുക, അടുത്ത അപ്ഗ്രേഡ് വിഭജിത പാത നിശബ്ദമായി തിരികെ കൊണ്ടുവരാതിരിക്കാൻ.

അനുബന്ധ ലേഖനങ്ങൾ