OpenVPN షెల్లో పనిచేస్తుంది కానీ cron కింద విఫలమవుతుంది: కారణం PATH
షెల్ నుండి కనెక్ట్ అయ్యే ఆదేశం టన్నెల్ ప్రారంభం కాకముందే cron లేదా subprocess కింద విఫలం కావచ్చు. మార్గం, పని డైరెక్టరీ మరియు టెర్మినల్ను సరిచేయండి.
అదే ఆదేశం షెల్ నుండి కనెక్ట్ అవుతుంది మరియు cron కింద చనిపోతుంది, కాబట్టి టన్నెల్ లేదా సర్టిఫికెట్ దోషి అని నిర్ధారించడం సహజం. అది నమ్మకముందు రెండు రన్లకు ఏమి సామాన్యమో చూడండి: బైనరీ, కాన్ఫిగరేషన్ మరియు క్రెడెన్షియల్స్ ఒకేలా ఉన్నాయి, ప్రక్రియ పర్యావరణం మాత్రమే మారింది. ప్రోగ్రామ్ కనుగొనబడనప్పుడు, ఎంత TLS డీబగ్గింగ్ అయినా సహాయపడదు. సరిదిద్దడం సాధారణంగా మార్గంలో, పని డైరెక్టరీలో మరియు కొన్ని పర్యావరణ చరాలలో ఉంటుంది, VPN లో కాదు.
పనిచేసే షెల్లో command -v openvpn సమాధానాన్ని ముద్రిస్తుంది, అది చాలాసార్లు /usr/sbin/openvpn, అంటే cron తన శోధన మార్గంలో పెట్టని డైరెక్టరీ.
టన్నెల్ ఎప్పుడూ ప్రారంభం కాలేదు, కాబట్టి టన్నెల్ సమస్య కాదు
cron ప్రారంభించే పనులు కనీస పర్యావరణాన్ని వారసత్వంగా పొందుతాయి, సాధారణంగా PATH=/usr/bin:/bin, మరియు నియంత్రణ టెర్మినల్ పొందవు. /usr/sbin లేదా /usr/local/sbin లో ఇన్స్టాల్ చేసినది ఆ జాబితాలో ఉండదు, మరియు లాగ్ లైన్ TLS లోపానికి బదులు openvpn: not found అని చదువుతుంది. Python యొక్క subprocess వేరే విధంగా విఫలమవుతుంది: ఇది ఇంటర్ప్రెటర్ ప్రక్రియ పర్యావరణాన్ని వారసత్వంగా పొందుతుంది, అది cron కంటే సంపన్నంగా ఉండవచ్చు కానీ టిల్డాను విస్తరించే షెల్ ఇంకా లేదు. రెండు వైఫల్యాలు ఒక ప్యాకెట్ కూడా హోస్ట్ను విడిచిపెట్టకముందే సంభవిస్తాయి.
వాటిని వేరు చేసే వేగవంతమైన మార్గం చివరి లోపానికి బదులు మొదటి లోపాన్ని చదవడం. లేని బైనరీ షెల్ లేదా Python మినహాయింపును కలిగిస్తుంది, చెడు కాన్ఫిగరేషన్ OpenVPN వినియోగ సందేశాన్ని కలిగిస్తుంది, నిజమైన హ్యాండ్షేక్ వైఫల్యం సమయ ముద్రలు మరియు తోటి చిరునామాలను కలిగిస్తుంది. మూడవది మాత్రమే టన్నెల్ సమస్య.
పూర్ణ మార్గాలు మరియు ఆర్గ్యుమెంట్ జాబితాలు షెల్ స్ట్రింగ్లను ఓడిస్తాయి
పరిష్కరించిన మార్గాన్ని స్పష్టంగా ఇవ్వండి మరియు షెల్ను పూర్తిగా దాటవేయండి. subprocess.run(["/usr/sbin/openvpn", "--config", config, "--verb", "4"], capture_output=True, text=True, timeout=90) ఫైల్ పేరును వివరించమని షెల్ను అడగకుండా రిటర్న్ కోడ్, stdout మరియు stderr ఇస్తుంది. కాన్ఫిగరేషన్ మార్గాన్ని os.environ["HOME"] లేదా pathlib.Path.home() నుండి నిర్మించండి, టిల్డా ఎప్పుడూ విస్తరించాల్సిన అవసరం లేకుండా. నిజంగా షెల్ సింటాక్స్ అవసరమైనప్పుడు shlex.split ఉపయోగించండి, ఎందుకంటే .split() తో స్ట్రింగ్ విభజించడం ఖాళీ ఉన్న ఏ మార్గంలోనైనా విరిగిపోతుంది. stderr కూడా చదవండి, ఎందుకంటే OpenVPN తన చాలా ప్రారంభ వైఫల్యాలను అక్కడే రాస్తుంది.
అదే నియమం cron కి కూడా వర్తిస్తుంది: పని లైన్ లాగిన్ షెల్ కాదు, కాబట్టి ఏదీ మీ ప్రొఫైల్ను లోడ్ చేయదు మరియు ఏదీ మీ మారుపేర్లను నిర్వచించదు.
crontab నిజంగా ఏమి వారసత్వంగా పొందుతుంది
crontab ఎంట్రీ crontab ప్రకటించే పర్యావరణాన్ని మరియు కొన్ని వారసత్వ డిఫాల్ట్లను పొందుతుంది, కాబట్టి మార్గాన్ని పూర్తిగా రాయండి లేదా అది చేసే స్క్రిప్ట్లో కాల్ను చుట్టండి. ఫైల్ పైభాగంలో PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin లాంటి లైన్ సాధారణ ఇన్స్టాల్ స్థానాలను కవర్ చేస్తుంది, >> cron.log 2>&1 తో మళ్లింపు తదుపరి వైఫల్యాన్ని చదవగలిగేలా చేస్తుంది. పాస్ఫ్రేజ్తో రక్షించబడిన ప్రొఫైల్ cron కింద తన రహస్యాన్ని అడగడానికి మార్గం లేదు, ఎందుకంటే అడగడానికి టెర్మినల్ లేదు. అలాంటి కనెక్షన్ క్రెడెన్షియల్ ఫైల్ చదవగల systemd యూనిట్కు చెందాలి, తనను ఇంటరాక్టివ్ అని నటించే పనికి కాదు.
సాపేక్ష మార్గాలు రెండవ ఉచ్చు. పరీక్షా రన్ తరచుగా ప్రొఫైల్ ఉన్న ఫోల్డర్ నుండి జరుగుతుంది, cron పని పూర్తిగా వేరే చోట ప్రారంభమవుతుంది, కాబట్టి --config office.ovpn అక్కడ లేని ఫైల్గా పరిష్కరించబడుతుంది మరియు సందేశం లేని టన్నెల్కు బదులు లేని ఫైల్గా చదవబడుతుంది.
పర్యావరణాన్ని తీసేసి నిరూపించండి
కనీస పర్యావరణాన్ని నేరుగా పునరుత్పత్తి చేయండి: env -i PATH=/usr/bin:/bin /usr/sbin/openvpn --config office.ovpn --verb 4. ఆ రన్ నుండి మార్గం లేదా టెర్మినల్ గురించి ఫిర్యాదు వస్తే సమస్య VPN పైన ఉంది. అది కనెక్ట్ అయితే, మిగిలిన అనుమానితులు అది నడిచే ఖాతా, అది ప్రారంభమయ్యే డైరెక్టరీ మరియు అది అందించే క్రెడెన్షియల్. రెండు ఫలితాలలో ఏదైనా సర్టిఫికెట్ తనిఖీ మరో రౌండ్ కంటే మెరుగుది.
తర్వాత ర్యాపర్ను స్వయం నివేదికగా చేయండి. అది చేరుకున్న ప్రతి దశకు ప్రత్యేక స్థితితో బయటకు వెళ్లండి, రెండు స్ట్రీమ్లను సమయ ముద్రతో లాగ్ చేయండి, తదుపరి వైఫల్యం అది మార్గ పరిష్కారంలో, ప్రామాణీకరణలో, లేదా టన్నెల్ ఇప్పటికే పైన ఉన్న తర్వాత చనిపోయిందా అని చెబుతుంది.
యూనిట్కు సరైన క్రమం కూడా అవసరం: Wants=network-online.target తో పాటు After=network-online.target చిరునామా లేదా డిఫాల్ట్ మార్గం ఉన్నట్లు ఏర్పడకముందే క్లయింట్ ప్రారంభం కాకుండా నిరోధిస్తాయి, లేకపోతే అది సర్టిఫికెట్ లేదా TLS లోపాలుగా కనిపించి చేతితో పునఃప్రారంభించినప్పుడు మాయమవుతుంది.