web-dev-qa-db-fra.com

Proxy_pass dynamique à $ var avec nginx 1.0

J'essaie de transmettre une requête par proxy à différentes cibles en fonction d'une variable d'environnement. Mon approche était de mettre l'URL cible dans la variable personnalisée $ target et de la donner à proxy_pass. 

Mais utiliser une variable avec proxy_pass ne semble pas fonctionner. Cette configuration simple conduit à une réponse "502 Bad Gateway" de 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;
  }
}

La même configuration sans la variable fonctionne:

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

Est-ce vraiment impossible d'utiliser proxy_pass de cette façon ou est-ce que je fais quelque chose de mal?

27
Sebastian Heuer

Je suis récemment tombé sur ce besoin moi-même et j'ai constaté que pour utiliser des variables dans une destination proxy_pass, vous devez définir un résolveur car votre error.log contiendrait probablement quelque chose comme no resolver defined to resolve ...

Dans mon cas, la solution consistait à configurer Google à l'aide de la résolution DNS:

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

Dans votre cas, cela devrait fonctionner:

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

Pour que le résolveur 127.0.0.1 fonctionne, vous devez installer bind9 localement . Pour Debian/Ubuntu:

Sudo apt-get install bind9

Plus d'informations sur nginx et le proxy_passing dynamique ici: http://www.nginx-discovery.com/2011/05/day-51-proxypass-and-resolver.html

Edit: Remplacé le précédent DNS public par un local pour la sécurité issues .

59
soulseekah

Même si la réponse de @soulseekah est complète et correcte, je souhaite envoyer une réponse aux personnes utilisant Nginx dans un groupe de conteneurs, à savoir ceux situés dans Kubernetes ou Docker Compose.

En gros, vous devez configurer un résolveur pour Nginx avec l’adresse de votre résolveur DNS actuel. Pour Docker, il s'agit de always at 127.0.0.11, pour Kubernetes, reportez-vous à this answer

À l'intérieur de mon réseau de stations de travail, j'ai réussi à configurer un proxy_pass dynamique en procédant ainsi:

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

Notez que il était fondamental d’ajouter le $uri$is_args$args, faute de quoi le passage du proxy ne prend pas en compte le chemin et la chaîne de requête.

PS: dans mon exemple, je lis un en-tête en utilisant la variable $http_XBackend. L'en-tête est passé par le client sous la forme XBackend: Host, ici la Host devrait être le nom d'hôte vers lequel vous souhaitez transférer vos appels. J'ai essayé d'utiliser des en-têtes avec des tirets sans succès, j'ai dû utiliser un en-tête sans tirets.

4
Naramsim

Nous sommes tombés sur le même problème

proxy_pass n'a pas résolu mes variables, jusqu'à ce que nous découvrions que notre serveur DNS avait un problème

peut être vérifié avec cette cmd par la voie 

nslookup your-domain your-dns-ip
0
user3400341