Handle X-Forwarded-Proto in backend nginx

When nginx is being used as backend server, it will talk plain "http" to the frontend server only (for performance reasons and to simplify setup).

But web applications often need to know, if the traffic between the browser and server is encrypted (https), e.g. when checking if a particular part of the site is being accessed securely.

Since only the frontend proxy (the one between nginx and the browser) knows about this, this information has to be forwarded to the backend.


One common solution is for the frontend to set the "X-Forwarded-Proto" header when forwarding the browser request to the backend server.

This is very similar to the information about the browser's IP address: this is also only known by the frontend and the backend will see the IP of the frontend proxy, but not the one of the user.
The "X-Real-IP" header is often being used to forward this information from the frontend to the backend and nginx supports this via the NginxHttpRealIpModule, e.g.: set_real_ip_from $ip_frontend;

Unfortunately there is no support yet for X-Forwarded-Proto, but it can easily get done as follows:


server {
  set $my_https "off";
  if ($http_x_forwarded_proto = "https") {
    set $my_https "on";
  location ~ ^(.+\.php)(.*)$ {
    fastcgi_param  HTTPS    $my_https;

This will set the HTTPS variable either to "on" or "off", according to if X-Forwarded-Proto is "https" or "http".

If nginx is also used as the frontend proxy, you would pass the information as follows in the location context:


proxy_set_header X-Real-IP       $remote_addr;
By Daniel in Ubuntu, Snippets05/07/10 English (US) Email


Comment from: NIXin [Visitor]
NIXinApparently, this is a nicer way of doing the same thing:

http {

map $http_x_forwarded_proto $https {
default off;
https on;

fastcgi_param HTTPS $https;

But for some reason neither work for me (I use it with PHP-FPM), and I still have to manually set $https "on"; in each SSL site in /etc/sites-enabled/site123.com
01/13/11 @ 02:36
Comment from: Brandon Holtsclaw [Visitor] Email
Brandon HoltsclawPlease don't use Ifs like that, or if you do don't advocate it to others.

04/17/12 @ 12:08
Comment from: Daniel [Member] Email
The IfIsEvil wiki page considers "If" evil "when used in location context".
That's not what I am doing here (it is used in the "server" context).

Apart from that, the "map" solution suggested by NIXin should be preferred anyway though - I am quite sure to have it used somewhere already (and that it might not have existed back when I wrote this post).
04/19/12 @ 18:18
Comment from: Pothi [Visitor] Email
PothiThanks for the tip, Daniel. It works!

@NIXin: In your way of doing it, I encountered an error regarding the duplicate variable "https". So, changing it in the following way works...

map $http_x_forwarded_proto $forwarded_https { default off; https on; }

fastcgi_param HTTPS $forwarded_https;

Daniel's method seems efficient when hosting multiple sites.
04/05/15 @ 19:06

Leave a comment

Your email address will not be revealed on this site.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)
This is a captcha-picture. It is used to prevent mass-access by robots.
Please enter the characters from the image above. (case insensitive)
You can just use your OpenID to provide your name, e-mail and url.