HTTP 严格传输安全(HSTS)是一种安全功能,web 服务器通过它来告诉浏览器仅用 HTTPS 来与之通讯,而不是使用 HTTP。本文会说明如何在 Apache2、Nginx 和 Lighttpd 上如何启用 HSTS。
什么是 HTTP 严格传输安全?
引用自 Mozilla Developer Network:
如果一个 web 服务器支持 HTTP 访问,并将其重定向到 HTTPS 访问的话,那么访问者在重定向前的初始会话是非加密的。举个例子,比如访问者输入 http://www.foo.com/ 或直接输入 foo.com 时。
这就给了中间人攻击的一个机会,重定向可能会被破坏,从而定向到一个恶意站点而不是应该访问的加密页面。
HTTP 严格传输安全(HSTS)功能使 Web 服务器告知浏览器绝不使用 HTTP 访问,在浏览器端自动将所有到该站点的 HTTP 访问替换为 HTTPS 访问。
以下引自维基百科:
HSTS 可以用来抵御 SSL 剥离攻击。SSL 剥离攻击是中间人攻击的一种,由 Moxie Marlinspike 于2009年发明。他在当年的黑帽大会上发表的题为 “New Tricks For Defeating SSL In Practice” 的演讲中将这种攻击方式公开。SSL剥离的实施方法是阻止浏览器与服务器创建HTTPS连接。它的前提是用户很少直接在地址栏输入https://,用户总是通过点击链接或3xx重定向,从HTTP页面进入HTTPS页面。所以攻击者可以在用户访问HTTP页面时替换所有https://开头的链接为http://,达到阻止HTTPS的目的。
HSTS可以很大程度上解决SSL剥离攻击,因为只要浏览器曾经与服务器创建过一次安全连接,之后浏览器会强制使用HTTPS,即使链接被换成了HTTP。
另外,如果中间人使用自己的自签名证书来进行攻击,浏览器会给出警告,但是许多用户会忽略警告。HSTS解决了这一问题,一旦服务器发送了HSTS字段,用户将不再允许忽略警告。
场景举例:
当你通过一个无线路由器的免费 WiFi 访问你的网银时,很不幸的,这个免费 WiFi 也许就是由黑客的笔记本所提供的,他们会劫持你的原始请求,并将其重定向到克隆的网银站点,然后,你的所有的隐私数据都曝光在黑客眼下。
严格传输安全可以解决这个问题。如果你之前使用 HTTPS 访问过你的网银,而且网银的站点支持 HSTS,那么你的浏览器就知道应该只使用 HTTPS,无论你是否输入了 HTTPS。这样就防范了中间人劫持攻击。
注意,如果你之前没有使用 HTTPS 访问过该站点,那么 HSTS 是不奏效的。网站需要通过 HTTPS 协议告诉你的浏览器它支持 HSTS。
服务器开启 HSTS 的方法是,当客户端通过HTTPS发出请求时,在服务器返回的 HTTP 响应头中包含 Strict-Transport-Security
字段。非加密传输时设置的HSTS字段无效。
HSTS部署
通过在加密的HTTP响应中包含Strict-Transport-Security头来实现网站HSTS,例如
Strict-Transport-Security: max-age=63072000; includeSubdomains; preload;
最佳的部署方案是部署在离用户最近的位置,例如架构有前端反向代理和后端web服务器,在前端代理处配置HSTS是最好的,否则就需要在web服务器层配置HSTS。如果web服务器不明确支持HSTS,可以通过增加响应头的机制,但需要阅读各种服务器的附属细则。如果其他方法都失败了,可以在应用程序层增加HSTS。
Apache
#启用HTTP严格传输安全
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
#HSTS策略只能在加密通道的HTTP响应中进行设置,因此需要把http重定向到https,如果明文响应中允许设置HSTS头,中间人攻击者就可以通过在普通站点中注入HSTS信息来执行DoS攻击
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
…
#将所有访问者重定向到加密的网站
RedirectPermanent / https://www.example.com/
<VirtualHost>
或者使用 mod_rewrite 来做重定向,但是上述的方式更简单更安全。不过,mod_rewrite 可以重定向页面到对应的 HTTPS 页面,而上述配置则只重定向到“/”:
<VirtualHost *:80>
[...]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>
</VirtualHost>
不要忘记重启 Apache。
IIS
第三方模块 http://hstsiis.codeplex.com/
Nginx
Nginx好像所有的配置都是这么简单= =!直接将下述行添加到你的 HTTPS 配置的 server 块中:
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
示例:
server {
listen xxxx:443 ssl;
server_name www.example.com;
add_header Strict-Transport-Security “max-age=31536000;includeSubdomains;preload”;
….
}
server {
listen xxxx:80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
…
}
重启Nginx
注意:addheader指令只会将HTTP头添加到非错误响应中(2xx和3xx)
更多部署方法请参考:https://linux.cn/article-5266-1.html
学习一下