प्रॉक्सी, रीराइट और संरक्षित URL के माध्यम से नगनेक्स रीडायरेक्ट


71

Nginx में हम निम्नानुसार एक URL को पुनर्निर्देशित करने का प्रयास कर रहे हैं:

http://example.com/some/path -> http://192.168.1.24

जहाँ उपयोगकर्ता अभी भी अपने ब्राउज़र में मूल URL देखता है। एक बार जब उपयोगकर्ता पुनर्निर्देशित हो जाता है, तो कहें कि वे लिंक पर क्लिक करते हैं /section/index.html, हम चाहते हैं कि यह एक अनुरोध करे जिससे रीडायरेक्ट हो सके

http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html

और फिर भी मूल URL को सुरक्षित रखें।

हमारे प्रयासों में परदे के पीछे और नियमों का उपयोग करते हुए विभिन्न समाधान शामिल हैं, और नीचे कॉन्फ़िगरेशन हमें दिखाता है कि हमें एक समाधान के सबसे करीब लाया गया है (ध्यान दें कि यह वेब सर्वर के लिए वेब सर्वर कॉन्फ़िगरेशन example.comहै)। हालाँकि, इसके साथ अभी भी दो समस्याएं हैं:

  • यह फिर से लिखना ठीक से नहीं करता है, http://192.168.1.24जिसमें वेब सर्वर द्वारा प्राप्त अनुरोध URL शामिल है /some/pathऔर इसलिए आवश्यक पृष्ठ की सेवा करने में विफल रहता है।
  • जब आप किसी लिंक को एक बार पृष्ठ परोसने के बाद होवर करते हैं, तो वह /some/pathURL से गायब होता है

    server {
        listen          80;
        server_name     www.example.com;
    
        location /some/path/ {
            proxy_pass http://192.168.1.24;
            proxy_redirect http://www.example.com/some/path http://192.168.1.24;
            proxy_set_header Host $host;
        }
    
        location / {
            index index.html;
            root  /var/www/example.com/htdocs;
        }
    }
    

हम एक समाधान की तलाश कर रहे हैं जिसमें केवल वेब सर्वर कॉन्फ़िगरेशन को बदलना शामिल है example.com। हम 192.168.1.24(भी Nginx) पर कॉन्फिग को बदलने में सक्षम हैं , हालांकि हम इसे टालना चाहते हैं और इससे बचना चाहते हैं क्योंकि हमें सैकड़ों अलग-अलग सर्वरों के लिए इस सेटअप को दोहराना होगा, जिनकी पहुंच अनुमानित है example.com

जवाबों:


59

सबसे पहले, आपको rootस्थान ब्लॉक के अंदर निर्देश का उपयोग नहीं करना चाहिए , यह एक बुरा अभ्यास है। इस मामले में हालांकि यह कोई फर्क नहीं पड़ता।

दूसरा स्थान ब्लॉक जोड़ने का प्रयास करें:

location ~ /some/path/(?<section>.+)/index.html {
    proxy_pass http://192.168.1.24/$section/index.html;
    proxy_set_header Host $host;
}

यह $ अनुभाग खंड के लिए / कुछ / पथ / और index.html से पहले भाग को कैप्चर करता है, जो तब प्रॉक्सी_पास गंतव्य को सेट करने के लिए उपयोग किया जाता है। आप आवश्यकता होने पर रेगेक्स को अधिक विशिष्ट बना सकते हैं।


1
देर से जवाब के लिए माफी - यह हम जो खोज रहे हैं उसे प्राप्त करने के बहुत करीब है। एकमात्र कमी यह है कि, एक बार लक्ष्य पृष्ठ पर काम कर लेने के बाद, ब्राउज़र में लिंक के लिए URL में '/ / कुछ / पथ /' शामिल नहीं होते हैं, जिसका अर्थ है कि यदि उपयोगकर्ता उन पर क्लिक नहीं करता है तो वे काम नहीं करते हैं। अगर हम इस पर काबू पाने के लिए काम कर सकते हैं तो मैं इस उत्तर को अपडेट करूँगा और स्वीकार करूँगा, क्योंकि यह लगभग वहाँ है।
रोबजेनकोक्स

8
ब्राउज़र द्वारा देखे जाने वाले लिंक 192.168.1.24 सर्वर पर चल रहे सॉफ़्टवेयर द्वारा उत्पन्न होते हैं। आप जो चाहते हैं उसे प्राप्त करने के लिए आपको उस सॉफ़्टवेयर को संशोधित करना चाहिए।
टेरो किलकेनेन

सुनिश्चित नहीं है कि मैं स्थान ब्लॉक के अंदर रूट के बारे में आपकी चेतावनी का पालन करता हूं। nginx प्रलेखन पढ़ना यह सामान करने का सही तरीका है। वे केवल सभी स्थानों के बाहर डिफ़ॉल्ट रूट नहीं होने से बुरे अभ्यास की चेतावनी देते हैं। nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
पुरुष मोगरेबी

खैर, अंगूठे का एक नियम है कि rootएक locationब्लॉक के अंदर उपयोग न करना आसान है , फिर आपको डिफ़ॉल्ट स्थानों के लिए कोई अप्रत्याशित व्यवहार नहीं मिलेगा। केवल अगर आपको rootप्रत्येक स्थान के लिए डिफ़ॉल्ट बदलने की आवश्यकता है , तो आप इसका उपयोग कर सकते हैं।
तेरो किलकेनेन

1
नाम के रूप में $ होस्ट प्राप्त करने से आपका क्या मतलब है ? सटीक HTTP हेडर क्या है जो भेजा गया था और आप वास्तव में क्या भेजना चाहते हैं?
तेरो किलकेनेन

65

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

इस मामले में आपका locationब्लॉक वास्तव में सरल हो सकता है:

location /some/path/ {
    proxy_pass http://192.168.1.24/;
    # note this slash  -----------^
    proxy_set_header Host $host;
}

1
देर से जवाब के लिए माफी - मैंने इसे आज़माया और दुर्भाग्य से यह हमारे उपयोग-मामले के लिए काम नहीं करता है। मुद्दा यह है कि, जब अनुरोध को लक्ष्य सर्वर पर किया जाता है, तो /some/path/URL का हिस्सा अनुरोध में संरक्षित होता है जो एक मान्य URL नहीं है (हमें इसे हटाने के लिए URL को फिर से लिखना होगा)।
रोबजेनकोक्स

@robjohncox वास्तव में आपने क्या प्रयास किया?
एलेक्सी टेन

9
स्लेश ने मेरे लिए चाल चली। अब mydomain.com/some/path/* को 192.168.1.24/* पर सही ढंग से
सम्‍मिलित किया गया है

7
क्या मैं इस प्रतिक्रिया में "# नोट इस स्लेश" टिप्पणी को बढ़ा सकता हूं? उस टिप्पणी के लिए तीन चीयर्स!
8one6

यकीन नहीं होता कि यह आप सभी के लिए कैसे काम कर रहा है। यही मैं हासिल करने की कोशिश कर रहा हूं। हालांकि, जब कोई उपयोगकर्ता किसी लिंक है कि स्थानीय सेवा पर 192.168.1.24/login को जैसे अनुप्रेषित होगा क्लिक करता है, वह mydomain.com/some/path/login के बजाय mydomain.com/login पर भेज दिया जाएगा
mueslo

4

आप /some/path/फ्रंट-एंड /पर और बैकएंड पर 100% सीमलेस मैपिंग करने के लिए निम्न कॉन्फिगर का उपयोग कर सकते हैं ।

ध्यान दें कि यह अब तक का एकमात्र उत्तर है, जो मूल रूप से 404 Not Foundत्रुटियों को उत्पन्न करने वाले पूर्ण पथों का भी ध्यान रखेगा , बशर्ते कि सही HTTP Refererशीर्ष लेख ब्राउज़र द्वारा भेजा गया हो, इसलिए, उन सभी gif को अंतर्निहित HTML को संशोधित करने की आवश्यकता के बिना लोड करना जारी रखना चाहिए। (जो न केवल महंगा है, बल्कि अतिरिक्त मॉड्यूल के बिना भी समर्थित नहीं है जो डिफ़ॉल्ट रूप से संकलित नहीं है)।

location /some/path/ {
    proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
    error_page 404 = @404;
    return 404; # this would normally be `try_files` first
}
location @404 {
    add_header Vary Referer; # sadly, no effect on 404
    if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
        return 302 $1$uri;
    }
    return 404 "Not Found\n";
}

आप https://github.com/cnst/StackOverflow.cnst.nginx.conf रिपॉजिटरी के भीतर पूर्ण प्रमाण-की-अवधारणा और न्यूनतम-व्यवहार्य-उत्पाद पा सकते हैं ।

यहां यह पुष्टि करने के लिए परीक्षण चल रहा है कि सभी किनारे मामले काम करने लगते हैं:

curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer

curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found

curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri:    /and/more.gif

पुनश्च आप अलग अलग रास्तों का एक बहुत मैप करने के लिए है, तो के बजाय एक regex तुलना करने का $http_refererएक के भीतर ifके भीतर location @404, आप वैश्विक आधारित का उपयोग करना चाहें mapबजाय निर्देश।

यह भी ध्यान दें कि दोनों में अनुगामी स्लैश proxy_pass, साथ ही साथ locationयह निहित है, संबंधित उत्तर के अनुसार काफी महत्वपूर्ण हैं

संदर्भ:


2

जब उस स्लैश को एक नगनेक्स समीपस्थ जेनकींस में जोड़ा जाता है, तो आपको "यह प्रतीत होता है कि आपका रिवर्स प्रॉक्सी सेट टूटा हुआ है" त्रुटि के साथ प्रस्तुत किया गया है।

proxy_pass          http://localhost:8080/;

Remove this -----------------------------^

इसे पढ़ना चाहिए

proxy_pass          http://localhost:8080;

मुझे नहीं लगता कि यह ओपी का प्रश्न था और न ही उल्लेखित मुद्दों में से किसी को हल करता था।
कोरी रॉबिन्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.