So bewahren Sie die Anforderungs-URL mit nginx proxy_pass auf

78

Ich habe versucht, den Thin App Server zu verwenden und hatte ein Problem.

Wenn NGINX Proxies die Anforderung an Thin (oder Einhorn) unter Verwendung proxy_pass http://my_app_upstream;der Anwendung , die modifizierte URL empfängt von nginx gesendet werden ( http://my_app_upstream).

Was ich möchte, ist, die ursprüngliche URL und die ursprüngliche Anfrage vom Client ohne Änderung zu übergeben, da die App stark davon abhängt.

Der Nginx- Doc sagt:

Wenn URI in unverarbeiteter Form übertragen werden muss, sollte die Direktive proxy_pass ohne URI-Teil verwendet werden.

Ich verstehe jedoch nicht, wie genau das konfiguriert werden soll, da das zugehörige Beispiel tatsächlich URI verwendet:

location  /some/path/ {
  proxy_pass   http://127.0.0.1;
}

Könnten Sie mir bitte helfen, herauszufinden, wie die ursprüngliche Anforderungs-URL des Clients beibehalten werden kann ?

Dmytrii Nagirniak
quelle

Antworten:

131

Ich denke, die proxy_set_headerRichtlinie könnte helfen:

location / {
    proxy_pass http://my_app_upstream;
    proxy_set_header Host $host;
    # ...
}
yibe
quelle
90
Hinweis für andere Personen, die dies feststellen: Das Herzstück der Lösung, damit Nginx die URL nicht manipuliert, besteht darin, den Schrägstrich am Ende der proxy_passDirektive zu entfernen . http://my_app_upstreamvshttp://my_app_upstream/
Hugo Josefson
2
Für mich war das, dass bei der Umleitung von JSP der Hostname my_app_upstream angezeigt wurde. Verwenden von proxy_set_header Host $hostmodifiziertem und erstelltem Tomcat / JSP, um zu glauben, dass es sich um eine vom Client angeforderte Domäne handelt. Vielen Dank für die Hilfe
ankitjaininfo
1
@HugoJosefson wow Gott sei Dank, ich bemerke deinen Beitrag. Dies sollte in der Antwort
plus
3
In meinem Fall würde die Lösung von @ HugoJosefson nicht funktionieren. Ich zeigte auf localhost: port ; Ich musste den Header setzen.
2
Es ist eine Verbesserung, aber das Schema (http oder https) bleibt nicht erhalten. Jetzt werden meine https://example.com/pageUrishttp://example.com/page
John Smith Optional
10

Nur proxy_set_header Host $ Host Miss Port für meinen Fall. Gelöst von:



    location / {
     proxy_pass http://BACKENDIP/;
     include /etc/nginx/proxy.conf;
    }

und dann in der proxy.conf



    proxy_redirect off;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Grigory Kislin
quelle
1
Vielen Dank, dies war das Teil, das mir fehlte (der $ server_port), damit die OAuth-Überprüfung auf dem Endpunkt hinter dem Proxy funktioniert.
Renier
Ich verwende Rack-Schutz mit Sinatra und wurde auf POST-URLs verboten. Durch Hinzufügen des Ports zum Host-Proxy-Header wurde dies für mich behoben.
pduey
Dies funktioniert nicht mehr in den neuesten Versionen von Nginx. Ich denke, stackoverflow.com/questions/31482796/…
iwein
4

Hinweis für andere Personen, die dies feststellen: Das Herzstück der Lösung, damit Nginx die URL nicht manipuliert, besteht darin, den Schrägstrich am Ende der Anweisung Copy: proxy_pass zu entfernen. http: // my_app_upstream vs http: // my_app_upstream / - Hugo Josefson

Ich habe das oben in den Kommentaren gefunden, aber ich denke, es sollte wirklich eine Antwort sein.

Chris Stryczynski
quelle
3

Um perfekt weiterzuleiten, ohne absoluteURIdie Anfrage und die Hostin der Kopfzeile zu zerhacken :

server {
    listen 35005;

    location / {
        rewrite            ^(.*)$   "://$http_host$uri$is_args$args";
        rewrite            ^(.*)$   "http$uri$is_args$args" break;
        proxy_set_header   Host     $host;

        proxy_pass         https://deploy.org.local:35005;
    }
}

Hier zu finden: https://opensysnotes.wordpress.com/2016/11/17/nginx-proxy_pass-with-absolute-url/

Velkan
quelle
3

Falls etwas den Speicherort ändert, den Sie bedienen möchten, z. B. try_filesbleibt die Anforderung für das Back-End erhalten:

location / {
  proxy_pass http://127.0.0.1:8080$request_uri;
}
Walf
quelle
3

nginx stellt auch die Variable $ http_host bereit, die den Port für Sie übergibt. Es ist eine Verkettung von Host und Port.

Also musst du nur tun:

proxy_set_header Host $http_host;
user6880399
quelle
2

In meinem Szenario habe ich dies über den folgenden Code in der Konfiguration von nginx vhost gemacht

server {
server_name dashboards.etilize.com;

location / {
    proxy_pass http://demo.etilize.com/dashboards/;
    proxy_set_header Host $http_host;
}}

$ http_host setzt die URL im Header wie angefordert

Mansur Ali
quelle
-1

für meinen Auth-Server ... das funktioniert. Ich möchte Optionen für / auth für meine eigene humanisierte Lesbarkeit haben ... oder ich habe es auch von Port / Upstream für Maschine zu Maschine konfiguriert.

.

zu Beginn von conf

####################################################
upstream auth {
    server 127.0.0.1:9011 weight=1 fail_timeout=300s;
    keepalive 16;
  }

In meinem 443 Serverblock

          if (-d $request_filename) {
          rewrite [^/]$ $scheme://$http_host$uri/ permanent;
      }

  location /auth {
          proxy_pass http://$http_host:9011;
          proxy_set_header Origin           http://$host;
          proxy_set_header Host             $http_host:9011;
          proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
          proxy_set_header Upgrade          $http_upgrade;
          proxy_set_header Connection       $http_connection;
          proxy_http_version 1.1;
      }

Am Ende von conf

#####################################################################
#                                                                   #
#     Proxies for all the Other servers on other ports upstream     #
#                                                                   #
#####################################################################


#######################
#        Fusion       #
#######################

server {
    listen 9001 ssl;

#############  Lock it down  ################

# SSL certificate locations
    ssl_certificate /etc/letsencrypt/live/allineed.app/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/allineed.app/privkey.pem;

# Exclusions

    include snippets/exclusions.conf;

# Security

    include snippets/security.conf;
    include snippets/ssl.conf;

# Fastcgi cache rules

    include snippets/fastcgi-cache.conf;
    include snippets/limits.conf;
    include snippets/nginx-cloudflare.conf;

###########  Location upstream ##############

    location  ~ / {
        proxy_pass http://auth;
        proxy_set_header Origin           http://$host;
        proxy_set_header Host             $host:$server_port;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade          $http_upgrade;
        proxy_set_header Connection       $http_connection;
        proxy_http_version 1.1;
    }
        if (-d $request_filename) {
        rewrite [^/]$ $scheme://$http_host$uri/ permanent;
    }
}
Kai Gouthro
quelle