Reverseproxying sırasında memenin ana bilgisayar adını iletmek için nginx yapın


89

Ana bilgisayar adlarıyla birkaç liman işçisi konteynerini çalıştırıyorum:

web1.local web2.local web3.local

Bunlara nginx ile hostname bazında yönlendirme yapılır. Bu kurulumun önünde (internete bağlı farklı makinelerde) bir proxy'm var.

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

Ve gerçek sanal ana bilgisayar açıklaması:

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

Şimdi, kapsayıcılar "web1.local" yerine "main" ana bilgisayar adını aldıklarından, isteklere doğru yanıt vermiyorlar.

Soru: nginx'e, Host: upstream sunucu grubunun adı yerine giriş yukarı sunucunun adını iletmesini nasıl söyleyebilirim?


3
Yapabileceğini sanmıyorum. Neden arka uç sunucularınızı main veya example.com'a yanıt verecek şekilde ayarlamıyorsunuz? Arka uç kim olduğunu bilmiyor gibi değil . Tersi kolayca mümkündür: proxy_set_header Host $ host; Giriş akışından gelen herhangi bir Host değişkenini, orijinal istekten gelen hostname ile değiştirir
Andrew Domaszek

Yapılacak en uygun şey uygulamayı düzeltmektir.
Michael Hampton

Yanıtlar:


109

Aslında bunu proxy_set_header ile yapabilirsiniz.

Daha fazla ayrıntı için buraya bakınız : http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header veya burada örnek bir kullanım durumuna bakın: https://stackoverflow.com/questions/12847771/configure-nginx- -vekil-pass ile

Dinamik yaklaşımı yukarıda belirtilen yapılandırmanıza dahil ettim:

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;
  }
}

İşte statik bir ana bilgisayar adı ile bir örnek:

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
proxy_set_header X Forwarded-For $ proxy_add_x_forwarded_for; daha iyi görünüyor
sivann

1
@pavel: Anladım. Aslında bazı araştırmalar ve bazı testler yaptım. İhtiyaçlarınızı yerine getirmek için düz bir yaklaşım olmadığı görülüyor. Yani "bastarize" bir çözüm bile bir çözümdür. Bunu neden yapmak istediğini sormak istemiyorum. Sebeplerin olduğuna eminim. :-)
Jens Bradler

@JensBradler Benden daha uzman görünüyorsunuz, çözümüm hakkında ne düşündüğünüzü söyler misiniz? Ben İSS'me iki hesaplarından siteme iki kopyasını çalıştırmak çünkü aynı şeyi istiyorum: site1.myisp.comve site2.myisp.comve sadece kendi adına cevap. Şimdi, etki alanı adıma sahibim ve ISP web sitemi sunucularımı dengelemek için kullanmak istiyorum. Bu iyi bir sebep değil mi? Çok teşekkür ederim;)
ncenerar 20:14

1
@ ncenerar Bunu yapabilirsiniz ama bu sizi tek bir başarısızlık noktasına getirecektir: Yük dengeleyici. Eğer bu yük dengeleme için ise (artıklık değil) DNS tabanlı yük dengelemeyi DNS yerine çalışma ile birlikte de kullanabilirsiniz.
Jens Bradler

2
Bu cevap resmi blogun tavsiyesini yansıtmaktadır .
Bernard Rosset

28

Aynı sorunu yaşadım ve sonunda iki proxy seviyesi kullanarak çözdüm. Durumunuz için nasıl yapabileceğinizi aşağıda bulabilirsiniz (bence):

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;
  }
}

Gördüğünüz gibi, işin püf noktası, her bir sunucu için doğru ana bilgisayarı yeniden yazarak sunucuyu proxy yapacak belirli bir bağlantı noktasına yanıt veren yerel bir sunucu oluşturmaktır. Ardından, bu yerel sunucuları yukarı akışınızda kullanabilir ve son olarak da bu yukarı akışı gerçek vekilde kullanabilirsiniz.


Başlangıçta Lua yaklaşımını kullandım, ancak şimdi tamamen standart konfigürasyonda istediğimi yapmamı sağlayan HAProxy'e geçtim.
pavel_karoukin

3

Bu yüzden nginx için tüm belgeleri okumaktan (yukarı yöndeki modülün kodunu gerçekten çözümleyemedim = () Bu bastardizeli çözümle geldim. Ne yazık ki bu çözüm başarısız ana bilgisayarların kaydını tutmuyor, yalnızca rastgele birini seçip isteği yönlendiriyorsunuz. Bu yüzden, tüm arka uçların çalıştığından emin olmak için bir tür izlemem gerekiyor.

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

Yukarı akış adresinde bunun gibi ayrı bir başlık olarak geçiyoruz

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;
  }
}

Ya denedinse?

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;
  }
}



0

Diğer insanlar komut dosyası değişkeni ($ upstream gibi) kullanarak zaten yayınlandıkları gibi, ek başlık kesmeksizin bu sorunu istediğiniz şekilde ayarlayabilirsiniz ve bu sorunu çözecektir.

Proxy Geçiş işleyicisi tehdit komut dosyası değişkenleri, bir değer koşullu değilse (adında $ yoksa), yapılandırma aşamasında yukarı akış yönünde yedeklenir ve daha sonra kullanılır.

Bu sorunu atlamanın basit bir yolu ve (ücretsiz sürüm) giriş yönündeki en büyük avantajlara sahip olması aşağıdaki gibi bir şey kullanmak olacaktır 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;
}

Yukarıdaki örnek neredeyse yukarı akış ile aynı görünüyor. Eşleştirmeyi yapan başka modüller de var, yani chash_map_module , ancak ağaçtan çıktıkları için bunları kendi başınıza yapmanız gerekecektir, bu bazı kullanım durumları için mümkün değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.