在服务器上启用 HTTPS

克里斯·帕尔默
Chris Palmer
Matt Gaunt

本文介绍的步骤

  1. 创建一个 2048 位 RSA 公钥/私钥对。
  2. 生成一个嵌入您的公钥的证书签名请求 (CSR)。
  3. 将 CSR 与证书授权机构 (CA) 共享以接收最终证书或证书链。
  4. 将最终证书安装在非 Web 可访问的位置,例如 /etc/ssl(Linux 和 Unix)或 IIS 需要它的位置 (Windows)。

生成密钥和证书签名请求

本部分使用 openssl 命令行程序(大部分 Linux、BSD 和 Mac OS X 系统均附带此程序)来生成私钥/公钥和 CSR。

生成一个公钥/私钥对

我们首先生成一个 2048 位 RSA 密钥对。较小的密钥(如 1024 位)不足以抵御暴力猜测攻击。较大的密钥(如 4096 位)有点过度。随着时间的推移,随着计算机处理费用降低,密钥大小会增加。目前 2,048 是最佳平衡点。

用于生成 RSA 密钥对的命令如下:

openssl genrsa -out www.example.com.key 2048

这会生成以下输出:

Generating RSA private key, 2048 bit long modulus
.+++
.......................................................................................+++
e is 65537 (0x10001)

生成证书签名请求

在此步骤中,您需要将公钥以及有关贵组织及网站的信息嵌入到证书签名请求(即 CSR)中。openssl 命令以交互方式要求您提供所需的元数据。

运行以下命令:

openssl req -new -sha256 -key www.example.com.key -out www.example.com.csr

输出以下内容:

You are about to be asked to enter information that will be incorporated
into your certificate request

What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:California
Locality Name (for example, city) []:Mountain View
Organization Name (for example, company) [Internet Widgits Pty Ltd]:Example, Inc.
Organizational Unit Name (for example, section) []:Webmaster Help Center Example
Team
Common Name (e.g. server FQDN or YOUR name) []:www.example.com
Email Address []:webmaster@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

为确保 CSR 的有效性,请运行以下命令:

openssl req -text -in www.example.com.csr -noout

响应应如下所示:

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CA, ST=California, L=Mountain View, O=Google, Inc.,
OU=Webmaster Help Center Example Team,
CN=www.example.com/emailAddress=webmaster@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ad:fc:58:e0:da:f2:0b:73:51:93:29:a5:d3:9e:
                    f8:f1:14:13:64:cc:e0:bc:be:26:5d:04:e1:58:dc:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         5f:05:f3:71:d5:f7:b7:b6:dc:17:cc:88:03:b8:87:29:f6:87:
         2f:7f:00:49:08:0a:20:41:0b:70:03:04:7d:94:af:69:3d:f4:
         ...

将 CSR 提交给证书授权机构

对于不同的证书授权机构 (CA),需要使用不同的方法将 CSR 发送给他们。方法可能包括在其网站上使用表单、通过电子邮件或其他方式发送 CSR。一些 CA(或其转销商)甚至可能会自动执行其中部分或全部流程(在某些情况下,包括密钥对和 CSR 的生成)。

将 CSR 发送到您的 CA,然后按照其说明接收最终证书或证书链。

对于为您的公钥进行担保的服务,不同 CA 的收费将有所不同。

您还可以选择将密钥映射到多个 DNS 名称,包括几个不同的名称(例如 example.com、www.example.com、example.net 和 www.example.net 的全部)或“通配符”名称(例如 *.example.com)。

例如,有一个 CA 目前提供以下价格:

  • 标准:16 美元/年,适用于 example.com 和 www.example.com。
  • 通配符:150 美元/年,适用于 example.com 和 *.example.com。

按这些价格,当您拥有超过 9 个子网域时,通配符证书会比较划算;您也可以只购买一个或多个单名称证书。(例如,如果您有五个以上子网域,那么在服务器上启用 HTTPS 时,您可能会发现通配符证书更方便。)

将证书复制到所有前端服务器的非网络可访问位置,例如 /etc/ssl(Linux 和 Unix)或 IIS 需要它们的位置 (Windows)。

在服务器上启用 HTTPS

在服务器上启用 HTTPS 是确保网页安全的关键步骤。

  • 使用 Mozilla 的服务器配置工具设置您的服务器,以支持 HTTPS。
  • 定期使用 Qualys 便捷的 SSL 服务器测试来测试您的网站,并确保得分至少为 A 或 A+。

此时,您必须做出关键的操作决策。请选择以下选项之一:

  • 为 Web 服务器从中传送内容的每个主机名指定一个不同的 IP 地址。
  • 使用基于名称的虚拟托管。

如果您一直为每个主机名使用不同的 IP 地址,则可以轻松地让所有客户端支持 HTTP 和 HTTPS。

但是,大多数网站运营商使用基于名称的虚拟托管来节省 IP 地址,并且这通常更方便。Windows XP 和低于 2.3 的 Android 上的 IE 的问题是,它们不理解服务器名称指示 (SNI),而这对于基于 HTTPS 名称的虚拟托管来说至关重要。

总有一天(希望很快),不支持 SNI 的客户端将被现代软件所取代。监控请求日志中的用户代理字符串,了解何时已有足够的用户迁移到现代软件。(您可以决定您的阈值;可能小于 5%,或小于 1%。)

如果您的服务器上还没有 HTTPS 服务,请立即启用(无需将 HTTP 重定向到 HTTPS;请参阅下文)。配置您的网络服务器以使用您购买并安装的证书。Mozilla 便捷的配置生成器可能会对您有所帮助。

如果您有许多主机名或子网域,它们都需要使用正确的证书。

现在,以及在网站的整个生命周期内,使用 Qualys 便捷的 SSL 服务器测试来检查 HTTPS 配置。您的网站得分应为 A 或 A+;任何会导致降级的内容都被视为 bug。(今天的 A 在明天会变成 B,因为针对算法和协议的攻击一直在改进!)

将站内网址设为相对网址

由于您的网站同时通过 HTTP 和 HTTPS 传输,无论采用哪种协议,都应该尽可能顺畅运行。一个重要的因素是对站内链接使用相对网址。

确保站内网址和外部网址与协议无关;也就是说,确保使用相对路径或省去协议,例如 //example.com/something.js

当您通过 HTTPS 提供包含 HTTP 资源(称为混合内容)的网页时,会出现问题。浏览器警告用户,已失去 HTTPS 的全部能力。事实上,如果是主动混合内容(脚本、插件、CSS、iframe),浏览器通常根本不会加载或执行内容,从而导致网页损坏。请注意,在 HTTP 网页中包含 HTTPS 资源完全没问题。

此外,当您链接到网站中的其他网页时,用户可能会从 HTTPS 降级为 HTTP。

当您的网页包含使用 http:// 架构的完全限定站内网址时,就会发生此类问题。

错误做法
<h1>Welcome To Example.com</h1>
<script src="http://example.com/jquery.js"></script>
<link rel="stylesheet" href="http://assets.example.com/style.css"/>
<img src="http://img.example.com/logo.png"/>;
<p>A <a href="http://example.com/2014/12/24/">new post on cats!</a></p>
避免使用完全限定的站内网址。

换句话说,应使站内网址尽可能采用相对地址:协议相对(缺少协议,以 //example.com 开头)或主机相对(以相对路径开头,例如 /jquery.js)。

正确做法
<h1>Welcome To Example.com</h1>
<script src="/jquery.js"></script>
<link rel="stylesheet" href="/assets/style.css"/>
<img src="/images/logo.png"/>;
<p>A <a href="/2014/12/24/">new post on cats!</a></p>
使用相对站内网址。
正确做法
<h1>Welcome To Example.com</h1>
<script src="//example.com/jquery.js"></script>
<link rel="stylesheet" href="//assets.example.com/style.css"/>
<img src="//img.example.com/logo.png"/>;
<p>A <a href="//example.com/2014/12/24/">new post on cats!</a></p>
或者,使用相对协议站内网址。
正确做法
<h1>Welcome To Example.com</h1>
<script src="/jquery.js"></script>
<link rel="stylesheet" href="/assets/style.css"/>
<img src="/images/logo.png"/>;
<p>A <a href="/2014/12/24/">new post on cats!</a></p>
<p>Check out this <a href="https://foo.com/"><b>other cool site.</b></a></p>
尽可能为网站间网址使用 HTTPS 网址。

通过脚本执行此操作,而不是手动操作。如果您网站内容在数据库中,请在数据库的开发副本中测试脚本。如果网站内容由简单文件组成,请在文件的开发副本中测试脚本。像往常一样,只有在更改通过 QA 后,才能将更改推送到生产环境中。您可以使用 Bram van Damme 的脚本或类似脚本来检测网站中的混合内容。

在链接到其他网站(而不是包含其他网站的资源)时,请勿更改协议,因为您无法控制这些网站的运行方式。

为了使大型网站的迁移更顺利,我们建议您使用相对协议网址。如果您不确定是否可以完全部署 HTTPS,强制网站的所有子资源使用 HTTPS 可能会适得其反。在某些情况下,您可能会觉得 HTTPS 有些奇怪,而 HTTP 网站仍然必须像往常一样正常运行。随着时间的推移,您将完成迁移并锁定 HTTPS(请参阅接下来的两个部分)。

如果您的网站依赖于第三方(例如 CDN 或 jquery.com)提供的脚本、图片或其他资源,则有以下两种选择:

  • 对这些资源使用相对协议网址。如果该第三方不提供 HTTPS,请让第三方提供。大多数已经做到这一点,包括 jquery.com。
  • 从由您控制且同时提供 HTTP 和 HTTPS 的服务器提供资源。这通常是个好点子,因为您可以更好地控制网站的外观、性能和安全。此外,您不必信任第三方,尽管他们总是很不错。

将 HTTP 重定向到 HTTPS

您需要在网页的标头处放置一个规范链接,以告知搜索引擎 HTTPS 是访问您网站的最佳方式。

在您的网页中设置 <link rel="canonical" href="https://…"/> 标记。这有助于搜索引擎确定访问您网站的最佳方式。

启用严格传输安全和安全 Cookie

此时,您已准备好“锁定”使用 HTTPS。

  • 使用 HTTP 严格传输安全协议 (HSTS) 来避免 301 重定向产生的费用。
  • 始终在 Cookie 上设置安全标记。

首先,使用严格传输安全来告知客户端,它们应始终通过 HTTPS 连接到您的服务器,即使遵循 http:// 引用也是如此。这样可以抵御 SSL 剥离等攻击,还可以避免我们在将 HTTP 重定向到 HTTPS 中启用的 301 redirect 的往返费用。

通过设置 Strict-Transport-Security 标头来启用 HTTP 严格传输安全协议 (HSTS)。OWASP 的 HSTS 页面包含各种服务器软件的说明链接

大多数网络服务器都提供类似的功能来添加自定义标头。

还有一点也很重要,那就是确保客户端绝不会通过 HTTP 发送 Cookie(例如用于身份验证或网站偏好设置)。例如,如果用户的身份验证 Cookie 将以明文形式公开,其整个会话的安全保障将被破坏 — 即使您其他的所有措施都正确无误!

因此,更改您的 Web 应用,以便始终在其设置的 Cookie 上设置安全标志。此 OWASP 页面介绍了如何在多个应用框架中设置安全标志。每个应用框架都有一种方法来设置此标志。

大多数网络服务器都提供一种简单的重定向功能。使用 301 (Moved Permanently) 向搜索引擎和浏览器表明 HTTPS 版本是规范网页,并将用户从 HTTP 重定向到网站的 HTTPS 版本。

搜索结果排名

Google 使用 HTTPS 作为肯定搜索质量指标。Google 还发布了有关如何转移、移动或迁移网站的指南,同时保持网站的搜索排名。Bing 还发布了网站站长指南

性能

如果内容和应用层经过了精心调整(请参阅 Steve Souders 的著作提供了很好的建议),相对于应用的总体成本,剩余的 TLS 性能问题通常很小。此外,您可以减少和分摊这些费用。(如需有关 TLS 优化和一般性的实用建议,请参阅 Ilya Grigorik 所著的高性能浏览器网络。)另请参阅 Ivan Ristic 的 OpenSSL 实战宝典防弹 SSL 和 TLS

在某些情况下,TLS 可以提高性能,主要是可以采用 HTTP/2 所带来的结果。Chris Palmer 在 2014 年 Chrome 开发者峰会上发表了有关 HTTPS 和 HTTP/2 性能的演讲

引荐来源网址标头

当用户从您的 HTTPS 网站链接到其他 HTTP 网站时,用户代理不会发送引荐来源网址标头。如果这是个问题,有多种方法可解决:

  • 其他网站应迁移到 HTTPS。如果被引荐网站可以完成本指南的在服务器上启用 HTTPS 部分,您可以将您网站中指向自己网站的链接从 http:// 更改为 https://,也可以使用相对协议链接。
  • 若要解决引荐来源网址标头方面的各种问题,请使用新的引荐来源网址政策标准

由于搜索引擎正在迁移到 HTTPS,因此将来当您迁移到 HTTPS 时,可能会看到更多引荐来源网址标头。

广告收入

通过展示广告来利用网站变现的网站运营商希望确保迁移到 HTTPS 不会减少广告展示次数。但是,由于混合内容的安全问题,HTTP <iframe> 在 HTTPS 页面中不起作用。这里存在一个棘手的集体行动问题:在广告客户通过 HTTPS 发布内容之前,网站运营商无法在不损失广告收入的情况下迁移到 HTTPS;但在网站运营者迁移到 HTTPS 之前,广告客户没有什么动力发布 HTTPS。

广告客户至少应通过 HTTPS 提供广告服务(例如完成本页面中的“在服务器上启用 HTTPS”部分)。很多广告客户在这样做。您应该要求完全不提供 HTTPS 的广告客户至少开始提供 HTTPS。您可能希望推迟完成使站内网址变为相对网址,直到有足够多的广告客户可以正常地互操作。