I got the following setup:
Internet => nginx[public:80 +443, SSL termination)
=> Varnish[localhost:81] => Apache[localhost:82]
Now some sites should only be reachable via HTTPS and a valid SSL certificate. For these few exceptions I'd like to activate HSTS, either on nginx (preferred, or on Apache).
The problem:
- On nginx, I'd need some logic à la
if Host = foo.tld
then setStrict-Transport-Security xxx
, but according to http://wiki.nginx.org/IfIsEvil one should not useif
in alocation
- On Apache, I'd need something like
if X-Forwarded-Proto 443 set Strict-Transport-Security xxx
, but I don't seem to be able to construct this withSetEnvIf
(Apache 2.2)
Is my logic flawed? Another idea for an approach?
This is the configuration currently active:
nginx
server { server_tokens off; listen xx.xx.xxx.xxx:80; server_name localhost; location / { proxy_pass http://127.0.0.1:81; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port 80; proxy_set_header Host $host; add_header X-XSS-Protection "1; mode=block"; } } server { server_tokens off; listen xx.xx.xxx.xxx:443 ssl; server_name localhost; ssl on; ssl_certificate /etc/ssl/foo.crt; ssl_certificate_key /etc/ssl/private/foo.key; ssl_session_timeout 10m; # http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; location / { proxy_pass http://127.0.0.1:81; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port 443; proxy_set_header Host $host; add_header X-XSS-Protection "1; mode=block"; } }
Varnish
No special configuration.
Apache
<VirtualHost *:82>
[...] nothing special
</VirtualHost>
You could have multiple server blocks. So just add new server block for domains that need HSTS.
Here first block will handle all https connections except
example.com
andother.example.com
.And you don't need
ssl on
directive if you havessl
flag inlisten
.EDIT
There is another solution with only one server block:
We use
map
to define HSTS header value and use the fact, than nginx will not add header with empty value.You can also add the HSTS header unconditionnaly.
Indeed, it only takes effect if the connection succeeded, over TLS and without cert warning. Cf paragraph 5.1 of RFC6797.