it-swarm.com.de

Dynamischer Proxy-Pass zu $ ​​var mit Nginx 1.0

Ich versuche, eine Anforderung an verschiedene Ziele abhängig von einer Umgebungsvariablen zu übergeben. Mein Ansatz bestand darin, die Ziel-URL in die benutzerdefinierte Variable $ target zu setzen und diese an proxy_pass zu übergeben. 

Die Verwendung einer Variablen mit proxy_pass scheint jedoch nicht zu funktionieren. Diese einfache Konfiguration führt zu einer Antwort "502 Bad Gateway" von nginx.

server {
  listen   8080;
  server_name  myhost.example.com;
  access_log  /var/log/nginx/myhost.access.log;
  location /proxy {
    set $target http://proxytarget.example.com;
    proxy_pass $target;
  }
}

Die gleiche Konfiguration ohne die Variable funktioniert:

server {
  listen   8080;
  server_name  myhost.example.com;
  access_log  /var/log/nginx/myhost.access.log;
  location /proxy {
    proxy_pass http://proxytarget.example.com;
  }
}

Ist es wirklich nicht möglich, proxy_pass auf diese Weise zu verwenden, oder mache ich nur etwas falsch?

27
Sebastian Heuer

Ich bin vor kurzem über dieses Bedürfnis selbst gestolpert und habe festgestellt, dass Sie zur Verwendung von Variablen in einem Proxy_Pass-Ziel einen Resolver festlegen müssen, da Ihr error.log höchstwahrscheinlich etwas wie no resolver defined to resolve ...

In meinem Fall bestand die Lösung darin, Folgendes mit Google für die DNS-Auflösung einzurichten:

location ~ /proxy/(.*) {
    resolver 127.0.0.1 [::1];
    proxy_pass http://$1;
}

In Ihrem Fall sollte dies funktionieren:

location /proxy {
    resolver 127.0.0.1 [::1];
    set $target http://proxytarget.example.com;
    proxy_pass $target;
}

Damit der Resolver 127.0.0.1 funktioniert, müssen Sie bind9 lokal installieren. Für Debian/Ubuntu:

Sudo apt-get install bind9

Weitere Informationen zu Nginx und dynamischem proxy_passing hier: http://www.nginx-discovery.com/2011/05/day-51-proxypass-and-resolver.html

Edit: Ersetzte den vorherigen öffentlichen DNS durch einen lokalen für Sicherheit issues .

59
soulseekah

Auch wenn die Antwort von @soulseekah vollständig und richtig ist, möchte ich eine Antwort für die Leute posten, die Nginx in einem Cluster von Containern verwenden, die in Kubernetes oder Docker Compose enthalten sind.

Grundsätzlich müssen Sie einen Resolver für Nginx mit der Adresse Ihres aktuellen DNS-Resolvers konfigurieren. Für Docker ist es immer bei 127.0.0.11, für Kubernetes beziehen sich auf diese Antwort

In meinem Docker-Netzwerk konnte ich erfolgreich einen dynamischen proxy_pass konfigurieren:

resolver 127.0.0.11 [::1];
set $bcknd http://$http_XBackend$uri$is_args$args;
proxy_pass        $bcknd;

Beachten Sie, dass war von grundlegender Bedeutung , um den $uri$is_args$args hinzuzufügen, da der Proxy-Pass andernfalls den Pfad und die Querzeichenfolge nicht berücksichtigt.

PS: In meinem Beispiel lese ich einen Header mit der Variable $http_XBackend. Der Header wird vom Client als XBackend: Host übergeben. Hier sollte Host der Hostname sein, an den Sie Ihre Anrufe weiterleiten möchten. Ich habe versucht, Kopfzeilen ohne Striche zu verwenden. Ich musste einen Kopf ohne Striche verwenden.

4
Naramsim

Stolperte über dasselbe Problem

proxy_pass löste meine Variablen nicht, bis wir herausfanden, dass unser DNS-Server ein Problem hatte

kann übrigens mit diesem cmd überprüft werden 

nslookup your-domain your-dns-ip
0
user3400341