在服务器上启用 HTTPS

克里斯·帕尔默
Chris Palmer
Matt Gaunt

本文介绍的步骤

  1. 创建一个 2048 位 RSA 公钥/私钥对。
  2. 生成嵌入您的公钥的证书签名请求 (CSR)。
  3. 将 CSR 与证书授权机构 (CA) 共享以接收最终证书或证书链。
  4. 将最终证书安装在非网络可访问的位置,例如 /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;请参阅下文)。配置您的 Web 服务器以使用您购买和安装的证书。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 上设置安全标记。

首先,使用严格传输安全来告知客户端,即使遵循 http:// 引用,也应始终通过 HTTPS 连接到您的服务器。这样可抵御 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。您可能希望推迟完成使站内网址变成相对网址,直到有足够多的广告客户能够正常地进行互操作。