OpenVPN client-connect विफलता: क्या disconnect पर सफ़ाई की गारंटी है?
अस्वीकृत क्लाइंट फ़ायरवॉल नियम या लिखा गया रिकॉर्ड वापस नहीं लेता। कॉलबैक अनुबंध की तुलना उस रोलबैक से करें जो आपके hook को स्वयं करना पड़ता है।
जब कोई client-connect स्क्रिप्ट ग़ैर-शून्य कोड के साथ बाहर निकलती है, तो OpenVPN क्लाइंट को अस्वीकार कर देता है, और ऑपरेटर आमतौर पर मान लेते हैं कि संबंधित client-disconnect स्क्रिप्ट सब ठीक कर देगी। अक्सर वह कभी चलती ही नहीं, क्योंकि disconnect प्रोसेसिंग इस पर निर्भर है कि connect चरण क्या पूरा कर सका। अस्वीकृति और रोलबैक को एक ही तंत्र मानना ही विफल लॉगिन को लीक हुए फ़ायरवॉल नियम या अनाथ रिकॉर्ड में बदल देता है। ये दो अलग ज़िम्मेदारियाँ हैं, और इनमें से केवल एक स्वचालित है। सर्वर पर स्थिति छोड़ने का आरोप लगाने से पहले hook का अपना एग्ज़िट पथ पढ़ें।
ग़ैर-शून्य एग्ज़िट क्लाइंट को अस्वीकार करती है; आपका काम वापस नहीं लेती
client-connect का एग्ज़िट स्टेटस प्रवेश का निर्णय है। शून्य का अर्थ प्रवेश है, बाकी कुछ भी का अर्थ इंस्टेंस को पूरी तरह स्थापित होने से पहले ढहा देना है। उस अनुबंध में कुछ भी यह नहीं जाँचता कि स्क्रिप्ट बाहरी दुनिया में पहले से क्या कर चुकी है। अगर स्क्रिप्ट ने iptables नियम जोड़ा, पंक्ति लिखी या काउंटर बढ़ाया, तो वे बदलाव अस्वीकृति के बाद भी बने रहते हैं।
यही असमानता प्लगइन पर भी लागू होती है, जहाँ एक इंस्टेंस के लिए कई connect फ़ंक्शन चल सकते हैं। बाद की विफलता पहले की सफलता को पूर्वव्यापी रूप से रद्द नहीं करती, और पहले फ़ंक्शन के पास यह जानने का कोई तरीका नहीं होता कि सहोदर फ़ंक्शन विफल हुआ।
अस्वीकृति स्वचालित है, सफ़ाई नहीं
OpenVPN 2.6 मैनुअल client-disconnect प्रोसेसिंग को पहले की connect प्रोसेसिंग के सफल होने से जोड़ता है। एक प्रलेखित अपवाद कैस्केड श्रृंखलाओं को कवर करता है: अगर एक connect चरण पहले ही सफलता लौटा चुका है, तो इंस्टेंस ढहाते समय संबंधित disconnect चरण फिर भी चलते हैं, भले ही बाद का connect चरण विफल हुआ हो। वह अपवाद संकीर्ण है और इस पर निर्भर है कि कितने कॉलबैक कॉन्फ़िगर हैं, इसलिए एक shell स्क्रिप्ट का परीक्षण आपको श्रृंखला के बारे में कुछ नहीं बताता।
डिज़ाइन करने से पहले वास्तविक कॉन्फ़िगरेशन का नक्शा बनाएँ: कौन-सी स्क्रिप्ट, कौन-सा प्लगइन और किस क्रम में चलते हैं। नीचे दी गई तालिका बताती है कि अधूरा सेटअप पीछे क्या छोड़ता है।
| What the hook did before failing | What the client sees | What stays behind |
|---|---|---|
| Created a firewall entry | A rejection, with no tunnel | A rule matching an address nobody owns |
| Wrote a state row | A rejection, with no tunnel | A record of a session that never started |
| Allocated a tunnel address | A rejection, with no tunnel | An address marked busy until something releases it |
हर पंक्ति क्लाइंट के लिए एक ही तरह और होस्ट के लिए अलग तरह से समाप्त होती है। क्लाइंट यह नहीं बता सकता कि इनमें से कौन-सी घटी, इसलिए hook को विफलता स्टेटस लौटाने से पहले अपना किया हुआ वापस लेना पड़ता है।
जो स्क्रिप्ट विफल हुई उसी के भीतर क्षतिपूर्ति करें
साझा स्थिति को छूने से पहले जो भी संभव हो सत्यापित करें: प्रमाणपत्र के फ़ील्ड, पते की उपलब्धता, वह समूह जिससे क्लाइंट संबंधित है। सबसे सस्ती अस्वीकृति वही है जो किसी भी आवंटन से पहले होती है। जब सेटअप कई बाहरी कार्रवाइयों में फैल जाए, तो रिकॉर्ड रखें कि कौन-सी पूरी हुईं और विफलता स्टेटस लौटाने से पहले उन्हें उल्टे क्रम में वापस लें।
एक ठोस उदाहरण: स्क्रिप्ट प्रति-क्लाइंट फ़ायरवॉल प्रविष्टि बनाती है, फिर उसे वर्णित करने वाली स्थिति-पंक्ति लिखने में विफल हो जाती है। विफल शाखा को अभी बनाई गई प्रविष्टि हटानी चाहिए और फिर ग़ैर-शून्य कोड के साथ बाहर निकलना चाहिए। ऐसी disconnect घटना की प्रतीक्षा करना जो शायद कभी निर्धारित ही न हो, वही तरीका है जिससे नियम उस सत्र से ज़्यादा जीता है जिसके लिए वह बना था।
क्षतिपूर्ति को इडेम्पोटेंट और स्वामित्व वाला बनाएँ
सफ़ाई दो बार चलाने के लिए सुरक्षित होनी चाहिए और इस बारे में सटीक होनी चाहिए कि वह क्या हटा सकती है। पहले के प्रयास की देर से आई घटना को केवल इसलिए नए सत्र का आवंटन नहीं हटाना चाहिए कि दोनों एक साझा नाम या पुनर्चक्रित टनल पता साझा करते हैं। विशिष्ट हैंडल या ऑपरेशन आईडी संसाधन के साथ दर्ज करें, और नाम के बजाय उसी कुंजी से हटाएँ। डेटाबेस लेनदेन केवल डेटाबेस के अपने बदलावों में मदद करते हैं; उस सीमा के बाहर का फ़ायरवॉल नियम स्पष्ट क्षतिपूर्ति चरण मांगता है।
मान लें कि प्रक्रिया बदलाव और सफ़ाई के बीच मर सकती है, और एक समाधानकर्ता जोड़ें जो अनुसूची के अनुसार बाहरी स्थिति की तुलना स्वीकृत क्लाइंट सूची से करता है।
उन तीन पथों का परीक्षण करें जो वास्तव में भिन्न हैं
तीन मामलों का अभ्यास करें: कुछ भी आवंटित होने से पहले अस्वीकृति, आंशिक आवंटन के बाद अस्वीकृति, और एक सामान्य स्वीकृत सत्र जो बाद में समाप्त होता है। ये तीन अलग लॉग पंक्तियाँ और अलग अवशेष उत्पन्न करते हैं। हर एक के बाद बाहरी स्थिति पर जाँच करें, केवल क्लाइंट के विफलता संदेश पर नहीं, क्योंकि तीन में से दो में क्लाइंट की विफलता ही अपेक्षित परिणाम है।
hook का चरण, एग्ज़िट स्टेटस और क्या आवंटित या जारी हुआ, लॉग करें, क्रेडेंशियल छोड़कर। जो hook लॉग अपने बनाए संसाधन का नाम लेता है, वही छह महीने बाद लीक हुए नियम को खोजने योग्य बनाता है।