एक देश के लिए चालीस .ovpn फ़ाइलें किसी प्रदाता से आती हैं, और योजना स्पष्ट लगती है: कोई एक यादृच्छिक प्रतिलिपि उसकी जगह पर रखें, फिर टनल शुरू करें। ExecStart के भीतर पाइपलाइन के रूप में लिखने पर वह योजना बूट के समय ऐसे स्टेटस कोड के साथ मर जाती है जो कुछ नहीं समझाता। यूनिट फ़ाइल कोई स्क्रिप्ट नहीं है, और सुधार यह है कि या तो स्पष्ट रूप से कोई शेल लाया जाए या फ़ाइलें चुनना पूरी तरह बंद कर दिया जाए।

लक्षण: ऐसी यूनिट जो शुरू होती है और तुरंत मर जाती है

स्थिति दिखाती है कि सेवा सेकंड के एक अंश में विफल हो गई, और जर्नल की पंक्ति ऐसे आदेश का नाम लेती है जो किसी शेल को कभी नहीं मिला होता। टनल के बारे में कुछ नहीं दिखता, क्योंकि टनल कभी शुरू ही नहीं हुई।

जर्नल से सटीक कमांड लाइन पढ़ना इसकी पुष्टि का सबसे तेज़ तरीका है। systemd जो निष्पादित किया उसे दोहराता है, और स्ट्रिंग पाइपलाइन के अक्षरों को ऑपरेटर के रूप में नहीं बल्कि शाब्दिक आर्ग्युमेंट के रूप में दिखाएगी।

ExecStart पाइपलाइन क्यों नहीं चला सकता

systemd स्वयं कमांड लाइन को विभाजित करता है, अपना उद्धरण और चर-प्रतिस्थापन लागू करता है, और फिर परिणाम को सीधे निष्पादित करता है। पाइप, रीडायरेक्शन, शेल द्वारा ग्लोब विस्तार और कमांड प्रतिस्थापन सीधे-सीधे इस व्याकरण का हिस्सा नहीं हैं। यह डिज़ाइन का चुनाव है, चूक नहीं: यूनिट घोषित करती है कि क्या चलाना है, और शेल का तर्क उस स्क्रिप्ट में होता है जिसे यूनिट कॉल करती है। दोनों सुधार इसी से निकलते हैं, और किसी में भी यूनिट को अधिक विशेषाधिकार देने की आवश्यकता नहीं है।

यह भ्रामक एग्ज़िट कोड को भी समझाता है। पहले आर्ग्युमेंट को बाइनरी माना जाता है, इसलिए ख़राब बनी पंक्ति आपके तर्क का कोई भी भाग चलने से पहले विफल हो जाती है।

चयन ExecStartPre में करें

सीधा सुधार एक तैयारी चरण है जो स्पष्ट रूप से शेल को बुलाता है और चयन तथा शुरुआत को एक ही यूनिट में रखता है, ताकि एक में विफलता दूसरे को अकेले चलता हुआ न छोड़े।

[Service]
Type=notify
ExecStartPre=/bin/bash -c "ls /etc/openvpn/profiles/au* | shuf -n 1 | xargs -r -I{} cp -f {} /etc/openvpn/%i.conf"
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf

तीन ब्यौरे तय करते हैं कि यह किसी वास्तविक मशीन के संपर्क में टिकेगा या नहीं। नामकरण पहला जाल है: systemd यूनिट को पार्स करते समय ही, bash चलने से बहुत पहले, %i को प्रतिस्थापित कर देता है, इसलिए स्पेसिफ़ायर को एकल उद्धरणों के बाहर रहना होगा। xargs -r तब cp को बिना आर्ग्युमेंट चलने से रोकता है जब ग्लोब किसी चीज़ से मेल नहीं खाता। और विफल तैयारी चरण यूनिट को रोक देता है, और यही सही परिणाम है: कल के कॉन्फ़िगरेशन के साथ शुरू करना न शुरू करने से बुरा है। जो यादृच्छिक चयन हमेशा वही फ़ाइल लेता है वह आमतौर पर बदक़िस्मती नहीं है। जाँचें कि क्या प्रतिलिपि की गई फ़ाइल किसी पैकेज अद्यतन द्वारा अधिलेखित हो रही है, या ग्लोब केवल एक पुरानी प्रविष्टि से मेल खा रहा है।

या OpenVPN को एंडपॉइंट चुनने दें

OpenVPN पहले से ही एक प्रोफ़ाइल में कई एंडपॉइंट रख सकता है और उनमें से यादृच्छिक रूप से चुन सकता है, जिससे शेल, प्रतिलिपि और लिखने का अधिकार बूट पथ से पूरी तरह हट जाते हैं।

client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>

यह रूप सर्वर चयन को प्रदाता द्वारा लिखी गई फ़ाइल के भीतर रखता है, इसलिए फ़ाइलों का नाम बदलने वाला रोटेशन यूनिट को नहीं तोड़ता। यह उम्मीदवारों की सूची को लेखा-परीक्षण योग्य भी बनाता है, जो किसी निर्देशिका पर ग्लोब कभी नहीं होता। मिलान तब भी अपनी जगह रखता है जब प्रोफ़ाइल किसी एंडपॉइंट से अधिक चीज़ों में भिन्न हों: भिन्न प्रमाणपत्र, भिन्न रूटिंग निर्देश, भिन्न सिफ़र नीति। उस स्थिति में चयन पूरे कॉन्फ़िगरेशन के बीच होता है और शेल वाला चरण इसे व्यक्त करने का ईमानदार तरीका है।

जिस इंस्टेंस और फ़ाइल का उसने उपयोग किया उसे फिर से पढ़ें

इसकी सामग्री को डीबग करने से पहले पुष्टि करें कि वास्तव में कौन-सी यूनिट चल रही है। पैकेज की मेटा सेवा और टेम्पलेट अधोसंरचना हैं; आपकी फ़ाइलों के अनुरूप यूनिट वही इंस्टेंस हैं जो उनके नाम पर बने हैं।

systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager

जिस इंस्टेंस को सक्रिय करने की किसी को याद नहीं रहती वह आमतौर पर पैकेज निर्देशिका में किसी भटकी हुई कॉन्फ़िगरेशन फ़ाइल तक जाता है। टेम्पलेट के बजाय उसी नाम वाले इंस्टेंस को बंद करें, वरना अगला पैकेज अपग्रेड उसे वापस ले आएगा। बदलाव के बाद यूनिट शुरू करें और जर्नल जो कमांड लाइन बताता है उसे पढ़ें, फिर उस कॉन्फ़िगरेशन पथ की पुष्टि करें जो उसने वास्तव में खोला। वह एक जाँच काम करने वाले यादृच्छिक चयन को उस सेवा से अलग करती है जो चुपचाप पिछले महीने की फ़ाइल फिर से इस्तेमाल कर रही है।

संबंधित लेख