उल्टा होने पर अपस्ट्रीम के होस्टनाम को पास करने के लिए नेग्नेक्स बनाएं


89

मैं होस्टनाम के साथ कई डॉकटर कंटेनर चलाता हूं:

web1.local web2.local web3.local

इनको रूटिंग, होस्टेज के आधार पर nginx द्वारा किया जाता है। मेरे पास इस सेटअप के सामने एक प्रॉक्सी है (इंटरनेट से जुड़ी विभिन्न मशीन पर) जहां मैं अपस्ट्रीम को परिभाषित करता हूं:

    upstream main {
      server web1.local:80;
      server web2.local:80;
      server web3.local:80;
    }

और वास्तविक आभासी मेजबान विवरण:

    server {
      listen 80;
      server_name example.com;
      location / {
        proxy_pass http://main;
      }
    }

अब, क्योंकि कंटेनर "web1.local" के बजाय होस्टनाम "मुख्य" प्राप्त करते हैं, वे अनुरोध का ठीक से जवाब नहीं देते हैं।

प्रश्न: मैं होस्ट में सर्वरों के अपस्ट्रीम समूह के नाम के बजाय अपस्ट्रीम सर्वर का नाम कैसे पास कर सकता हूं?


3
मुझे नहीं लगता कि आप कर सकते हैं। आप मुख्य या example.com पर प्रतिक्रिया देने के लिए अपने बैकेंड सर्वर क्यों सेट नहीं करते हैं? ऐसा नहीं है कि बैकएंड पता नहीं है कि यह कौन है। रिवर्स आसानी से संभव है: प्रॉक्सी_सेट_हेडर होस्ट $ होस्ट; मूल अनुरोध से होस्टनाम के साथ अपस्ट्रीम से वापस आने वाले किसी भी होस्ट चर की जगह लेगा।
एंड्रयू डॉमासेक

आवेदन को ठीक करना उचित है।
माइकल हैम्पटन

जवाबों:


109

वास्तव में आप ऐसा प्रॉक्सी_सेट_हीडर के माध्यम से कर सकते हैं।

अधिक जानकारी के लिए यहां देखें : http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header या यहां एक उदाहरण उपयोग-मामला देखें : https://stackover.com/questions/12847771/configure-nginx- साथ-प्रॉक्सी-पास

मैंने आपके ऊपर पोस्ट किए गए कॉन्फ़िगरेशन में गतिशील दृष्टिकोण को शामिल किया है:

server {
  listen 80;
  server_name example.com;
  location / {
    proxy_pass       http://main;
    proxy_set_header Host            $host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

यहाँ स्थैतिक होस्ट नाम के साथ एक उदाहरण दिया गया है:

server {
  listen 80;
  server_name example.com;
  location / {
    proxy_pass       http://main;
    proxy_set_header Host            www.example.com;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

7
प्रॉक्सी_सेट_हाइडर एक्स-फॉरवर्डेड-फॉर $ प्रॉक्सी_एड_एक्स_फोवर्डवर्ड_फोर्स; बेहतर लगता है
सिवन

1
@ तिरछा: मिल गया। वास्तव में मैंने कुछ शोध और कुछ परीक्षण भी किए। ऐसा लगता है कि आपकी आवश्यकता को पूरा करने के लिए कोई सीधा दृष्टिकोण नहीं है। तो एक "कमीने" समाधान भी एक समाधान है। मुझे यह पूछना पसंद नहीं है कि आप ऐसा क्यों करना चाहते हैं। मुझे पूरा यकीन है कि आपके पास अपने कारण हैं। :-)
जेन्स ब्रैडलर

@JensBradler आप मुझसे अधिक विशेषज्ञ लगते हैं, तो क्या आप मुझे बता सकते हैं कि आप मेरे समाधान के बारे में क्या सोचते हैं? मैं क्योंकि मैं अपने आईएसपी पर दो खातों से मेरी वेबसाइट की दो प्रतियां चलाने यही कार्य करना: site1.myisp.comऔर site2.myisp.comऔर वे केवल अपने-अपने नाम करने के लिए जवाब। मैं, अब, अपने डोमेन नाम का मालिक हूं और अपने सर्वर को संतुलित करने के लिए अपनी आईएसपी वेबसाइट का उपयोग करना चाहता हूं। यह एक अच्छा कारण नहीं है? बहुत बहुत धन्यवाद;)
ncenerar

1
@ncenerar आप ऐसा कर सकते हैं लेकिन यह आपको विफलता के एक बिंदु पर लाएगा: लोड बैलेंसर। यदि यह लोड संतुलन (अतिरेक नहीं) के लिए है, तो आप DNS विफलता के साथ संयोजन में DNS आधारित लोड संतुलन का भी उपयोग कर सकते हैं।
जेन्स ब्रैडलर

2
यह उत्तर आधिकारिक ब्लॉग की सलाह को दर्शाता है ।
बर्नार्ड रॉसैट

28

मुझे भी यही समस्या थी और मैंने आखिरकार प्रॉक्सी के दो स्तरों का उपयोग करके इसे हल किया। यहाँ है कि आप अपनी स्थिति के लिए कैसे कर सकते हैं (मुझे लगता है):

server {
  listen      8001 default_server;
  server_name web1.example.com;
  location / {
    proxy_pass       http://web1.local:80;
    proxy_set_header Host web1.local:80;
  }
}

server {
  listen      8002 default_server;
  server_name web2.example.com;
  location / {
    proxy_pass       http://web2.local:80;
    proxy_set_header Host web2.local:80;
  }
}

server {
  listen      8003 default_server;
  server_name web3.example.com;
  location / {
    proxy_pass       http://web3.local:80;
    proxy_set_header Host web3.local:80;
  }
}

upstream main {
  server 127.0.0.1:8001;
  server 127.0.0.1:8002;
  server 127.0.0.1:8003;
}

server {
  listen      80;
  server_name example.com;
  location / {
    proxy_pass http://main;
  }
}

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


मैंने मूल रूप से लुआ दृष्टिकोण का उपयोग किया था, लेकिन अब पूरी तरह से HAProxy पर स्विच कर दिया गया है जो मानक विन्यास के साथ बस वही करना चाहता है जो मैं चाहता था।
पावेल_कर्किन

3

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

server {
        listen 80;
        server_name example.com;
        resolver 127.0.0.1;

        location / {
                set $upstream "";
                rewrite_by_lua '
                        local upstreams = {
                                "http://web1.dokku.localdomain",
                                "http://web2.dokku.localdomain",
                                "http://web3.dokku.localdomain",
                                "http://web4.dokku.localdomain"
                        }
                        ngx.var.upstream = upstreams[ math.random( #upstreams ) ] 
                ';
                proxy_pass $upstream;
        }
}

2

हम इस तरह से एक अलग हेडर के रूप में अपस्ट्रीम एडियर में पास होते हैं

server {
  listen 80;
  server_name example.com;
  location / {
    proxy_pass       http://main;
    proxy_set_header Host            $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    add_header       X-Upstream      $upstream_addr;
  }
}

अगर आपने कोशिश की तो क्या होगा?

server {
  listen 80;
  server_name example.com;
  location / {
    proxy_pass       http://main;
    proxy_set_header Host            $upstream_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    add_header       X-Host          $host;
  }
}

2

जबकि लक्ष्य तर्कसंगत लगता है, nginx मेजबान को बदलने के लिए नहीं जा रहा है: हेडर अपस्ट्रीम से मेल करने के लिए । इसके बजाय, यह DNS में upstreamडोमेन नामों की तरह व्यवहार करता है CNAME- एक आईपी पते पर पहुंचने के तरीके के रूप में।

अपस्ट्रीम के चयन से पहले अनुरोध हेडर (और बॉडी) तय किए जाते हैं। यदि कोई विशेष अपस्ट्रीम पाया जाता है तो अपस्ट्रीम मध्य-अनुरोध को बदल सकता है, लेकिन अनुरोध परिवर्तित नहीं होता है।


0

हम्म। मेरे पास एक समान सेटअप है, जिसमें मैंने बस किया है

location / {
    ... 
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_pass ...;
}

के उपयोग $http_host(आवक अनुरोध से HTTP होस्ट हेडर) यहाँ के बजाय $host(सर्वर होस्टनाम विन्यास) एक ही होस्ट हैडर ग्राहक द्वारा पारित कर दिया, नदी के ऊपर करने के लिए पारित किया जा करने के लिए अपने परीक्षण में कारण बनता है।

Https://stackoverflow.com/questions/14352690/change-host-header-in-nginx-reverse-proxy भी देखें


0

जैसा कि अन्य लोग पहले से ही स्क्रिप्ट चर (जैसे $ अपस्ट्रीम) का उपयोग करके पोस्ट करते हैं, आप इसे वैसे भी सेट कर सकते हैं जैसे आप चाहते हैं, और यह समस्या को ठीक कर देगा, बिना अतिरिक्त हेडर हैकिंग के।

प्रॉक्सी पास हैंडलर एक अलग तरीके से स्क्रिप्ट चर को धमकी देता है, यदि कोई मान सशर्त नहीं है (नाम में $ नहीं है) कॉन्फ़िगरेशन चरण पर अपस्ट्रीम का समर्थन किया जाता है और बाद में उपयोग करता है।

इस मुद्दे को छोड़ देने का एक सरल तरीका है, और (फ्री संस्करण) अपस्ट्रीम के सबसे अधिक फायदे कुछ इस तरह से होंगे Split_Clients:

split_clients $request_uri $my_upstream {
              33%          server1.domainX.com;
              33%          server2.domainX.com;
# Always use DOT at end entry if you wonder why, read the SC code.
              *            server3.domainX.com;  
}
location / {
    ... 
    proxy_pass http://$my_upstream;
}

उपरोक्त उदाहरण लगभग ऊपर जैसा दिखता है। अन्य मॉड्यूल मौजूद हैं जो मैपिंग करते हैं, अर्थात chash_map_module , लेकिन जब वे पेड़ से बाहर होते हैं, तो आपको उन्हें अपने द्वारा बनाने की आवश्यकता होगी, जो कुछ उपयोग-मामलों के लिए संभव नहीं है /

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