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 ક્લાયન્ટના પોતાના કોડ સુધી પહોંચતી નથી, તેથી પ્રોફાઇલ સંપાદન કે ઓળખપત્ર ચકાસણી કોઈ મદદ કરી શકતી નથી.
સ્થિતિ કોડ આ કુટુંબને સામાન્ય ક્રેશથી અલગ પાડે છે. status=203/EXEC સાથે નીકળતા unit એ ક્યારેય પ્રક્રિયા શરૂ કરી નથી; જે unit શરૂ થઈને પછી status=1 સાથે નીકળે છે તે કદાચ પ્રમાણીકરણ, DNS કે રૂટિંગમાં નિષ્ફળ ગયું હોઈ શકે. ક્લાયન્ટ લોગ પહેલાં કોડ વાંચો, કારણ કે પ્રથમ કિસ્સામાં ક્લાયન્ટ લોગ ખાલી રહેશે.
જર્નલમાંનો પાથ એ છે જે systemd એ વાપર્યો, જરૂરી નથી કે તમે સંપાદિત કર્યો હોય તે. Drop-in ફાઇલો અને જનરેટરનું આઉટપુટ વેન્ડર ફાઇલને બદલી શકે છે, અને જૂનું daemon-reload જૂની લીટી મેમરીમાં રહેવા દે છે. તેથી પ્રથમ નિદાન એ છે કે systemd ને પૂછવું કે તે આદેશને શું માને છે, તમે યાદ રાખો છો તે ફાઇલ ખોલવાને બદલે.
બાઈનરીનો પાથ લખાયેલો હોય તેવા ત્રણ સ્થળો
ડિસ્ટ્રિબ્યુશન પેકેજ, વેન્ડર સ્ક્રિપ્ટ અને રિલીઝ tarball માંથી ઇન્સ્ટોલ થયેલો VPN ક્લાયન્ટ ત્રણ અલગ પ્રીફિક્સમાં આવી શકે છે. 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 દ્વારા સંપાદિત કરવું વધુ સારું છે, જેથી વેન્ડર ફાઇલ અકબંધ રહે અને અપગ્રેડ અનુમાનિત રહે.
વિશેષાધિકાર નિયમ એ જ પાથ અને એ જ પેટા-આદેશો સાથે મેળ ખાવો જોઈએ. /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-pagersystemctl show નિર્ણાયક આઉટપુટ છે, કારણ કે તે systemd એ ખરેખર વિશ્લેષણ કરેલું argv છાપે છે, કોઈપણ drop-in સહિત. systemd-analyze verify રીસ્ટાર્ટ પહેલાં ગુમ થયેલો કે ન ચલાવી શકાય તેવો પાથ પકડે છે, અને રીસ્ટાર્ટ પછીનો status આદેશ કહે છે કે પ્રક્રિયા હવે છે કે નહીં.
જો unit શરૂ થાય અને પછી નિષ્ફળ જાય, તો તમે EXEC કુટુંબ છોડીને ક્લાયન્ટની પોતાની ભૂલ-સંચાલનમાં પ્રવેશ્યા છો. જર્નલમાં ક્લાયન્ટનો સંદેશ શોધો, બીજી execve નિષ્ફળતા નહીં. unit નો diff અને sudoers નો diff ફેરફાર રેકોર્ડમાં સાથે રાખો, જેથી આગલું અપગ્રેડ વિભાજિત પાથને શાંતિથી પાછો ન લાવે.