22

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 to http://ip_of_the_app:7180 at the same login page, and I have to login again. Can this double login be avoided?

2
  • tonio94, has your problem been addressed? if yes, please accept the answer. if no, please clarify what's missing.
    – cnst
    Jul 3, 2016 at 22:56
  • 2
    I just tested it yesterday, it works, proxy_redirect need to be removed. Thanks for the help.
    – tonio94
    Jul 5, 2016 at 2:26

1 Answer 1

36

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 nginxs IP) and X-Forwarded-Proto to check whether the client connected to the nginx through HTTP or HTTPS.

6
  • Thanks 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.
    – tonio94
    Jul 11, 2016 at 15:53
  • @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
    Jul 11, 2016 at 16:16
  • @JonathanKomar - Thank you for that, you are correct, now edited. Sorry it took me a while to notice your comment.
    – grochmal
    Sep 4, 2019 at 16:18
  • @grochmal Thanks, you basically saved my life with this info about: proxy_set_header HOST $host; Mar 29, 2020 at 23:09
  • 1
    @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/…
    – Felix B.
    May 1, 2021 at 17:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .