server {
listen xxx.abc.com;
server_name xxx.abc.com;
rewrite ^/(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl;
server_name xxx.abc.com;
add_header Strict-Transport-Security "max-age=172800; includeSubDomains";
ssl_certificate cert/server.crt;
ssl_certificate_key cert/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3001;
}
}
然后nginx配置保存,然后重启。
当我重启后,第一次使用https方式访问我的网站,nginx会告诉客户端浏览器,以后如果用户输入的是http,也要让浏览器以https来访问我的nginx服务器,如下所示:


但是如果nginx重启后,第一次使用http访问的话,虽然跳转了,但是并没有使用HSTS了,因为要跳转到https,才会使用HSTS。但是当我再输入http了就会有307状态码,并且有 "Provisional headers are shown" 这样的提示。
理解HSTS Preload List
HSTS虽然可以解决HTTPS的降级攻击,但是对于HSTS生效前首次的http请求,依然是无法避免http请求被劫持的问题,比如我们第一次浏览器清除缓存,然后第一次使用http请求的话,第一次http也是明文传输的,当跳转到https后会使用HSTS的,以后只要浏览器缓存不清除的话,nginx不重启的话,都会使用HSTS保护的。因此为了解决第一次http请求的问题,浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 的方案,内置一份可以定期更新的表,对于列表中的域名,即使用户之前没有访问过,也会使用https协议请求的。
目前这个Preload List由Google Chrome维护,Chrome、Firefox、Safari、IE 11和Microsoft Edge都在使用。如果要想把自己的域名加进这个列表,首先需要满足以下条件:
1. 拥有合法的证书(如果使用SHA-1证书,过期时间必须早于2016年);
2. 将所有HTTP流量重定向到HTTPS;
3. 确保所有子域名都启用了HTTPS;
4. 输出HSTS响应头:
5. max-age不能低于18周(10886400秒);
6. 必须指定includeSubdomains参数;
7. 必须指定preload参数;
即便满足了上述所有条件,也不一定能进入HSTS Preload List,更多信息可以查看:https://hstspreload.org/。
通过Chrome的chrome://net-internals/#hsts工具,可以查询某个网站是否在PreloadList之中,还可以手动把某个域名加到本机Preload List。
HSTS缺点
HSTS并不是HTTP会话劫持的完美解决方案。用户首次访问某网站是不受HSTS保护的。这是因为首次访问时,浏览器还未收到HSTS,所以仍有可能通过明文HTTP来访问。








