OpenVPN क्रेडेंशियल फ़ाइल या प्रबंधन सॉकेट: किसे स्क्रिप्ट करें
auth-user-pass खाते का प्रॉम्प्ट संभालता है; प्रबंधन सॉकेट चारों को। एक्सपोज़र, स्क्रिप्टिंग लागत और सेवा में हर एक कैसे विफल होता है, इसकी तुलना करें।
जो स्क्रिप्ट OpenVPN शुरू करती है और कभी जुड़ती नहीं, वह आमतौर पर नेटवर्क की समस्या नहीं है: क्लाइंट एक प्रॉम्प्ट पर बैठा है, जिसे बनाने के लिए कोई टर्मिनल नहीं है। OpenVPN के पास बिना मनुष्य के उस प्रॉम्प्ट का उत्तर देने के ठीक दो समर्थित तरीके हैं, auth-user-pass के पीछे एक क्रेडेंशियल फ़ाइल और प्रबंधन सॉकेट, और वे एक-दूसरे की जगह नहीं ले सकते। फ़ाइल एक निर्देश का खर्च करती है और एक प्रॉम्प्ट का उत्तर देती है; सॉकेट हर प्रॉम्प्ट का उत्तर देता है और loopback पोर्ट खोल सकने वाली हर चीज़ को बिना प्रमाणीकरण वाला नियंत्रण चैनल देता है। आपके परिनियोजन में कौन आता है, यह इस पर निर्भर है कि वास्तव में कौन-सा प्रॉम्प्ट अवरुद्ध है और आप कौन-सा रहस्य शांत छोड़ सकते हैं।
तंत्र चुनने से पहले प्रॉम्प्ट का नाम रखें
चार प्रॉम्प्ट टर्मिनल पर एक जैसे दिखते हैं। खाता-जोड़ी सर्वर की PAM या auth-user-pass-verify सेटिंग से आती है और auth-user-pass उसका उत्तर देता है। निजी कुंजी का पासफ़्रेज़ कुंजी फ़ाइल का होता है और --askpass से पढ़ा या हाथ से टाइप किया जाता है। PKCS#12 बंडल अपना अलग पासवर्ड माँगता है। प्रॉक्सी प्रमाणीकरण खाता क्रेडेंशियल नहीं, --http-proxy जो auth फ़ाइल लेता है उसका उपयोग करता है।
जब OpenVPN systemd, PHP या Node के चाइल्ड के रूप में चलता है तो कोई टर्मिनल नहीं होता, इसलिए इनमें से कोई भी चुपचाप अवरुद्ध कर देता है। प्रक्रिया वहीं बैठी रहती है, साइफ़र पंक्ति के बाद लॉग रुक जाता है और यूनिट अंततः समय-सीमा पार कर जाती है; यही चुप्पी कारण है कि लोग यह देखने के बजाय कि कौन-सा प्रॉम्प्ट लंबित है, रीट्राई लूप या sleep जोड़ देते हैं। केवल प्रबंधन सॉकेट चारों का उत्तर दे सकता है। क्रेडेंशियल फ़ाइल पहले का उत्तर देती है और किसी और का नहीं।
auth-user-pass: एक फ़ाइल, एक प्रॉम्प्ट
फ़ाइल में पहली पंक्ति पर उपयोगकर्ता नाम और दूसरी पर पासवर्ड होता है, और कुछ नहीं: कोई उद्धरण नहीं, कोई कुंजी-नाम नहीं, कोई टिप्पणी नहीं। मोड 600 सेट करें और मालिक उस खाते को बनाएँ जो openvpn चलाता है, जो किसी सेवा के लिए अक्सर आपके लॉगिन के बजाय एक समर्पित उपयोगकर्ता होता है। /root के नीचे root के स्वामित्व वाली फ़ाइल उस आदेश के बीच का अंतर है जो आपके शेल में चलता है और उस यूनिट के बीच जो बूट पर विफल होती है।
दो ब्यौरे सही फ़ाइल को प्रॉम्प्ट में बदल देते हैं। CRLF सहेजने वाला एडिटर पासवर्ड से चिपका हुआ कैरिज रिटर्न छोड़ देता है, इसलिए सर्वर ऐसा पासवर्ड अस्वीकार कर देता है जो फ़ाइल में सही दिखता है; आँख से नहीं, cat -A या od -c से जाँचें। और प्रोफ़ाइल के भीतर बिना आर्ग्युमेंट वाला auth-user-pass डिज़ाइन से «उपयोगकर्ता से पूछें» का अर्थ है, जिसे कमांड लाइन पर दूसरा निर्देश शायद ओवरराइड न कर सके, क्योंकि प्रोफ़ाइल वहीं पार्स होती है जहाँ वह है।
विकल्पों का क्रम तीसरा जाल है, और यह संस्करण-विशिष्ट है। कुछ OpenVPN 2.4 बिल्ड --config से पहले आने पर --auth-user-pass को अनदेखा करते हैं, इसलिए वही दो विकल्प उल्टे क्रम में जुड़ते हैं। निर्देश को प्रोफ़ाइल के भीतर या कमांड लाइन पर --config के बाद रखें, और कुछ और बदलने से पहले प्रोफ़ाइल में हर घटना को grep करें।
auth-nocache इस तंत्र का है पर कुछ देता नहीं। यह सीमित करता है कि क्लाइंट क्रेडेंशियल को स्मृति में कितनी देर रखता है, जो क्रैश के बाद मदद करता है और फ़ाइल न होने पर बिलकुल नहीं। सर्वर-साइड सत्र समय-सीमा के बाद पुनः कनेक्ट फ़ाइल को फिर से पढ़ता है, इसलिए बूट पर काम करने वाला क्रेडेंशियल दिन के मध्य में भी समाप्त हो सकता है।
प्रबंधन सॉकेट: हर प्रॉम्प्ट, अधिक सतह
क्लाइंट को लिसनर के साथ शुरू करें और स्पष्ट रूप से बताएँ कि प्रॉम्प्ट उस पर रिपोर्ट किए जाएँगे, OpenVPN 2.6 मैनुअल में प्रलेखित निर्देशों का उपयोग करके:
management 127.0.0.1 3030
management-query-passwords
bash से कनेक्शन को एक अतिरिक्त फ़ाइल डिस्क्रिप्टर पर रखें और स्थिति के बजाय प्रॉम्प्ट के नाम से उत्तर दें, क्योंकि पुनः कनेक्ट किसी दूसरे क्रम में पूछ सकता है:
exec 3<>/dev/tcp/127.0.0.1/3030
while read -r -u 3 line; do
case "$line" in
*"Need 'Auth' username/password"*)
echo 'username "Auth" alice' >&3
echo 'password "Auth" secret' >&3 ;;
*"Need 'Private Key' password"*)
echo 'password "Private Key" secret' >&3 ;;
esac
done
सीमा परिवहन है। प्रबंधन प्रोटोकॉल loopback पर TCP के ऊपर सादा पाठ है, इसलिए दूरस्थ नियंत्रक तक पहुँचने के लिए लिसनर को LAN या टनल पते पर प्रकाशित नहीं करना चाहिए; दूरस्थ नियंत्रक का अर्थ SSH अग्रेषण है, चौड़ा बंधन नहीं। समुदाय डेमन भी एक बार में केवल एक प्रबंधन क्लाइंट स्वीकार करता है, इसलिए GUI या मॉनिटर आपकी स्क्रिप्ट के साथ सॉकेट साझा नहीं कर सकते। दूसरा कनेक्शन अस्वीकार किया जाता है, कतार में नहीं रखा जाता, और विफलता बहरे हो चुके स्क्रिप्ट जैसी दिखती है।
वह सॉकेट नियंत्रण चैनल भी है। प्रबंधन पासवर्ड के बिना 127.0.0.1:3030 से जुड़ सकने वाली हर चीज़ स्थिति पढ़ सकती है, टनल को मार सकती है या स्वयं किसी प्रॉम्प्ट का उत्तर दे सकती है। प्रबंधन पासवर्ड और क्रेडेंशियल फ़ाइल एक ही श्रेणी के रहस्य हैं, और दोनों समान सावधानी के योग्य हैं।
परिनियोजन के लिए कौन उपयुक्त है
क्रेडेंशियल फ़ाइल चुनें जब एकमात्र प्रॉम्प्ट खाता-जोड़ी हो, क्लाइंट स्थिर मालिक के साथ सेवा के रूप में चले, और आप 600 फ़ाइल को ऐसे बैकअप से बाहर रख सकें जिन्हें आप नियंत्रित नहीं करते। प्रबंधन सॉकेट चुनें जब कुंजी पासफ़्रेज़ या PKCS#12 पासवर्ड शामिल हो, जब रैपर पहले से प्रक्रिया की निगरानी कर रहा हो, या जब पुनः कनेक्ट डीबग करते समय स्थिति और प्रॉम्प्ट देखने पड़ें।
दो शर्तें निर्णय बदलती हैं। यदि रैपर /bin/sh है, सीधे बाइनरी को बुलाने वाली systemd यूनिट है, या न्यूनतम कंटेनर है, तो केवल-bash सॉकेट गोंद उपलब्ध नहीं है और फ़ाइल सस्ता उत्तर है। यदि रहस्य अक्सर घूमता है, तो कोई भी फ़ाइल उसके लिए अच्छा घर नहीं है: छोटे रैपर से कुंजीरिंग पूछें और यूनिट को रैपर बुलाने दें, जो रोटेशन को एक जगह रखता है और पासवर्ड को शेल इतिहास से बाहर।
प्रोसेस प्रतिस्थापन दोनों के बीच है और किसी का नहीं। नीचे की एक-पंक्ति काम करती है क्योंकि bash इसे openvpn शुरू होने से पहले विस्तारित करता है, इसलिए नहीं कि क्लाइंट वाक्यविन्यास समझता है:
openvpn --config client.ovpn --auth-user-pass <(printf "%s
%s
" "$USER" "$PASS")
यह /bin/sh के अंतर्गत, शेल को बायपास करने वाली यूनिट में, और bash या /dev/fd के बिना इमेज में टूट जाती है। इसे इंटरैक्टिव परीक्षण के लिए रखें, कभी उस अनुबंध के रूप में नहीं जिस पर सेवा निर्भर करती है।
रहस्य की रक्षा करें, फिर लॉग से सत्यापित करें
दोनों तंत्र OpenVPN प्रक्रिया के लिए पठनीय रहस्य छोड़ते हैं। पासवर्ड को कभी कमांड लाइन पर या यूनिट फ़ाइल में न रखें, जहाँ ps और systemctl इसे हर स्थानीय उपयोगकर्ता को दिखाते हैं; फ़ाइल का पथ दें, उसके अंदर का मान नहीं। जहाँ प्रमाणपत्र खाता-जोड़ी की जगह ले सकते हैं, वह प्रॉम्प्ट की श्रेणी को छिपाने के बजाय हटा देता है।
सही रन प्रॉम्प्ट अनुक्रम पूरा होना और सत्र «Initialization Sequence Completed» तक पहुँचना दिखाता है। यदि क्लाइंट उसी प्रॉम्प्ट पर रुक जाए तो मिलान विफल हुआ: सॉकेट द्वारा भेजी गई ठीक पंक्तियाँ प्रिंट करें, उद्धरण और प्रॉम्प्ट का नाम जाँचें, और sleep जोड़ने के बजाय पैटर्न ठीक करें। जो टनल सफलता बताती है और कुछ नहीं ढोती वह रूटिंग या push समस्या है, क्रेडेंशियल समस्या नहीं।
फिर केवल पहला प्रारंभ नहीं, पुनः कनेक्ट भी जाँचें। सर्वर-साइड सत्र गिरा दें या उसकी समय-सीमा पूरी होने दें; क्लाइंट फिर पूछता है, और वहीं बूट पर सही दिखने वाली फ़ाइल दिखाती है कि क्या वह पुनः जुड़ने वाले खाते के लिए अब भी पठनीय है।