एउटा देशका लागि चालीस .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

कसैले पनि सक्रिय गरेको सम्झना नगरेको इन्स्टेन्स सामान्यतया प्याकेज डिरेक्टरीमा हराएको कन्फिगरेसन फाइलसम्म पुग्छ। टेम्प्लेटको सट्टा त्यही नामको इन्स्टेन्स बन्द गर्नुहोस्, नत्र अर्को प्याकेज अपग्रेडले त्यसलाई फर्काइदिन्छ। परिवर्तनपछि युनिट सुरु गर्नुहोस् र जर्नलले रिपोर्ट गर्ने आदेश लाइन पढ्नुहोस्, त्यसपछि यसले साँच्चै खोलेको कन्फिगरेसन मार्ग पुष्टि गर्नुहोस्। त्यो एउटै जाँचले काम गर्ने अनियमित छनोटलाई गत महिनाको फाइल चुपचाप पुनः प्रयोग गर्ने सेवाबाट अलग गर्छ।

सम्बन्धित लेखहरू