हार्मोनल पवित्रवार व्यवस्थापक और डेवलपर PHP या REMOTE_ADDR बनाम HTTP_X_FORWARDED_FOR

हाल ही में, उन्होंने एक दिलचस्प बहस देखी कि वास्तव में PHP लिपियों से अंतिम उपयोगकर्ता के आईपी पते को निर्धारित करना कितना आवश्यक है।
दरअसल, विषय का प्रत्येक शब्द वास्तविक स्थिति को दर्शाता है। यह एक धार्मिक बहस थी, जो अद्भुत वसंत के मौसम से बढ़ी थी, जिसमें, मेरा मानना ​​है कि कोई सही और गलत नहीं थे, लेकिन जिसने मुझे थोड़ा शोध के लिए प्रेरित किया और मेरी खुशी के लिए, इस उलझन की समझ को समाप्त कर दिया, लेकिन वास्तव में एक बहुत ही सरल प्रश्न है।
उन लोगों के लिए, जिन्होंने मुझ पर शक किया , मुझे यकीन था कि मैंने इसे समझ लिया था, लेकिन बिल्ली के नीचे छोटी चीज़ों को समझने के लिए बहुत आलसी से पूछने से डरता था।


प्रागितिहास


सैमसंग स्मार्टटीवी प्लेटफॉर्म के लिए एक वीओडी सेवा विकसित करते समय, हमें निश्चित रूप से उपयोगकर्ता के देश को जानने की आवश्यकता है ताकि हम गलती से खुश उपयोगकर्ता को एक फिल्म न दिखाए जहां कॉपीराइट धारक मना करता है ... लेकिन इस अनुबंध अवधि के उल्लंघन में हजारों डॉलर में बच्चे का जुर्माना शामिल नहीं है (इसके लिए क्या होता है) निरीक्षण)।
[प्रश्न, जैसा कि टिप्पणियों में उल्लेख किया गया है, कानूनी है, और धोखाधड़ी संभव है, लेकिन लेख इस तरह के धोखाधड़ी को रोकने के लिए कैसे करें, लेकिन कैसे php और nginx के साथ दोस्तों को सही तरीके से बनाने के बारे में नहीं है]

सर्वर पर हमारे पास निम्नलिखित हैं: php-fpm + nginx

देश का निर्धारण कैसे करें? खैर, स्वाभाविक रूप से, उपयोगकर्ता के आईपी और GEO आईपी आधार मैक्समाइंड के माध्यम से
"पफ़्फ़ ...." - हम सभी ने मेरे लिए सोचा - लेकिन उतना ही सरल। और अपनी बाइक न लिखने के लिए, वह स्टैकओवरफ्लो पर googled , यहां तक ​​कि हर लाइन में डीलडाउन किया, उस पर स्क्रू किया और उसे वहीं छोड़ दिया और कोड बढ़ता गया:

public function getUserHostAddress(){ if (!empty($_SERVER['HTTP_X_REAL_IP'])) //check ip from share internet { $ip=$_SERVER['HTTP_X_REAL_IP']; } elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) //check ip from share internet { $ip=$_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) //to check ip is pass from proxy { $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; } else { $ip=$_SERVER['REMOTE_ADDR']; } return $ip; } 


और यह काम किया! लगभग एक साल ... जब तक कुछ अप्रत्याशित नहीं हुआ। स्वाभाविक रूप से इस कोड के लिए अप्रत्याशित ...

कैसे php या प्रॉक्सी श्रृंखला भ्रमित करने के लिए (अभी भी इतिहास का हिस्सा)


सब कुछ टूट गया है! और यह तब हुआ जब हमें भुगतान प्रणालियों में से एक को पेंच करना पड़ा और यह सब कोड क्रैश हो गया, क्योंकि एक पता HTTP_X_FORWARDED_FOR पर नहीं आया था, लेकिन अल्पविराम से अलग किए गए पते की एक सूची (जो कड़ाई से कानूनी, अनुमेय और php गोदी में विनियमित नहीं है)
अगर HTTP_X_REAL_IP या HTTP_CLIENT_IP (जो डॉक द्वारा भी विनियमित नहीं हैं) वांछित आईपी में सम्‍मिलित नहीं है, पर किसी ने कुछ भी नहीं देखा होगा, लेकिन अफसोस कि वे खाली थे :(

"ठीक है," हमें लगा (अब मैं अकेला नहीं था), सब कुछ फिर से लिखो और उपयोगकर्ता से IP को REMOTE_ADDR चर में धकेलने के लिए कहो:

  public function getUserHostAddress(){ $ip=$_SERVER['REMOTE_ADDR']; return $ip; } 


और यह काम किया! लगभग एक महीना ... जब तक कुछ अप्रत्याशित नहीं हुआ। स्वाभाविक रूप से इस कोड के लिए अप्रत्याशित ...

कठिन पुरुषों के वसंत तर्क (यह विडंबना नहीं है - वे शांत हैं)


सब कुछ टूट गया है! और यह इसलिए हुआ क्योंकि हमें nginx को अपडेट करने की आवश्यकता थी। और हमने इस मामले में पेशेवरों की ओर रुख किया - अपने प्रवेशकों के लिए।
और उन लोगों ने, रेमोटे_एडीडीआर को फॉरवर्ड करने के लिए कॉन्फिगरेशन को अपडेट करने और हमारी "बैसाखी / बैसाखी से छुटकारा" (जब तक हम इस बात को समझ नहीं पाए) से छुटकारा पाने का फैसला किया।

REMOTE_ADDR ने अपरिवर्तित छोड़ दिया अर्थात अब कुछ ऐसा है जैसे "127.0.0.1" चमक गया
HTTP_X_FORWARDED_FOR में उपयोगकर्ता का IP स्कैम किया गया था (जो इस बीच, ब्राउज़र से हेडर `x-फॉरवर्डेड-फॉर: 999.999.999.999` भेजकर आसानी से ओवरराइड कर लिया गया था)
और फिर यह शुरू हुआ - पी = डेवलप, ए = एडमिन:

A: आपके लिए सब कुछ टूट गया, और चूंकि हमारे पास एक nginx प्रॉक्सी है, तो आपको जिस पते की आवश्यकता है वह HTTP_X_FORWARDED_FOR में है और REMOTE_ADDR में क्लाइंट के लिए php-fpm का वास्तविक IP पता स्थित होगा (अर्थात 127.0.0.1)
R: लेकिन हम HTTP_X_FORWARDED_FOR पर विश्वास नहीं कर सकते हैं, क्योंकि यह एक ऐसा चर है जिसे हेडर के माध्यम से सर्वर पर आसानी से पुनः परिभाषित किया जा सकता है, बल्कि एक दिलचस्प लेख का हवाला देते हुए।
A: नहीं, हम इसे अंतिम उपयोगकर्ता का वास्तविक IP बना देंगे, और REMOTE_ADDR में php के लिए वास्तविक ग्राहक पता
आर: तो हम परदे के पीछे के अनुक्रम का पालन नहीं करेंगे, और फिर भी एक और सर्वर पर सार्वभौमिकरण के लिए (एक प्रॉक्सी के बिना कहें) ये कॉन्फ़िगरेशन REMOTE_ADDR में सब कुछ सच नहीं हो सकता है जो वैसे भी काम करेगा।

... यह संक्षिप्त और मैट के बिना है ...

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

किसे दोष देना है, किसे सही है


यह हमारे लिए न्याय करने के लिए नहीं है, लेकिन कोई भी नहीं!

अगर हमारे पास वास्तव में php, या पारदर्शी समीपता के लिए सीधे ग्राहकों का एक समूह है, तो सब कुछ सरल है - स्वास्थ्य और आनंद के लिए REMOTE_ADDR का उपयोग करें।

लेकिन फैनिंग के बारे में क्या है और यह कहाँ होना चाहिए अगर हम सामान्य प्रॉक्सिंग का उपयोग करते हैं और चाहते हैं कि PHP इसके बारे में जाने?

नुस्खा ... लेकिन रामबाण नहीं:



निष्कर्ष में


Php + nginx के लिए कई प्रॉक्सी विकल्प हैं


पुनश्च
बाद में हम सेटिंग्स में फेंग शुई डालेंगे और पारदर्शी प्रॉक्सी से छुटकारा पाएंगे, साथ ही दोनों प्रॉक्सी मामलों के लिए आईपी का निर्धारण करने के लिए एक सार्वभौमिक फ़ंक्शन लिखेंगे।

पी पी एस
मज़े के लिए, कौन परवाह करता है: अगर कोई टिप्पणी करता है तो यह फ़ंक्शन लिखता है और नग्नेक्स कॉन्फ़िगरेशन हमारे लिए है और हम इसका उपयोग करेंगे, फिर ईमानदारी से, उसे फोन पर 100 रूबल मिलेंगे।
लेकिन यह फ़ंक्शन और कॉन्फ़िगरेशन वास्तव में रूढ़िवादी होना चाहिए और सब कुछ पर विचार करना चाहिए :) सभी सुराग लेख में हैं।
मुख्य बात ज़ेन है: अपना समय ले लो - अचानक पहले वाले त्रुटियों के साथ लिखेंगे और आप उन्हें ध्यान में रखेंगे, जल्दी करो - अचानक पहला सही जवाब आपके ऊपर होगा।

आप सभी को धन्यवाद। एक अच्छा वसंत है! सहकर्मियों के साथ व्यवस्था करें और उन्हें प्यार करें! :)

यूडीपी:
खुद का कार्यान्वयन:
  /** * @param null|string $ip_param_name -   _SERVER,     IP  *       REMOTE_ADDR       , *     IP    , *    HTTP_X_REAL_IP    * @param bool $allow_non_trusted - ,   $ip_param_name  *      _SERVER[$ip_param_name] *      _SERVER     $non_trusted_param_names * @param array $non_trusted_param_names -  ,     IP   _SERVER * @throws Exception * @return string */ public function getUserHostAddress( $ip_param_name = null, $allow_non_trusted = false, array $non_trusted_param_names = array('HTTP_X_REAL_IP','HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','REMOTE_ADDR') ){ if(empty($ip_param_name) || !is_string($ip_param_name)){ //       $ip = $_SERVER['REMOTE_ADDR']; }else{ //    if(!empty($_SERVER[$ip_param_name]) && filter_var($_SERVER[$ip_param_name], FILTER_VALIDATE_IP)){ //      $ip = $_SERVER[$ip_param_name]; }else if($allow_non_trusted){ //           foreach($non_trusted_param_names as $ip_param_name_nt){ if($ip_param_name === $ip_param_name_nt) //      continue; if(!empty($_SERVER[$ip_param_name_nt]) && filter_var($_SERVER[$ip_param_name_nt], FILTER_VALIDATE_IP)){ //      $ip = $_SERVER[$ip_param_name_nt]; break; } } } } if(empty($ip)) //      ip,     $_SERVER['REMOTE_ADDR'] -   throw new Exception("Can't detect IP"); return $ip; } 

Source: https://habr.com/ru/post/In177113/


All Articles