Nginx: Detect HTTPS connection using a header

On my load balancer I terminate HTTPS connections with Nginx and then proxy the request to one of the web servers which are also backed by Nginx.

On the load balancer in fastcgi_params I have:

fastcgi_param   HTTPS   $https;

On the web servers there is a site that can only be accessed by HTTPS. How can I detect if the HTTPS param is set and if not redirect to the secure version of the site?


If I understand you correctly, your setup is something like this:

client -(http/https)-> nginx(front) -(http)-> nginx(back) -(fastcgi)-> app

There are actually 3 different places where redirection could be done:

On your front Nginx server, you can just do redirection when needed:

if ( $https != 'on' ) {
  return 301 https://$host$request_uri;
}

If you cannot do this on the front Nginx server, you have to carry information on used protocol to back Nginx instance. Usual way is use of X-Forwarded-Proto header. You should add in appropriate place on your front Nginx server:

proxy_set_header X-Forwarded-Proto $scheme;

Then, you can make redirection in back Nginx server:

if ( $http_x_forwarded_proto != 'https' ) {
  return 301 https://$host$request_uri;
}

Obviously, you could handle redirection inside app as well. You should have X-Forwarded-Proto header available in app, or you could set it as fastcgi param:

Somewhere in http {}

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

And extra mapping:

fastcgi_param   HTTPS $fe_https;

Personally, I think that redirection should be done as early in a chain as plausible.