संदेश कहता है कि OpenVPN इनलाइन प्रमाणपत्र लोड नहीं कर सकता, जबकि आपके दिमाग़ में बैठा फ़ाइल नाम उलटा कहता है। पार्सर को क्या मिला, यह इससे ज़्यादा मायने रखता है कि फ़ाइल सिस्टम में क्या है, क्योंकि cert निर्देश पूरी तरह अलग दो तरह के मान स्वीकार करता है। एक वह पथ है जिसे वह खोलता है; दूसरा वह PEM टेक्स्ट है जो कॉन्फ़िगरेशन के भीतर आया। जब तक आप नहीं जानते कि चल रहे क्लाइंट को कौन-सा रूप मिला, हर सुधार एक अनुमान है।

दो भंडारण रूप, एक निर्देश

cert, key और ca निर्देशों में से प्रत्येक एक पथ या एक इनलाइन ब्लॉक स्वीकार करता है। जब मान पथ होता है, OpenVPN उस फ़ाइल को खोलता है और ऑब्जेक्ट को डिस्क से पढ़ता है। जब कॉन्फ़िगरेशन में cert टैग से घिरा ब्लॉक होता है, तो वही निर्देश इसके बजाय उन टैगों के बीच की सामग्री का उपभोग करता है, और कोई अलग फ़ाइल शामिल नहीं होती।

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

उलटा सच नहीं है। जो प्रोफ़ाइल अपना डेटा भीतर जड़ता है उसके पास client.crt रखने से कुछ नहीं बदलता, क्योंकि कॉन्फ़िगरेशन में कुछ भी उस फ़ाइल का संदर्भ नहीं देता। स्पष्ट रूप से मौजूद फ़ाइल के अनदेखा लगने का यह सबसे आम कारण है।

इनलाइन ब्लॉक ऑब्जेक्ट कैसे बनता है

इनलाइन सामग्री को कॉन्फ़िगरेशन से निकाला जाता है और टेक्स्ट के रूप में PEM पार्सर को सौंपा जाता है। वह पार्सर सामान्य सीमाओं की अपेक्षा करता है: एक BEGIN पंक्ति, base64 पेलोड और उससे मेल खाती END पंक्ति। यदि ब्लॉक किसी असफल कॉपी से कट गया, किसी डाउनलोड पेज ने उसे HTML में लपेट दिया, या उसे ऐसे एडिटर में खोला गया जिसने डैश सामान्य कर दिए, तो पार्सर ऐसी सामग्री पर विफल हो जाता है जो मौजूद दिखती है।

<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>

इसीलिए त्रुटि का शब्दांकन भ्रामक है। इनलाइन शब्द बताता है कि लोडर ने कहाँ देखा, यह नहीं कि उसे वहाँ क्या मिला। कॉन्फ़िग में नामित फ़ाइल और उसमें जड़ा ऑब्जेक्ट एक ही शिकायत पैदा कर सकते हैं जब अंतर्निहित बाइट्स अनुपयोगी हों।

जाँचें कि लोड किया गया प्रोफ़ाइल वास्तव में कौन-सा रूप उपयोग करता है, यह नहीं कि आपके एडिटर ने संयोग से कौन-सी फ़ाइल खोली:

grep -nE '^(ca|cert|key) |^<(ca|cert|key)>' client.ovpn

पथ संदर्भ कैसे हल होता है

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

सापेक्ष पथ वही अस्पष्टता विरासत में लेते हैं। जब आप नंगा फ़ाइल नाम देखें, तो पूछें कि उत्पादन में प्रक्रिया की वर्तमान निर्देशिका क्या है, बजाय यह मान लेने के कि वह आपके टर्मिनल से मेल खाती है।

अलग से संग्रहीत प्रमाणपत्र के लिए, उसके ऊपर कुछ भी डिबग करने से पहले एक ऑफ़लाइन पार्स ऑब्जेक्ट की पुष्टि करता है:

openssl x509 -in client.crt -noout -subject -issuer -dates
openssl pkey -in client.key -noout -check

वे कमांड सिद्ध करते हैं कि फ़ाइलें पढ़ने योग्य और संरचनात्मक रूप से वैध हैं। वे यह सिद्ध नहीं करते कि सहकर्मी जारीकर्ता पर भरोसा करता है, प्रमाणपत्र अब भी अपनी वैधता अवधि के भीतर है, या कुंजी उसी की है।

पार्सर त्रुटि आपको क्या बता सकती है और क्या नहीं

पार्स विफलता समस्या को एक इनपुट और एक चरण तक सीमित करती है। यह नहीं बताती कि क्लाइंट ने दो भंडारण रूपों में से किसका उपयोग किया, और यह भी नहीं बताती कि ऑब्जेक्ट स्वीकार किया जाता या नहीं। ये अलग साक्ष्यों वाले अलग प्रश्न हैं।

पार्स सफल होने के बाद, अगली विफलता किसी बाद के चरण की होती है। भरोसा अस्वीकृति, उद्देश्य का बेमेल या कुंजी का बेमेल सहकर्मी या TLS परत बताती है, लोडर नहीं। उसी फ़ाइल को बार-बार बदलने से वह त्रुटि नहीं हटेगी।

जाँच के दौरान संवेदनशील आधे हिस्से को सार्वजनिक रिपोर्टों से बाहर रखें। निर्देशों के नाम, त्रुटि टेक्स्ट और ब्लॉक की संरचना साझा करें, कुंजी सामग्री और कोई भी पहचानने वाला पेलोड हटाकर। openvpn(8) मैनुअल फ़ाइल निर्देशों के दोनों रूपों और उनके पीछे के कार्यशील-निर्देशिका व्यवहार का दस्तावेज़ीकरण करता है।

संबंधित लेख