如何配置使用 HTTP 严格传输安全(HSTS)

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

全网部署

hsts-num.JPG

1 条评论

发表评论

*