सवाल प्रॉक्सी के माध्यम से Nginx रीडायरेक्ट, पुनर्लेखन और यूआरएल संरक्षित करें


Nginx में हम एक यूआरएल को निम्नानुसार रीडायरेक्ट करने का प्रयास कर रहे हैं:

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

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

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

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

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

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

    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


63
2018-04-04 00:49


मूल




जवाब:


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

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

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

यह / some / path / के बाद और index.html से पहले $ अनुभाग चर के बाद भाग को कैप्चर करता है, जिसका उपयोग proxy_pass गंतव्य को सेट करने के लिए किया जाता है। यदि आपको आवश्यकता हो तो आप रेगेक्स को अधिक विशिष्ट बना सकते हैं।


54
2018-04-04 05:24



देर से उत्तर के लिए माफ़ी - यह है इसलिए जो हम खोज रहे हैं उसे प्राप्त करने के करीब। एकमात्र कमी यह है कि, एक बार लक्ष्य पृष्ठ परोसने के बाद, ब्राउज़र में लिंक के लिए URL में '/ some / path /' शामिल नहीं होता है, जिसका अर्थ है कि यदि उपयोगकर्ता उस पर क्लिक करता है तो वे काम नहीं करते हैं। यदि हम इस बात को दूर करने के लिए काम कर सकते हैं कि मैं इस जवाब को अपडेट और स्वीकार करूँगा, क्योंकि यह लगभग इतना है। - robjohncox
ब्राउज़र देखे गए लिंक 1 9 2.168.1.24 सर्वर पर चल रहे सॉफ़्टवेयर द्वारा जेनरेट किए गए लिंक हैं। आप जो चाहते हैं उसे प्राप्त करने के लिए आपको उस सॉफ़्टवेयर को संशोधित करना चाहिए। - Tero Kilkanen
सुनिश्चित नहीं है कि मैं स्थान ब्लॉक के अंदर रूट के बारे में आपकी चेतावनी का पालन करता हूं। nginx दस्तावेज पढ़ना यह सामान करने का सही तरीका है। वे केवल खराब परिस्थितियों को चेतावनी देते हैं कि सभी स्थानों के बाहर डिफ़ॉल्ट रूट न हो। nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/... - guy mograbi
खैर, अंगूठे का नियम उपयोग करना आसान नहीं है root ए के अंदर location ब्लॉक, तो आपको डिफ़ॉल्ट स्थानों के लिए कोई अप्रत्याशित व्यवहार नहीं मिलेगा। केवल तभी आपको डिफ़ॉल्ट को बदलने की जरूरत है root प्रत्येक स्थान के लिए, आप इसका उपयोग कर सकते हैं। - Tero Kilkanen
आपका क्या मतलब है नाम के रूप में $ होस्ट प्राप्त करता है? भेजा गया सटीक HTTP शीर्षलेख क्या है और आप इसे वास्तव में क्या भेजना चाहते हैं? - Tero Kilkanen


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

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

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

56
2018-04-04 06:17



देर से उत्तर के लिए माफ़ी - मैंने इसे आजमाया और दुर्भाग्य से यह हमारे उपयोग-मामले के लिए काम नहीं करता है। मुद्दा यह है कि, जब लक्ष्य सर्वर पर अनुरोध किया जाता है, तो /some/path/ यूआरएल का हिस्सा अनुरोध में संरक्षित है जो वैध यूआरएल नहीं है (हमें इसे हटाने के लिए यूआरएल को फिर से लिखना होगा)। - robjohncox
@robjohncox आपने वास्तव में क्या प्रयास किया? - Alexey Ten
स्लैश ने मेरे लिए चाल बनाई। अब mydomain.com/some/path/* को सही ढंग से 1 9 2.168.1.24/* पर प्रॉक्सी किया गया है और नहीं 1 9 2.168.1.24/some/path/* - Vadimo
क्या मैं इस प्रतिक्रिया में "# इस स्लैश" टिप्पणी को ऊपर उठा सकता हूं? उस टिप्पणी के लिए तीन चीयर्स! - 8one6
सुनिश्चित नहीं है कि यह आप सभी के लिए कैसे काम कर रहा है। यह मैं क्या हासिल करने की कोशिश कर रहा हूँ। हालांकि, जब कोई उपयोगकर्ता उस लिंक पर क्लिक करता है जो रीडायरेक्ट करेगा स्थानीय सेवा पर 192.168.1.24/login तक, उसे mydomain.com/some/path/login के बजाय mydomain.com/login पर रीडायरेक्ट किया गया है - mueslo


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

ध्यान दें कि अब तक यह एकमात्र उत्तर है जो निर्बाध रूप से उत्पन्न होने वाले पूर्ण पथों का ख्याल रखेगा 404 Not Found त्रुटियां, बशर्ते कि सही HTTP Referer हेडर ब्राउज़र द्वारा भेजा जाता है, इसलिए, उन सभी gifs को अंतर्निहित 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

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

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

संदर्भ:


2
2017-08-27 03:42





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

proxy_pass          http://localhost:8080/;

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

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

proxy_pass          http://localhost:8080;

1
2018-05-04 15:44