传输层安全 (TLS) 配置

传输层安全 (TLS) 可确保所有通信的机密性、真实性和完整性,因此应将其用于所有入站和出站网站通信。

TLS 配置

问题

如果数据在网络上未加密发送,则第三方可以拦截它,并访问和修改数据——这通常被称为 中间人攻击 (MiTM)。MiTM 攻击对系统安全造成严重后果。

因此,所有请求和响应都应通过 HTTPS 发送,HTTPS 使用 TLS 对数据进行加密。现代 Web 实际上强制执行此操作——所有浏览器都正在转向默认情况下要求 HTTPS,并且许多 Web 功能只能在 安全上下文 中使用。

解决方案

您应设置服务器软件以使用安全配置,强制使用具有安全 TLS 设置的 HTTPS。有几个可用的 TLS 配置生成器可以帮助您完成此操作,例如 Mozilla SSL 配置生成器。此工具根据 Mozilla 的 TLS 指南 提供多种选项。

资源加载

问题

所有资源,无论其来源如何,都应通过安全通道加载。

尝试通过不安全连接 (HTTP) 加载活动资源(如 JavaScript)的安全 (HTTPS) 网站将被浏览器阻止。结果,用户将遇到降级的 UI 和 混合内容 警告。例如,在下面的代码中,HTTP 被错误地用于加载 JavaScript 库

html
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>

类似地,尝试不安全地加载被动内容(如图像),尽管风险较低,但仍会导致降级的 UI 和混合内容警告,并且可能允许主动攻击者篡改网站或诱骗用户。例如

html
<img src="http://very.badssl.com/image.jpg" />

尽管现代浏览器在网站不安全地加载资源时会明确显示,但这些错误仍然在网络上频繁出现。

解决方案

在部署之前,请验证所有资源是否都通过 HTTPS 加载。

示例

在此示例中,HTTPS 正确地用于加载 JavaScript 库

html
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>

HTTP 重定向

问题

网站可能会继续监听端口 80 (HTTP) 以防止用户在地址栏中键入 URL 时出现连接错误,因为初始浏览器连接通常通过 HTTP 建立。这在第一次连接到站点时会带来初始安全风险,因为该连接不受 TLS 保护。

此外,站点应避免从一个主机上的 HTTP 重定向到另一个主机上的 HTTPS,因为这会阻止为第一个主机设置 Strict-Transport-Security(请参阅 HTTP 严格传输安全)。

解决方案

监听端口 80 的站点应仅重定向到 HTTPS 上的同一资源。重定向发生后,Strict-Transport-Security 应确保所有未来尝试通过 HTTP 访问站点的操作都自动重定向到安全站点。

不打算公开访问的 API 或网站应完全禁用 HTTP 的使用。

要解决“不同主机”问题

  1. 首先,从 http://example.com/ 重定向到 https://example.com/
  2. 接下来,从 https://example.com/ 重定向到 https://example.org/

示例

使用 NGINX 将所有传入的 HTTP 请求重定向到 HTTPS 上的同一站点和 URI

nginx
server {
  listen 80;

  return 301 https://$host$request_uri;
}

使用 Apache 将 site.example.org 从 HTTP 重定向到 HTTPS

apacheconf
<VirtualHost *:80>
  ServerName site.example.org
  Redirect permanent / https://site.example.org/
</VirtualHost>

HTTP 严格传输安全实施

问题

为了防止 中间人攻击 (MiTM),浏览器应仅通过 HTTPS 连接到站点。

解决方案

HTTP Strict-Transport-Security (HSTS) 是一个 HTTP 标头,它通知浏览器仅通过 HTTPS 连接到给定站点,即使最初指定的方案为 HTTP 也是如此。为给定站点设置了 HSTS 的浏览器将自动将该站点的所有请求升级到 HTTPS。HSTS 还告诉浏览器更严格地处理 TLS 和证书相关的错误,方法是禁用绕过证书错误页面的功能。

Strict-Transport-Security 支持以下指令

max-age

设置浏览器重定向到 HTTPS 的持续时间(以秒为单位)。

includeSubDomains 可选

指定浏览器是否应将所有子域上的请求升级到 HTTPS。例如,在 domain.example.com 上设置 includeSubDomains 将确保除了 domain.example.com 之外,对 host1.domain.example.comhost2.domain.example.com 的请求也升级。

preload 可选

指定是否应预加载站点。包含此指令意味着您的站点可以包含在 HSTS 预加载列表 中。

按照以下步骤在您的网站上正确实施 HSTS

  1. 设置至少六个月(15768000)的 max-age 值。建议使用更长时间段,例如两年(63072000)。设置此值后,站点必须继续支持 HTTPS,直到达到过期时间。
  2. 如果可能,设置 includeSubDomains 以提高所有子域的安全级别。设置此指令时需要仔细测试,因为它可能会禁用尚未启用 HTTPS 的子域上的站点。
  3. 如果可能,设置 preload 以便将您的网站包含在 HSTS 预加载列表中。要将其添加到列表中,请访问 https://hstspreload.org/,并将您的站点 URL 输入页面顶部的表单中,并修复它提到的任何问题。Web 浏览器将在接收初始 Strict-Transport-Security 标头之前对预加载的站点执行 HTTPS 升级。这可以防止在首次使用时发生 降级攻击,建议所有高风险网站使用。请注意,包含在 HSTS 预加载列表中还需要设置 includeSubDomains 并将 max-age 设置为至少 1 年(31536000)。

除了 Strict-Transport-Security 之外,您还应在 Content-Security-Policy 中设置 upgrade-insecure-requests 指令。这指示浏览器将站点的所有不安全 URL(通过 HTTP 提供的 URL)视为已通过 HTTPS 提供。upgrade-insecure-requests 适用于具有大量需要重写的旧版不安全 URL 的网站。

示例

建议通过 HTTPS 连接到站点两年

http
Strict-Transport-Security: max-age=63072000

如果可能,此外还将子域请求升级到 HTTPS 并将站点包含在预加载列表中

http
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

还设置 upgrade-insecure-requests CSP

http
Content-Security-Policy: upgrade-insecure-requests;

另请参阅