OpenVPN कुंजी बनाने के लिए आपको कोई अस्थायी फ़ाइल नहीं चाहिए
कुंजी की सामग्री को स्मृति में रखना फ़ाइल के जीवन-चक्र से बचता है, रिसाव से नहीं। आउटपुट और त्रुटि की धाराएँ अलग रखें, और बाद में कुंजी को रहस्य मानें।
कुंजी बनाने के लिए अस्थायी फ़ाइल की जरूरत नहीं होती, और उसे छोड़ देना अधिकांश मार्गदर्शिकाओं के संकेत से कम सुधारता है। यह जो हटाता है वह एक फ़ाइल का जीवन-चक्र और उसके आसपास की सफ़ाई की दौड़ है। यह जो अछूता छोड़ता है वह बाद में रहस्य लीक करने का हर अवसर है। इन स्क्रिप्टों में शुद्धता की समस्या आम तौर पर कहीं और बैठती है, क्योंकि निदान और कुंजी की सामग्री अलग-अलग धाराओं में यात्रा करते हैं।
फ़ाइल कभी वह जोखिम नहीं थी जो आपने सोचा था
अस्थायी फ़ाइल एक ठोस जोखिम है जब वह सबके पढ़ने योग्य हो, जब वह क्रैश से बच जाए, या जब अपवाद के बाद सफ़ाई का चरण छूट जाए। ये वास्तविक हैं, और इन्हें ठीक करना उचित है। ये स्थानीय, दृश्य और परखने में आसान भी हैं। परिवर्तन को केवल दिखावटी मानने से पहले अपनी स्क्रिप्ट में हर एक का नाम लें।
अधिक शांत जोखिम नीचे की ओर बैठते हैं: डीबगिंग के दौरान छपी कुंजी, पूरे परिणाम ऑब्जेक्ट को क्रमबद्ध करने वाला अपवाद, कोर डंप लिखने वाला क्रैश हैंडलर, पहले फ़ाइल का पथ और फिर सामग्री पाने वाला लॉग संग्राहक। अस्थायी फ़ाइल से बचना इनमें से किसी के लिए कुछ नहीं करता, और इसके विपरीत मानना वह तरीका है जिससे सद्भावना वाला पुनर्लेखन रहस्य को पहले से अधिक खुला छोड़ देता है। परिवर्तन को क्रम में एक सुधार मानें, समाधान नहीं।
जब कोई फ़ाइल नाम नहीं दिया जाता तो क्लाइंट क्या लिखता है
क्लाइंट के मौजूदा संस्करण बिना आउटपुट पथ के कुंजी आदेश दिए जाने पर बनी कुंजी को मानक आउटपुट पर भेजते हैं। यही प्रलेखित व्यवहार स्मृति-आधारित दृष्टिकोण को व्यवहार्य बनाता है, और यह उपकरण को किसी डिवाइस पथ की ओर इंगित करने की पुरानी चाल की जरूरत हटा देता है।
import subprocess
proc = subprocess.run(
["openvpn", "--genkey", "tls-crypt"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
)
key_material = proc.stdout
आदेश को सूची के रूप में दें। यहाँ किसी शेल विस्तार की जरूरत नहीं है, और शेल सक्षम करना तर्कों की सीमा को ऐसे उद्धरणों पर निर्भर बना देता जो आपके नियंत्रण में नहीं हैं। यदि स्क्रिप्ट आपकी अपेक्षा से भिन्न खोज पथ के साथ चल सकती है तो इच्छित निष्पादन योग्य को निरपेक्ष पथ से इस्तेमाल करें।
वापसी कोड की जाँच असफल आह्वान के बाद सफलता के पथ को आगे बढ़ने से रोकती है। इसके बिना, खाली बाइट स्ट्रिंग आगे बह सकती है और बहुत बाद में विफल होती है, उस बिंदु पर जहाँ कुंजी उपयोग होती है और त्रुटि संदेश अब निर्माण का जिक्र भी नहीं करता।
दो धाराएँ, दो अर्थ
मानक आउटपुट कुंजी ढोता है। मानक त्रुटि वह सब ढोती है जो उपकरण आपको बताना चाहता है, जिसमें कॉन्फ़िगरेशन, संस्करण और कुंजी के प्रकार के बारे में चेतावनियाँ शामिल हैं। दोनों को एक बफ़र में मोड़ना वही गलती है जो विश्वसनीय दिखने वाली कुंजी पैदा करती है जिसके बीच में एक वाक्य सिला हुआ होता है।
विफलता का पथ भी अलग रखें। जब आह्वान विफल हो, तो विफल हुए आदेश और निकास स्थिति की सूचना दें, और फिर सचेत रूप से तय करें कि मानक त्रुटि का कोई भाग दिखाना सुरक्षित है या नहीं। पूरे परिणाम ऑब्जेक्ट को लॉग में उंडेलना आम शॉर्टकट है, और यह कुंजी को साथ ले जा सकता है।
बाइनरी के लिए सुरक्षित पठन तब मायने रखता है जब आप बाद में सामग्री का हैश करें या उसकी तुलना करें। अप्रत्याशित एन्कोडिंग वाला टेक्स्ट मोड ऐसे बाइट बदल सकता है जो कभी टेक्स्ट होने के लिए नहीं थे, और बदली हुई कुंजी हैंडशेक विफल होने तक गलत कुंजी से अलग नहीं पहचानी जाती।
अगर आप उसे फिर भी सहेजें, तो सचेत रूप से करें
अधिकांश परिनियोजनों को अंततः कुंजी डिस्क पर, गेटवे पर या रहस्य भंडार में चाहिए। उसे एक बार लिखें, निर्माण से ही प्रतिबंधित अनुमतियों के साथ, बाद के chmod के बजाय, और लेखन को परमाणु बनाएँ ताकि आंशिक फ़ाइल कभी वह न बने जिसे कोई सेवा शुरू होते समय पढ़ती है। एक ही निर्देशिका के पथ से नाम बदलना आम तौर पर उसके लिए पर्याप्त है। विफलता की शाखा में स्टेजिंग पथ हटा दें, क्योंकि विफल लेखन ठीक वही प्रति है जिसे लोग भूल जाते हैं।
फ़ाइल बनाते समय उसका मोड सेट करें, और निर्देशिका का मोड भी प्रतिबंधित रखें। ऐसे स्थान के नीचे किसी भी पथ से बचें जिसे कोई बैकअप कार्य बिना सोचे समेट लेता है, क्योंकि रात के बैकअप में रहस्य उस बैकअप की हर प्रति में रहस्य है। यही तर्क ऐसे साझा वॉल्यूम पर लागू होता है जिसे अन्य सेवाएँ पढ़ सकती हैं।
साझा कुंजी कोई पहचान नहीं है
यह सामग्री बनाना कोई प्रमाणपत्र जारी नहीं करता, किसी क्लाइंट को दर्ज नहीं करता और यह तय नहीं करता कि कौन जुड़ रहा है। साझा कुंजी उन पक्षों के बीच चैनल की रक्षा करती है जो पहले से एक-दूसरे पर भरोसा करते हैं; पहचान अभी भी प्रमाणपत्र से और उसके सामने बैठे किसी भी प्रमाणीकरण से आती है।
कुंजी के प्रकार भी एक-दूसरे के स्थान पर नहीं लगाए जा सकते। एक सुविधा के लिए सममित कुंजी दूसरे के लिए तैयार विकल्प नहीं है, और नए संस्करण हर सिरे पर अलग फ़ाइलों के साथ अपने प्रकार जोड़ते हैं। वह प्रकार बनाएँ जिसका नाम आपका कॉन्फ़िगरेशन वास्तव में लेता है, फिर उसे उस भूमिका में इस्तेमाल करें जो वह प्रकार परिभाषित करता है।
फ़ाइल का आकार देखने के बजाय वास्तविक कनेक्शन से परिणाम परखें। यदि हैंडशेक पूरा हो जाए और लॉग कोई कुंजी चेतावनी न दिखाएँ, तो निर्माण का पथ सही है; यदि कुंजी मिली-जुली धारा से कट गई होती, तो कनेक्शन ऐसे विफल होता जो स्क्रिप्ट नहीं, सामने वाले पक्ष की ओर इशारा करता।