

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 教程： SSL/TLS 开启配置 AL2
<a name="SSL-on-amazon-linux-2"></a>

安全套接字 Layer/Transport 层安全（SSL/TLS) creates an encrypted channel between a web server and web client that protects data in transit from being eavesdropped on. This tutorial explains how to add support manually for SSL/TLS在带有 AL2 Apache Web 服务器的 EC2 实例上。本教程假定您未使用负载均衡器。如果您正在使用 Elastic Load Balancing，则可以选择使用来自 [Amazon Certificate Manager](https://www.amazonaws.cn/certificate-manager/) 的证书在负载均衡器上配置 SSL 卸载。

由于历史原因，Web 加密通常简称为 SSL。虽然 Web 浏览器仍支持 TLS，但下一代协议 TLS 不容易受到攻击。默认情况下， AL2 为所有版本的 SSL 禁用服务器端支持。[安全标准机构](https://www.ssl.com/article/deprecating-early-tls/)认为 TLS 1.0 不安全。TLS 1.0 和 TLS 1.1 已于 2021 年 3 月正式[弃用](https://datatracker.ietf.org/doc/rfc8996/)。本教程仅包含有关启用 TLS 1.2 的指导。TLS 1.3 已于 2018 年完成， AL2 只要支持和启用底层 TLS 库（本教程中的 OpenSSL），即可使用。[客户端必须在 2023 年 6 月 28 日之前支持 TLS 1.2 或更高版本](https://www.amazonaws.cn/blogs/security/tls-1-2-required-for-aws-endpoints/)。有关更新的加密标准的更多信息，请参阅 [RFC 7568](https://tools.ietf.org/html/rfc7568) 和 [RFC 8446](https://tools.ietf.org/html/rfc8446)。

在本教程中，将现代 Web 加密简称为 TLS。

**重要**  
这些程序旨在与 AL2 一起使用。我们还假定您从新的 Amazon EC2 实例开始。如果您正在尝试设置运行不同分配的 EC2 实例，或者设置运行旧版本的实例 AL2，则本教程中的某些步骤可能无法运行。对于 Ubuntu，请参阅以下社区文档：[Open SSL on Ubuntu](https://help.ubuntu.com/community/OpenSSL)。有关 Red Hat Enterprise Linux 的信息，请参阅以下：[设置 Apache HTTP Web 服务器](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/setting-apache-http-server_deploying-different-types-of-servers)。有关其他发布版本，请参阅特定于该版本的文档。

**注意**  
或者，您可以将 Amazon Certificate Manager (ACM) 用于 Amazon Nitro 安全区，这是一种安全区应用程序，允许您在带有 Nitro Enclaves 的 Amazon EC2 实例上运行的 Web 应用程序和服务器上使用公有和私有 SSL/TLS 证书。 Amazon Nitro Enclaves 是一项 Amazon EC2 功能，它允许创建隔离的计算环境，以保护和安全地处理高度敏感的数据，例如 SSL/TLS 证书和私钥。  
适用于 Nitro Enclaves 的 ACM 与运行在 Amazon EC2 Linux 实例上的 **nginx** 结合使用，以创建私有密钥、分发证书和私有密钥以及管理证书续订。  
要使用适用于 Nitro Enclaves 的 ACM，必须使用启用了 Enclave 的 Linux 实例。  
有关更多信息，请参阅[什么是 Amazon 硝基飞地](https://docs.amazonaws.cn/enclaves/latest/user/nitro-enclave.html)？ 以及[Amazon Certificate Manager 《Nitro Enclaves](https://docs.amazonaws.cn/enclaves/latest/user/nitro-enclave-refapp.html) 用户指南》中的 *Amazon Nitro* Enclaves。

**Topics**
+ [

## 前提条件
](#ssl_prereq)
+ [

## 步骤 1：在服务器上启用 TLS
](#ssl_enable)
+ [

## 步骤 2：获取 CA 签名的证书
](#ssl_certificate)
+ [

## 步骤 3：测试和强化安全配置
](#ssl_test)
+ [

## 故障排除
](#troubleshooting)

## 前提条件
<a name="ssl_prereq"></a>

在开始本教程之前，请完成以下步骤：
+ 启动由 Amazon EBS 支持的 AL2 实例。有关更多信息，请参阅*《Amazon EC2 用户指南》*中的[启动实例](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/ec2-launch-instance-wizard.html)。
+ 配置安全组以允许您的实例接受以下 TCP 端口上的连接：
  + SSH (端口 22)
  + HTTP (端口 80)
  + HTTPS (端口 443)

  有关更多信息，请参阅《Amazon EC2 用户指南》**中的[安全组规则](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/security-group-rules.html)。
+ 安装 Apache Web 服务器。有关 step-by-step说明，请参阅[教程：在上安装 LAMP Web 服务器 AL2](ec2-lamp-amazon-linux-2.md)。仅需要 httpd 包及其依赖项，因此可以忽略涉及 PHP 和 MariaDB 的说明。
+ 要识别和验证网站，TLS 公有密钥基础设施 (PKI) 依赖于域名系统 (DNS)。要使用 EC2 实例托管公共网站，您需要为 Web 服务器注册一个域名，或者将现有域名转让给您的 Amazon EC2 主机。可通过很多第三方域注册和 DNS 托管服务来执行此操作，也可以使用 [Amazon Route 53](https://docs.amazonaws.cn/Route53/latest/DeveloperGuide/Welcome.html) 执行此操作。

## 步骤 1：在服务器上启用 TLS
<a name="ssl_enable"></a>

**选项：使用 Automation 完成本教程**  
要使用 Amazon Systems Manager 自动化而不是以下任务来完成本教程，请运行[自动化文档](https://console.amazonaws.cn/systems-manager/documents/AWSDocs-Configure-SSL-TLS-AL2/)。

此过程将引导您完成 AL2 使用自签名数字证书设置 TLS 的过程。

**注意**  
自签名证书对于测试是可接受的，但对于生产不是。如果您将自签名证书公开到 Internet，您网站的访客将会看到安全警告。

**在服务器上启用 TLS**

1. [连接到您的实例](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/connect-to-linux-instance.html)并确认 Apache 正在运行。

   ```
   [ec2-user ~]$ sudo systemctl is-enabled httpd
   ```

   如果返回的值不是“启用”，则启动 Apache 并将它设置为每次随系统一起启动。

   ```
   [ec2-user ~]$ sudo systemctl start httpd && sudo systemctl enable httpd
   ```

1. 为确保您的所有软件包都处于最新状态，请对您的实例执行快速软件更新。此过程可能需要几分钟的时间，但必须确保您拥有最新的安全更新和缺陷修复。
**注意**  
`-y` 选项安装更新时不提示确认。如果您希望在安装前检查更新，则可以忽略该选项。

   ```
   [ec2-user ~]$ sudo yum update -y
   ```

1. 现在，您的实例是最新的，请安装 Apache 模块 `mod_ssl` 以添加 TLS 支持。

   ```
   [ec2-user ~]$ sudo yum install -y mod_ssl
   ```

   您的实例现在具有以下文件，可使用这些文件配置安全服务器并创建证书以进行测试：
   +  `/etc/httpd/conf.d/ssl.conf` 

     mod\$1ssl 的配置文件。它包含一些*指令* 以指示 Apache 在何处查找以下信息：加密密钥和证书、要允许的 TLS 协议版本以及要接受的加密密码。
   + `/etc/pki/tls/certs/make-dummy-cert`

     用于为服务器主机生成自签名 X.509 证书和私有密钥的脚本。要测试是否正确设置 Apache 以使用 TLS，该证书是非常有用的。由于不提供身份证明，因此，不应在生产环境中使用该证书。如果在生产环境中使用该证书，则将在 Web 浏览器中触发警告。

1. 运行脚本以生成自签名虚拟证书和密钥以进行测试。

   ```
   [ec2-user ~]$ cd /etc/pki/tls/certs
   sudo ./make-dummy-cert localhost.crt
   ```

   这会在 `/etc/pki/tls/certs/` 目录中生成一个新文件 `localhost.crt`。指定的文件名与 `/etc/httpd/conf.d/ssl.conf` 中的 **SSLCertificateFile** 指令指定的默认值匹配。

   该文件包含自签名证书以及证书的私有密钥。Apache 要求证书和密钥采用 PEM 格式，其中包含 Base64 编码的 ASCII 字符，并用“BEGIN”和“END”行框起来，如以下简短示例所示。

   ```
   -----BEGIN PRIVATE KEY-----
   MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD2KKx/8Zk94m1q
   3gQMZF9ZN66Ls19+3tHAgQ5Fpo9KJDhzLjOOCI8u1PTcGmAah5kEitCEc0wzmNeo
   BCl0wYR6G0rGaKtK9Dn7CuIjvubtUysVyQoMVPQ97ldeakHWeRMiEJFXg6kZZ0vr
   GvwnKoMh3DlK44D9dX7IDua2PlYx5+eroA+1Lqf32ZSaAO0bBIMIYTHigwbHMZoT
   ...
   56tE7THvH7vOEf4/iUOsIrEzaMaJ0mqkmY1A70qQGQKBgBF3H1qNRNHuyMcPODFs
   27hDzPDinrquSEvoZIggkDMlh2irTiipJ/GhkvTpoQlv0fK/VXw8vSgeaBuhwJvS
   LXU9HvYq0U6O4FgD3nAyB9hI0BE13r1HjUvbjT7moH+RhnNz6eqqdscCS09VtRAo
   4QQvAqOa8UheYeoXLdWcHaLP
   -----END PRIVATE KEY-----                    
   
   -----BEGIN CERTIFICATE-----
   MIIEazCCA1OgAwIBAgICWxQwDQYJKoZIhvcNAQELBQAwgbExCzAJBgNVBAYTAi0t
   MRIwEAYDVQQIDAlTb21lU3RhdGUxETAPBgNVBAcMCFNvbWVDaXR5MRkwFwYDVQQK
   DBBTb21lT3JnYW5pemF0aW9uMR8wHQYDVQQLDBZTb21lT3JnYW5pemF0aW9uYWxV
   bml0MRkwFwYDVQQDDBBpcC0xNzItMzEtMjAtMjM2MSQwIgYJKoZIhvcNAQkBFhVy
   ...
   z5rRUE/XzxRLBZOoWZpNWTXJkQ3uFYH6s/sBwtHpKKZMzOvDedREjNKAvk4ws6F0
   CuIjvubtUysVyQoMVPQ97ldeakHWeRMiEJFXg6kZZ0vrGvwnKoMh3DlK44D9dlU3
   WanXWehT6FiSZvB4sTEXXJN2jdw8g+sHGnZ8zCOsclknYhHrCVD2vnBlZJKSZvak
   3ZazhBxtQSukFMOnWPP2a0DMMFGYUHOd0BQE8sBJxg==
   -----END CERTIFICATE-----
   ```

   文件名和扩展名只是为了提供便利，对功能没有影响。例如，只要 `ssl.conf` 文件中的相关指令使用相同的名称，您就可以将证书命名为 `cert.crt`、`cert.pem` 或任何其他文件名。
**注意**  
在使用您自己的自定义文件替换默认 TLS 文件时，请确保它们采用 PEM 格式。

1. 使用您常用的文本编辑器（如 **vim** 或 **nano**）以根用户身份打开 `/etc/httpd/conf.d/ssl.conf` 文件并注释掉以下行，因为自签名虚拟证书也包含密钥。如果在完成下一步之前没有注释掉该行，Apache 服务将无法启动。

   ```
   SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
   ```

1. 重启 Apache。

   ```
   [ec2-user ~]$ sudo systemctl restart httpd
   ```
**注意**  
确保 TCP 端口 443 在您的 EC2 实例上是可访问的，如之前所述。

1. 现在，您的 Apache Web 服务器应通过端口 443 支持 HTTPS (安全 HTTP)。通过将您的 EC2 实例的 IP 地址或完全限定域名与前缀 **https://** 一起输入浏览器 URL 栏中来对其进行测试。

   由于您正在使用自签名的不可信主机证书连接到站点，因此您的浏览器可能会显示一系列安全警告。忽视这些警告并继续连接站点。

   如果默认 Apache 测试页面打开，这意味着您已成功在服务器上配置 TLS。在浏览器和服务器之间传输的所有数据现在都已加密。
**注意**  
为了防止站点访问者遇到警告屏幕，您必须获取一个可信 CA 签名证书，该证书不仅进行加密，而且还公开验证您是否为站点拥有者。

## 步骤 2：获取 CA 签名的证书
<a name="ssl_certificate"></a>

您可以使用以下过程获取 CA 签名证书：
+ 从私有密钥生成证书签名请求 (CSR)
+ 将 CSR 提交给证书颁发机构 (CA)
+ 获取签名的主机证书
+ 配置 Apache 以使用证书

从加密角度看，自签名 TLS X.509 主机证书与 CA 签名证书完全相同。二者之间的区别在于社交层面，而非数学层面。CA 承诺，在向申请者颁发证书之前，至少验证域的所有权。每个 Web 浏览器都包含浏览器供应商 CAs 信任的列表。X.509 证书主要包含一个与您的私有服务器密钥对应的公有密钥和一个以加密方式与该公有密钥关联的 CA 的签名。当浏览器通过 HTTPS 连接到 Web 服务器时，服务器会提供一份证书，供浏览器根据其可信列表进行核对 CAs。如果签署人位于列表上，或可通过由其他可信签署人组成的*一系列信任*访问，则浏览器将与服务器协商一个快速加密数据通道并加载页面。

由于验证请求需要投入人力，证书通常会产生费用，因此应货比三家。少数人免费 CAs 提供基本级别的证书。其中最引人注目的是 CAs L [et's Encrypt](https://letsencrypt.org/) 项目，该项目还支持证书创建和续订过程的自动化。有关使用 Let's Encrypt 证书的更多信息，请参阅[获取 Certbot](https://eff-certbot.readthedocs.io/en/stable/install.html)。

如果您打算提供商业级服务，[Amazon Certificate Manager](https://docs.amazonaws.cn/acm/latest/userguide/acm-overview.html) 是一个不错的选择。

主机证书的基础是密钥。从 2019 年开始，[政府](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf)和[行业](https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.6.5.pdf)群体建议 RSA 密钥使用 2048 位的最小密钥（模数）大小，旨在将文档一直保护到 2030 年。OpenSSL 在中生成的默认模数大小为 2048 位，适用于 AL2 在 CA 签名的证书中使用。在以下过程中，为需要自定义密钥的人员提供了一个可选步骤，例如，具有较大模数或使用不同加密算法的步骤。

**重要**  
除非您拥有注册并托管的 DNS 域，否则，有关获取 CA 签名主机证书的这些说明不适用。

**获取 CA 签名的证书**

1.  [连接到](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/connect-to-linux-instance.html)您的实例并导航到etc/pki/tls/private//。这是存储 TLS 的服务器私有密钥的目录。如果您希望使用现有的主机密钥生成 CSR，请跳到步骤 3。

1. (可选) 生成新的私有密钥。下面是一些密钥配置示例。任何生成的密钥都可用于您的 Web 服务器，但它们实施安全的程度和类型有所不同。
   + **示例 1：**创建默认 RSA 主机密钥。生成的文件 **custom.key** 是一个 2048 位 RSA 私有密钥。

     ```
     [ec2-user ~]$ sudo openssl genrsa -out custom.key
     ```
   + **示例 2：**创建具有更大模数的更严格的 RSA 密钥。生成的文件 **custom.key** 是一个 4096 位 RSA 私有密钥。

     ```
     [ec2-user ~]$ sudo openssl genrsa -out custom.key 4096
     ```
   + **示例 3：**创建具有密码保护的 4096 位加密的 RSA 密钥。生成的文件 **custom.key** 是一个已使用 AES-128 密码加密的 4096 位 RSA 私有密钥。
**重要**  
对密钥进行加密可增强安全性，但由于加密的密钥需要密码，因此依赖于加密密钥的服务无法自动启动。每当您使用此密钥时，都必须通过 SSH 连接提供密码（在上一示例中为“abcde12345”）。

     ```
     [ec2-user ~]$ sudo openssl genrsa -aes128 -passout pass:abcde12345 -out custom.key 4096
     ```
   + **示例 4：**使用非 RSA 密码创建密钥。RSA 加密可能相对较慢，因为其公有密钥的大小基于两个大素数的乘积。不过，可以为 TLS 创建使用非 RSA 密码的密钥。在交付同等级别的安全性时，基于椭圆曲线的数学运算的密钥更小，计算起来更快。

     ```
     [ec2-user ~]$ sudo openssl ecparam -name prime256v1 -out custom.key -genkey
     ```

     结果为一个使用 prime256v1（OpenSSL 支持的“命名曲线”）的 256 位椭圆曲线私有密钥。[根据 NIST](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r4.pdf)，其加密强度略高于 2048 位 RSA 密钥。
**注意**  
并非所有密钥都 CAs 提供与 RSA elliptic-curve-based 密钥相同的支持级别。

   确保新的私钥具有高度限制的所有权和权限（owner=root，group=root，仅适用于所有者）。 read/write 命令将如以下示例所示。

   ```
   [ec2-user ~]$ sudo chown root:root custom.key
   [ec2-user ~]$ sudo chmod 600 custom.key
   [ec2-user ~]$ ls -al custom.key
   ```

   上述命令生成以下结果。

   ```
   -rw------- root root custom.key
   ```

    在创建并配置满意的密钥后，可以创建 CSR。

1. 使用您首选的密钥创建 CSR。下面的示例使用了 **custom.key**。

   ```
   [ec2-user ~]$ sudo openssl req -new -key custom.key -out csr.pem
   ```

   OpenSSL 将打开一个对话框，并提示您输入下表中显示的信息。对于基本的经域验证的主机证书来说，除 **Common Name** 以外的所有字段都是可选字段。    
[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/linux/al2/ug/SSL-on-amazon-linux-2.html)

   最后，OpenSSL 将提示您输入可选的质询密码。此密码仅适用于 CSR 和您与 CA 之间的事务，因此请遵循 CA 提供的有关此密码以及其他可选字段、可选公司名的建议。CSR 质询密码不会影响服务器操作。

   生成的文件 **csr.pem** 包含您的公有密钥、您的公有密钥的数字签名以及您输入的元数据。

1. 将 CSR 提交给 CA。这通常包括在文本编辑器中打开 CSR 文件并将内容复制到 Web 表格中。此时，可能会要求您提供一个或多个主题备用名称 (SANs) 以放在证书上。如果 **www.example.com** 是公用名，则 **example.com** 将是一个很好的 SAN，反之亦然。您网站的访客如果输入这两个名称的任何一个，便可看到一个没有错误的连接。如果您的 CA Web 表单允许，请在列表中包含常用名 SANs。有些是自动 CAs 包含的。

   在您的请求获得批准后，您将收到一个由 CA 签署的新主机证书。此外，系统可能会指示您下载*中间证书*文件，该文件包含完成 CA 的信任链所需的其他证书。
**注意**  
您的 CA 可能会针对各种用途发送多种格式的文件。在本教程中，您应只使用 PEM 格式的证书文件，此格式通常会（但不总是）标有 `.pem` 或 `.crt` 文件扩展名。如果您不确定要使用哪个文件，请使用文本编辑器打开这些文件，并查找一个包含一个或多个以下面的行开始的块的文件。  

   ```
   - - - - -BEGIN CERTIFICATE - - - - - 
   ```
该文件还应以下面的行结束。  

   ```
   - - - -END CERTIFICATE - - - - -
   ```
您还可以在命令行上测试文件，如下所示。  

   ```
   [ec2-user certs]$ openssl x509 -in certificate.crt -text
   ```
验证这些行是否显示在文件中。请勿使用结尾为 `.p7b`、`.p7c` 或类似文件扩展名的文件。

1. 将新的 CA 签名证书和任何中间证书放在 `/etc/pki/tls/certs` 目录中。
**注意**  
可通过多种方法将新证书上传到 EC2 实例，但最直接、最有益的方法是在本地计算机和 EC2 实例上打开一个文本编辑器（例如，vi、nano 或记事本），然后在这两者之间复制并粘贴文件内容。在 EC2 实例上执行这些操作时，您需要根 [sudo] 权限。这样，一旦有任何权限或路径问题，您可以立即看到。但请小心操作，不要在复制内容时添加任何多余的行或以任何方式更改内容。

   在`/etc/pki/tls/certs`目录内部，检查文件所有权、组和权限设置是否与限制性很强的 AL2 默认值相匹配（owner=root，group=root，仅适用于所有者）。 read/write 以下示例显示了要使用的命令。

   ```
   [ec2-user certs]$ sudo chown root:root custom.crt
   [ec2-user certs]$ sudo chmod 600 custom.crt
   [ec2-user certs]$ ls -al custom.crt
   ```

   这些命令应生成以下结果。

   ```
   -rw------- root root custom.crt
   ```

   中间证书文件的权限并不严格 (所有者=根、组=根、所有者可以写入、组可以读取、任何人均可读取)。以下示例显示了要使用的命令。

   ```
   [ec2-user certs]$ sudo chown root:root intermediate.crt
   [ec2-user certs]$ sudo chmod 644 intermediate.crt
   [ec2-user certs]$ ls -al intermediate.crt
   ```

   这些命令应生成以下结果。

   ```
   -rw-r--r-- root root intermediate.crt
   ```

1. 将用于创建 CSR 的私有密钥放在 `/etc/pki/tls/private/` 目录中。
**注意**  
可通过多种方法将自定义密钥上传到 EC2 实例，但最直接、最有益的方法是在本地计算机和 EC2 实例上打开一个文本编辑器（例如，vi、nano 或记事本），然后在这两者之间复制并粘贴文件内容。在 EC2 实例上执行这些操作时，您需要根 [sudo] 权限。这样，一旦有任何权限或路径问题，您可以立即看到。但请小心操作，不要在复制内容时添加任何多余的行或以任何方式更改内容。

   在`/etc/pki/tls/private`目录内部，使用以下命令验证文件所有权、组和权限设置是否与高度严格的 AL2 默认值相匹配（owner=root，group=root，仅适用于所有者）。 read/write 

   ```
   [ec2-user private]$ sudo chown root:root custom.key
   [ec2-user private]$ sudo chmod 600 custom.key
   [ec2-user private]$ ls -al custom.key
   ```

   这些命令应生成以下结果。

   ```
   -rw------- root root custom.key
   ```

1. 编辑 `/etc/httpd/conf.d/ssl.conf` 以反映您的新证书和密钥文件。

   1. 在 Apache 的 `SSLCertificateFile` 指令中提供 CA 签名主机证书的路径和文件名：

      ```
      SSLCertificateFile /etc/pki/tls/certs/custom.crt
      ```

   1. 如果您收到一个中间证书文件（此示例中为 `intermediate.crt`），请使用 Apache 的 `SSLCACertificateFile` 指令提供其路径和文件名：

      ```
      SSLCACertificateFile /etc/pki/tls/certs/intermediate.crt
      ```
**注意**  
有些证书将主机证书和中间证书 CAs 合并到一个文件中，因此没有必要使用该`SSLCACertificateFile`指令。请查询您的 CA 提供的说明。

   1. 在 Apache 的 `SSLCertificateKeyFile` 指令中提供私有密钥的路径和文件名（在该示例中为 `custom.key`）：

      ```
      SSLCertificateKeyFile /etc/pki/tls/private/custom.key
      ```

1. 保存 `/etc/httpd/conf.d/ssl.conf` 并重启 Apache。

   ```
   [ec2-user ~]$ sudo systemctl restart httpd
   ```

1. 通过在浏览器 URL 栏中输入带有 `https://` 前缀的域名来测试您的服务器。您的浏览器应通过 HTTPS 加载测试页面而不会产生错误。

## 步骤 3：测试和强化安全配置
<a name="ssl_test"></a>

在 TLS 可操作且公开发布后，应测试其实际安全性。使用在线服务（例如 [Qualys SSL Labs](https://www.ssllabs.com/ssltest/analyze.html)，该服务可对您的安全设置执行免费的全面分析）可轻松执行此操作。根据结果，您可以决定通过控制接受的协议、首选的密码和排除的密码来强化默认安全配置。有关更多信息，请参阅 [Qualys 如何用公式表示其分数](https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide)。

**重要**  
实际测试对服务器的安全性非常重要。少量配置错误可能导致严重的安全漏洞和数据丢失。由于建议的安全实践会不断变化以响应调查和新兴威胁，因此定期安全审核对于良好的服务器管理来说是必不可少的。

在 [Qualys SSL Labs](https://www.ssllabs.com/ssltest/analyze.html) 站点上，使用 **www.example.com** 格式输入服务器的完全限定域名。约两分钟后，您将收到您站点的评级 (从 A 到 F) 和结果的详细信息。下表汇总了设置与默认 Apache 配置相同且具有默认 Cert AL2 bot 证书的域的报告。


|  |  | 
| --- |--- |
| 总评 | B | 
| 证书 | 100% | 
| 协议支持 | 95% | 
| 密钥交换 | 70% | 
| 密码强度 | 90% | 

虽然概述信息显示配置基本正确，但详细报告标记了几个潜在的问题（在此处按严重性顺序列出）：

✗ **某些较旧的浏览器支持使用该 RC4 密码**。密码是加密算法的数学核心。 RC4[是一种用于加密 TLS 数据流的快速密码，众所周知，它有几个严重的弱点。](http://www.imperva.com/docs/hii_attacking_ssl_when_using_rc4.pdf)除非您有充分理由支持旧版浏览器，否则，应禁用该密码。

✗ **支持旧 TLS 版本。**该配置支持 TLS 1.0（已弃用）和 TLS 1.1（即将弃用）。从 2018 年开始，仅建议使用 TLS 1.2。

✗ **不完全支持向前保密性。**[向前保密性](https://en.wikipedia.org/wiki/Forward_secrecy)是一种算法功能，它使用从私有密钥派生的临时会话密钥进行加密。这意味着，在实践中，攻击者无法解密 HTTPS 数据，即使他们拥有 Web 服务器的长期私有密钥。

**纠正 TLS 配置并供将来使用**

1. 在文本编辑器中打开 `/etc/httpd/conf.d/ssl.conf` 配置文件，并在以下行的开头输入“\$1”以注释掉该行。

   ```
   #SSLProtocol all -SSLv3
   ```

1. 添加以下指令：

   ```
   #SSLProtocol all -SSLv3
   SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
   ```

   该指令显式禁用 SSL 版本 2 和 3 以及 TLS 版本 1.0 和 1.1。现在，服务器拒绝接受与使用 TLS 1.2 以外的任何协议的客户端之间的加密连接。指令中的冗长文字更清楚地向人类读者阐述为服务器配置的用途。
**注意**  
以此方式禁用 TLS 1.0 和 1.1 版可阻止一小部分过时的 Web 浏览器访问您的网站。

**修改允许的密码列表**

1. 在 `/etc/httpd/conf.d/ssl.conf` 配置文件中，找到包含 **SSLCipherSuite** 指令的部分，并通过在现有行的开头输入“\$1”来注释掉该行。

   ```
   #SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
   ```

1. 指定显式的密码套件，并指定密码顺序以优先使用向前保密性并避免不安全的密码。此处使用的 `SSLCipherSuite` 指令基于 [Mozilla SSL 配置生成器](https://mozilla.github.io/server-side-tls/ssl-config-generator/)的输出，该生成器根据服务器上运行的特定软件定制 TLS 配置。首先，通过使用以下命令的输出确定 Apache 和 OpenSSL 版本。

   ```
   [ec2-user ~]$ yum list installed | grep httpd
   
   [ec2-user ~]$ yum list installed | grep openssl
   ```

   例如，如果返回的信息是 Apache 2.4.34 和 OpenSSL 1.0.2，我们将其输入到生成器中。如果您选择“现代”兼容性模型，这将创建一条 `SSLCipherSuite` 指令，虽然该指令积极实施安全性，但仍适用于大多数浏览器。如果您的软件不支持现代配置，则可以更新软件或改为选择“中间”配置。

   ```
   SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:
   ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
   ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
   ```

   选定的密码名称中包含 *ECDHE*，它是 *Elliptic Curve Diffie-Hellman Ephemeral* 的缩写。术语 *ephemeral* 表示向前保密性。顺便说一句，这些密码不支持。 RC4

   建议您使用密码的明确列表，而不是依赖于内容不可见的默认值或简短指令。

   将生成的指令复制到 `/etc/httpd/conf.d/ssl.conf` 中。
**注意**  
此处为方便阅读将指令显示为几行，但在复制到 `/etc/httpd/conf.d/ssl.conf` 时，该指令必须位于一行中，并且密码名称之间只有一个冒号（无空格）。

1. 最后，通过删除以下行开头的“\$1”来取消对该行的注释。

   ```
   #SSLHonorCipherOrder on
   ```

   该指令强制服务器优先使用排名较高的密码，包括（在该示例中）支持向前保密性的密码。启用此指令后，服务器会在回滚到允许的安全性较低的密码之前尝试建立高度安全的连接。

在完成这两个过程后，将更改保存到 `/etc/httpd/conf.d/ssl.conf` 并重新启动 Apache。

如果您在 [Qualys SSL Labs](https://www.ssllabs.com/ssltest/analyze.html) 上再次测试该域名，您应该会看到 RC4 漏洞和其他警告已消失，摘要如下所示。


|  |  | 
| --- |--- |
| 总评 | A | 
| 证书 | 100% | 
| 协议支持 | 100% | 
| 密钥交换 | 90% | 
| 密码强度 | 90% | 

在每次更新 OpenSSL 时，将引入新的密码并删除对旧密码的支持。保留您的 EC2 AL2 实例 up-to-date，留意来自 [OpenSSL](https://www.openssl.org/) 的安全公告，并警惕技术媒体上有关新安全漏洞的报告。

## 故障排除
<a name="troubleshooting"></a>
+ **除非我输入密码，否则我的 Apache Web 服务器不会启动**

  如果您安装了受密码保护的加密的私有服务器密钥，这是预期行为。

  您可以从密钥中删除加密和密码要求。假设在默认目录中具有一个称为 `custom.key` 的加密的私有 RSA 密钥，并且此密钥上的密码是 **abcde12345**，则对 EC2 实例运行以下命令可生成此密钥的未加密版本。

  ```
  [ec2-user ~]$ cd /etc/pki/tls/private/
  [ec2-user private]$ sudo cp custom.key custom.key.bak
  [ec2-user private]$ sudo openssl rsa -in custom.key -passin pass:abcde12345 -out custom.key.nocrypt 
  [ec2-user private]$ sudo mv custom.key.nocrypt custom.key
  [ec2-user private]$ sudo chown root:root custom.key
  [ec2-user private]$ sudo chmod 600 custom.key
  [ec2-user private]$ sudo systemctl restart httpd
  ```

  Apache 现在启动时应该不会提示您提供密码。
+  **我在运行 sudo yum install -y mod\$1ssl 时收到了错误。**

  在为 SSL 安装所需的程序包时，您可能会看到与以下内容类似的错误。

  ```
  Error: httpd24-tools conflicts with httpd-tools-2.2.34-1.16.amzn1.x86_64
  Error: httpd24 conflicts with httpd-2.2.34-1.16.amzn1.x86_64
  ```

  这通常意味着您的 EC2 实例未运行 AL2。本教程仅支持从官方 AL2 AMI 新创建的实例。