OpenVPN PHP हुक: trusted_ip बनाम ifconfig_pool_remote_ip
दो अलग अर्थों वाले दो पते, जिन्हें वह प्रक्रिया पढ़ती है जिसे आपने शुरू नहीं किया। हुक चर क्या हैं, और खाली $_ENV क्यों कुछ साबित नहीं करता।
हुक स्क्रिप्ट में खाली $_ENV सरणी इस बात का सबूत लगती है कि OpenVPN ने कुछ पास नहीं किया। आम तौर पर यह किसी बिल्कुल अलग बात का सबूत है: PHP इस तरह सेट था कि वह उस सुपरग्लोबल को न भरे, और मान पूरे समय प्रक्रिया के वातावरण में पड़े थे। दूसरा गलत निष्कर्ष अधिक सूक्ष्म है, क्योंकि कनेक्शन हुक में दो पता चर अलग बातें दर्शाते हैं और एक-दूसरे की जगह इस्तेमाल होते हैं। दोनों गलतियाँ एक दोपहर खा जाती हैं, अगर आप गलत से शुरू करें।
दो पते, दो अलग दावे
बाहरी छोर वह है जो सर्वर ने क्लाइंट के जुड़ने पर देखा, IPv4 के लिए trusted_ip और IPv6 के लिए trusted_ip6 के रूप में उपलब्ध। वर्चुअल पता वह है जो पूल ने इस सत्र के लिए आवंटित किया, ifconfig_pool_remote_ip के रूप में उपलब्ध।
वे अलग प्रश्नों का उत्तर देते हैं, और रिकॉर्ड को आम तौर पर दोनों की बजाय एक की ज़रूरत होती है। पहला यह है कि कनेक्शन कहाँ से आया, जो सैकड़ों लोगों द्वारा साझा किया गया NAT पता हो सकता है। दूसरा यह है कि यह सत्र टनल के भीतर कहाँ रहता है, और इसे बाद में किसी अन्य सत्र को फिर से आवंटित किया जा सकता है। दोनों को मिला देने से ऐसे रिकॉर्ड बनते हैं जो विश्वसनीय लगते हैं और गलत होते हैं।
न्यूनतम पढ़ाई ऐसी दिखती है।
$outer4 = getenv('trusted_ip');
$outer6 = getenv('trusted_ip6');
$inner = getenv('ifconfig_pool_remote_ip');
$outer = $outer4 !== false ? $outer4 : $outer6;दोनों में से कोई भी मान किसी व्यक्ति की पहचान नहीं करता। एक नेटवर्क अवलोकन है, दूसरा पट्टा है, और जो रिकॉर्ड किसी एक को स्थिर डिवाइस पहचानकर्ता मानता है वह पहली बार गलत होगा जब कोई क्लाइंट किसी दूसरे नेटवर्क से फिर जुड़े या दूसरा पूल पता पाए। रिकॉर्ड को जिस प्रश्न का उत्तर देना है उसके अनुसार फ़ील्ड चुनें, फिर वह प्रश्न स्तंभ के पास लिखें।
जाँचें कि PHP कैसे शुरू हुआ, अपना शेल नहीं
हुक VPN डेमन की संतान के रूप में उस वातावरण के साथ चलता है जो डेमन बनाता है। आपके इंटरैक्टिव शेल का वातावरण अलग है, और स्क्रिप्ट को हाथ से चलाना हुक के बजाय शेल के वातावरण की परीक्षा करता है।
पहले इस बात की पुष्टि करें कि हुक वास्तव में उसी चरण में सक्रिय हुआ जिसकी आपको अपेक्षा थी। गलत चरण से जुड़ी स्क्रिप्ट, या वह जो कभी नहीं चली क्योंकि निर्देश किसी दूसरे पथ की ओर इशारा करता है, ठीक वही लक्षण देती है जो अनुपस्थित चर देता है। स्क्रिप्ट के शीर्ष पर जानबूझकर एक मार्कर पंक्ति जोड़ें और कुछ और देखने से पहले पुष्टि करें कि वह दिखती है। लॉग में एक ही टाइमस्टैम्प वाली पंक्ति «कभी नहीं चली» को «मान के बिना चली» से अलग करती है।
फिर पुष्टि करें कि वह कॉल कौन-सा इंटरप्रेटर और कौन-सी कॉन्फ़िगरेशन फ़ाइल इस्तेमाल करती है। वेब सर्वर के लिए PHP कॉन्फ़िगरेशन बदलने से OpenVPN द्वारा शुरू की गई CLI प्रक्रिया में कुछ नहीं बदलता, और दोनों पूरी तरह अलग php.ini फ़ाइलें लोड कर सकते हैं।
खाली $_ENV क्यों कुछ साबित नहीं करता
PHP का getenv संदर्भ प्रक्रिया के वातावरण को सीधे पढ़ने का वर्णन करता है, जो नाम न होने पर false लौटाता है। $_ENV सुपरग्लोबल अलग से भरा जाता है, और variables_order निर्देश तय करता है कि कौन-से सुपरग्लोबल भरे जाएँगे।
अगर वह निर्देश E छोड़ देता है, तो वातावरण में जो भी हो $_ENV खाली रहता है। उसे इंडेक्स करने वाला कोड तब ऐसे अनुपस्थित चर की सूचना देता है जो वास्तव में मौजूद है, और जाँच OpenVPN की ओर बढ़ती है जबकि उत्तर php.ini में है। निर्देश को विशेष रूप से CLI कॉन्फ़िगरेशन के लिए जाँचें, वेब सर्वर के लिए नहीं।
getenv से पढ़ना इस पूरी भ्रम-श्रेणी से बचाता है, और इंटरप्रेटर को बुलाने से पहले वातावरण साफ़ करने वाली रैपर स्क्रिप्ट उसे दूसरे रूप में फिर ले आती है।
संबंध संग्रहित करें, पंक्ति अद्यतन नहीं
लिखने से पहले तय करें कि रिकॉर्ड को कौन-सा मान चाहिए। अगर उद्देश्य यह दर्ज करना है कि सत्र कहाँ से आया, तो बाहरी छोर संग्रहित करें और उसे अवलोकन के रूप में लेबल करें। अगर उद्देश्य किसी कनेक्शन की अवधि के लिए सत्र को टनल पते से जोड़ना है, तो पूल पता संग्रहित करें और उसे सत्र से जोड़ें।
टनल पता साझा करने वाली हर पंक्ति के अनुसार नहीं, बल्कि प्रमाणित पहचान और वर्तमान सत्र के अनुसार अद्यतन करें, क्योंकि पूल पते दोबारा उपयोग होते हैं और देर से आया डिस्कनेक्ट इवेंट अन्यथा नए कनेक्शन का डेटा मिटा सकता है। केवल IPv4 मान चुपचाप लिखने के बजाय IPv6 को स्पष्ट रूप से संभालें। NULL बाहरी पते वाली पंक्ति गलत पते वाली पंक्ति से बेहतर है, क्योंकि पहली स्पष्ट रूप से अधूरी है।
लेखन को OpenVPN द्वारा दिए गए सत्र पहचानकर्ता से जोड़ें ताकि फिर से जुड़ने पर पुराना संपादित होने के बजाय नया रिकॉर्ड बने। पैरामीटरीकृत कथन और केवल उन्हीं अनुमतियों वाला खाता इस्तेमाल करें जिनकी क्रिया को ज़रूरत है। हुक डेमन के अधिकार से चलता है, इसलिए लापरवाह क्वेरी गलत लॉग पंक्ति से बड़ी समस्या है।
वातावरण डंप किए बिना निदान करें
लॉग करें कि कौन-से नाम मौजूद थे, कौन-सा चरण चला और कौन-सा इंटरप्रेटर इस्तेमाल हुआ। पूरा वातावरण मुद्रित न करें, क्योंकि हुक प्रक्रिया असंबंधित मान विरासत में ले सकती है जो लॉग फ़ाइल में नहीं होने चाहिए।
एक कनेक्शन को शुरू से अंत तक सत्यापित करें: बाहरी छोर पढ़ें, आवंटित पता पढ़ें, और दोनों को उस सत्र पर सर्वर के अपने दृष्टिकोण के सामने पुष्ट करें। एक क्लाइंट के लिए जोड़ी की पुष्टि हो जाने के बाद, संबंध पर अन्यत्र भरोसा किया जा सकता है।