如何配置使用 HTTP 严格传输安全（HSTS）
HTTP 严格传输安全（HSTS）是一种安全功能，web 服务器通过它来告诉浏览器仅用 HTTPS 来与之通讯，而不是使用 HTTP。本文会说明如何在 Apache2、Nginx 和 Lighttpd 上如何启用 HSTS。在主流的 web 服务器上测试通过： Nginx1.1.19、 Lighttpd 1.4.28 和Apache 2.2.22 ，环境为 Ubuntu 12.04、 Debian 6  7 和 CentOS 6，只需要调整部分参数就可以工作在其它的发行版上。  什么是 HTTP 严格传输安全？ 引用自Mozilla Developer Network：  如果一个 web 服务器支持 HTTP 访问，并将其重定向到 HTTPS 访问的话，那么访问者在重定向前的初始
HSTS https
220.161.81.10
强迫症发作 <br />
“重定向会可能会被破坏” <br />
两个“会”看起来很怪异。。。。。。
maowu122
2015-04-15T08:59:34.000
114.253.242.203
语误，马上改~
linux
2015-04-15T12:18:20.000
60.189.103.62
挖~问个问题 开启HSTS后 切换回HTTP不使用SSL会不会也给强制切换到HTTPS。。无限循环？
来自浙江台州的 Chrome 47.0|Windows 10 用户
2016-01-23T09:22:17.000
111.201.14.53
是的，如果你是用 301/302 切换回去，那就这样了——如果你用preload HSTS ，那更完了。。。
linux [Chrome 47.0|Mac 10.11]
2016-01-23T22:45:08.000
HTTP 严格传输安全（HSTS）是一种安全功能，web 服务器通过它来告诉浏览器仅用 HTTPS 来与之通讯，而不是使用 HTTP。本文会说明如何在 Apache2、Nginx 和 Lighttpd 上如何启用 HSTS。在主流的 web 服务器上测试通过： Nginx1.1.19、 Lighttpd 1.4.28 和Apache 2.2.22 ，环境为 Ubuntu 12.04、 Debian 6  7 和 CentOS 6，只需要调整部分参数就可以工作在其它的发行版上。  什么是 HTTP 严格传输安全？ 引用自Mozilla Developer Network：  如果一个 web 服务器支持 HTTP 访问，并将其重定向到 HTTPS 访问的话，那么访问者在重定向前的初始
HTTP 严格传输安全（HSTS）是一种安全功能，web 服务器通过它来告诉浏览器仅用 HTTPS 来与之通讯，而不是使用 HTTP。本文会说明如何在 Apache2、Nginx 和 Lighttpd 上如何启用 HSTS。在主流的 web 服务器上测试通过： Nginx 1.1.19、 Lighttpd 1.4.28 和 Apache 2.2.22 ，环境为 Ubuntu 12.04、 Debian 6 & 7 和 CentOS 6，只需要调整部分参数就可以工作在其它的发行版上。


![](/data/attachment/album/201504/14/142928nt90umljtulb8nte.gif)


### 什么是 HTTP 严格传输安全？


引用自 [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security)：



> 
> 如果一个 web 服务器支持 HTTP 访问，并将其重定向到 HTTPS 访问的话，那么访问者在重定向前的初始会话是非加密的。举个例子，比如访问者输入 http://www.foo.com/ 或直接输入 foo.com 时。
> 
> 
> 这就给了中间人攻击的一个机会，重定向可能会被破坏，从而定向到一个恶意站点而不是应该访问的加密页面。
> 
> 
> HTTP 严格传输安全（HSTS）功能使 Web 服务器告知浏览器绝不使用 HTTP 访问，在浏览器端自动将所有到该站点的 HTTP 访问替换为 HTTPS 访问。
> 
> 
> 


以下引自[维基百科](http://zh.wikipedia.org/wiki/HTTP%E4%B8%A5%E6%A0%BC%E4%BC%A0%E8%BE%93%E5%AE%89%E5%85%A8)：



> 
> HSTS 可以用来抵御 SSL 剥离攻击。SSL 剥离攻击是中间人攻击的一种，由 Moxie Marlinspike 于2009年发明。他在当年的黑帽大会上发表的题为 “New Tricks For Defeating SSL In Practice” 的演讲中将这种攻击方式公开。SSL剥离的实施方法是阻止浏览器与服务器创建HTTPS连接。它的前提是用户很少直接在地址栏输入https://，用户总是通过点击链接或3xx重定向，从HTTP页面进入HTTPS页面。所以攻击者可以在用户访问HTTP页面时替换所有https://开头的链接为http://，达到阻止HTTPS的目的。<sup class="reference" id="cite_ref-9"></sup>
> 
> 
> HSTS可以很大程度上解决SSL剥离攻击，因为只要浏览器曾经与服务器创建过一次安全连接，之后浏览器会强制使用HTTPS，即使链接被换成了HTTP。
> 
> 
> 另外，如果中间人使用自己的自签名证书来进行攻击，浏览器会给出警告，但是许多用户会忽略警告。HSTS解决了这一问题，一旦服务器发送了HSTS字段，用户将不再允许忽略警告。
> 
> 
> 


场景举例：



> 
> 当你通过一个无线路由器的免费 WiFi 访问你的网银时，很不幸的，这个免费 WiFi 也许就是由黑客的笔记本所提供的，他们会劫持你的原始请求，并将其重定向到克隆的网银站点，然后，你的所有的隐私数据都曝光在黑客眼下。
> 
> 
> 严格传输安全可以解决这个问题。如果你之前使用 HTTPS 访问过你的网银，而且网银的站点支持 HSTS，那么你的浏览器就知道应该只使用 HTTPS，无论你是否输入了 HTTPS。这样就防范了中间人劫持攻击。
> 
> 
> 


注意，如果你之前没有使用 HTTPS 访问过该站点，那么 HSTS 是不奏效的。网站需要通过 HTTPS 协议告诉你的浏览器它支持 HSTS。


服务器开启 HSTS 的方法是，当客户端通过HTTPS发出请求时，在服务器返回的 HTTP 响应头中包含 `Strict-Transport-Security` 字段。非加密传输时设置的HSTS字段无效。


### 在 Apache2 中设置 HSTS


编辑你的 apache 配置文件（如 `/etc/apache2/sites-enabled/website.conf` 和 `/etc/apache2/httpd.conf ），并加以下行到你的 HTTPS` VirtualHost：



```
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so

<VirtualHost 67.89.123.45:443>
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>

```

现在你的 web 站点在每次访问时都会发送该请求头，失效时间是两年（秒数）。这个失效时间每次都会设置为两年后，所以，明天你访问时，它会设置为明天的两年后。


你只能在 HTTPS 虚拟机中设置这个头，而不能设置在 HTTP 虚拟机中。


要将你的访问者重定向到对应 HTTPS 站点，可使用如下设置：



```
<VirtualHost *:80>
  [...]
  ServerName example.com
  Redirect permanent / https://example.com/
</VirtualHost>

```

如果仅仅是做重定向的话，甚至不需要设置 DocumentRoot。


你也可以使用 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。


### Lighttpd


对于 lighttpd 来说很简单，将下述配置增加到你的 Lighttpd 配置文件（例如：`/etc/lighttpd/lighttpd.conf）：`



```
server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
    setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=63072000; includeSubdomains; preload")
}

```

重启 Lighttpd。失效时间也是两年。


### Nginx


Nginx 甚至更简单，将下述行添加到你的 HTTPS 配置的 server 块中：



```
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

```

不要忘记重启 Nginx。

