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;

Source

Comments are closed.