[PATCH] set $https for use behind SSL-stripping load-balancer

Alex Wilson alex at cooperi.net
Wed Jan 28 04:35:33 UTC 2015

Currently when using nginx behind an SSL-stripping load-balancer, there is no way to control the scheme used when generating directory redirects. By this I mean, if you are serving a static directory tree and you visit the URL of a directory without the trailing / (eg https://example.com/foo), you get served a redirect to http://example.com/foo/ (note trailing slash, and "http" instead of "https").

You could argue that the front-end load balancer should rewrite the redirect on its way from the backend to the client in this case, but alas not all hardware/software used for the front-end supports this correctly, and it also reduces the scalability/performance of the front-end if it has to scan for these URLs and correct them. I think nginx should support generating these redirects correctly in the back-end.

The code that generates these redirects is in ngx_http_header_filter_module.c, around line 528-529 (in v1.6.2). It only looks at whether connection->ssl is 0 or not before deciding whether to introduce the 's' after 'http'.

This patch adds an extra flag to the ngx_connection_t called "ssl_set", and makes this redirect generator, as well as the getters for $scheme and $https, look at this flag as well as ->ssl. Then it adds a variable setter for $https that uses this flag where appropriate.

After this, you can simply add "set $https on;" to the server block on the backend server and it will generate correct redirects. Conveniently, you can also then use the stock fastcgi.conf / fastcgi_params for a back-end nginx and not have to worry about creating a different variable to make the fastcgi_param HTTPS be set correctly.

I thought about some alternatives to the "set $https on;" semantic -- maybe you should "set $scheme"? Or, as I've seen suggested once before, a "real_scheme" directive to pull it out of an HTTP header? It seems like there is not that much difference between the approaches though, and the "set variable" based approach is the most general: you can emulate the real_scheme directive with it by using a "map", but not the other way around. So if there are other ideas for a better approach I'd like to hear them, otherwise here is a patch for "set $https" :)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: nginx-set-https.patch
Type: application/octet-stream
Size: 3458 bytes
Desc: not available
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20150128/104ef143/attachment.obj>

More information about the nginx-devel mailing list