Nginx reverse proxy redirection
Do not set proxy_redirect
to off
, that is not doing what you think it is doing. proxy_redirect
performs something similar to URL rewriting, for example:
location /sales/ {
proxy_pass http://ip_of_the_app:7180/;
proxy_redirect http://ip_of_the_app:7180/ http://$host/sales/;
}
This allows you to host the /sales/
path somewhere else. But even then, the default parameters for proxy_redirect
do exactly that for you for free. The default is to redirect the location into whatever is present in proxy_pass
(and the default parameters are used when you do not set proxy_redirect
at all, or use proxy_redirect default;
).
You do not need to set proxy_redirect
.
What you're missing are headers that need to be sent to the app. The most important of them is HOST
. This shall perform the proxying as desired and shall keep the correct URL in the browser.
location / {
proxy_pass http://ip_of_the_app:7180/;
proxy_set_header HOST $host;
}
Note that the app at http://ip_of_the_app:7180/
will now receive the request with the Host: my-app.net
header.
You should also consider using a couple more headers:
proxy_set_header Referer $http_referer;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
This will allow for better logging inside the app at http://ip_of_the_app:7180/
. X-Forwarded-For
giving the IP of the actual client (as opposed to nginx
s IP) and X-Forwarded-Proto
to check whether the client connected to the nginx
through HTTP or HTTPS.
Related videos on Youtube
tonio94
Updated on September 18, 2022Comments
-
tonio94 over 1 year
I am using
nginx
as a reverse proxy and when I login in my web interface I am redirected to the proxied URL. I would like to avoid it and always keep the "server_name" as the URL. Is it possible?This is my
/etc/nginx/conf.d/my_app.conf
:server { listen 443 ssl; server_name my-app.net; ssl_certificate /etc/pki/tls/certs/my-app.cer; ssl_certificate_key /etc/pki/tls/private/my-app.key; ssl_protocols TLSv1.1 TLSv1.2; access_log /var/log/nginx/my-app.access.log main; location / { proxy_pass http://ip_of_the_app:7180/; proxy_redirect off; } }
I connect on
http://my-app.net
, enter login information, I am then redirected tohttp://ip_of_the_app:7180
at the same login page, and I have to login again. Can this double login be avoided?-
cnst almost 8 yearstonio94, has your problem been addressed? if yes, please accept the answer. if no, please clarify what's missing.
-
tonio94 almost 8 yearsI just tested it yesterday, it works, proxy_redirect need to be removed. Thanks for the help.
-
-
tonio94 almost 8 yearsThanks for your help. proxy_redirect is not needed but proxy_set_header Referer ip_of_the_app:7180 must be set in order to work properly.
-
grochmal almost 8 years@tonio94 - Thanks, I updated the answer. Note that the normal usage of the
Referer
is simply$http_referer
which copies it from the request. That does not work if the request does not have a Referer header, therefore hardcoding it is a solution in some cases. -
grochmal over 4 years@JonathanKomar - Thank you for that, you are correct, now edited. Sorry it took me a while to notice your comment.
-
Obay Abd-Algader about 4 years@grochmal Thanks, you basically saved my life with this info about: proxy_set_header HOST $host;
-
Felix B. about 3 years@grochmal I think it should be
X-Forwarded-For $proxy_add_x_forwarded_for
this will append the$remote_addr
IP to a list of possibly multiple forwarding hoops instead of replacing it.X-Real-IP $remote_addr
is where the previous hoop is supposed to go if I understand this right - see also docs.oracle.com/en-us/iaas/Content/Balance/Reference/… -
grochmal about 3 years@FelixB. I do not disagree, it would be better to use both X-Real-IP and then place the list in X-Forwarded-For . Unfortunately, few people/webservers use it that way (at least from my experience), and since the X- headers are just a convention there's no way to enforce anything. Moreover, if I'm not mistake to pass the full list through to X-Forwarded-For you would need nginx's realip and
real_ip_recursive on;
, which is another can of worms to worry about. I'd stick to the slightly incorrect but easy to make work solution for now.