

**本文档仅适用于 AWS CLI 版本 1。**

我们已宣布即将终止对 AWS CLI 版本 1 的支持。建议您迁移到 AWS CLI 版本 2。有关日期、其它详细信息以及如何迁移的信息，请参阅[公告](https://aws.amazon.com/blogs/developer/cli-v1-maintenance-mode-announcement/)。有关 AWS CLI 版本 2 的相关文档，请参阅[版本 2 用户指南](https://docs.aws.amazon.com/cli/latest/userguide/)。

# 强制在 AWS CLI 中实施最低 TLS 版本
<a name="cli-security-enforcing-tls"></a>

使用 AWS Command Line Interface（AWS CLI）时，传输层安全性协议（TLS）在保护 AWS CLI 和 AWS 服务之间的通信方面起着至关重要的作用。要提高与 AWS 服务通信时的安全性，您应使用 TLS 1.2 或更高版本。

AWS CLI 和 AWS 服务可以使用提供加密、身份验证和数据完整性的 TLS 协议安全地交换数据。通过利用 TLS 协议，AWS CLI 可确保您与 AWS 服务的交互免遭未经授权的访问和数据泄露，从而增强 AWS 生态系统的整体安全性。

AWS [责任共担模式](https://aws.amazon.com/compliance/shared-responsibility-model/)适用于 AWS Command Line Interface 中的数据保护。如该模式中所述，AWS 负责保护运行所有 AWS 服务 的全球基础架构。您负责维护对托管在此基础结构上的内容的控制。您还负责您所使用的 AWS 服务 的安全配置和管理任务。有关数据保护的更多信息，请参阅[AWS CLI 中的数据保护](data-protection.md)。

要确保 AWS CLI 版本 1 不使用 TLS 1.2 之前的 TLS 版本，您可能需要重新编译 OpenSSL 以强制实施此最低版本，然后重新编译 Python 以使用新构建的 OpenSSL。

**Topics**
+ [确定当前支持的协议](#enforcing-tls-supported)
+ [编译 OpenSSL 和 Python](#enforcing-tls-compile)

## 确定当前支持的协议
<a name="enforcing-tls-supported"></a>

首先，使用 OpenSSL 创建一个自签名证书，以用于测试服务器和 Python 开发工具包。

```
$ openssl req -subj '/CN=localhost' -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365
```

然后，使用 OpenSSL 启动测试服务器。

```
$ openssl s_server -key key.pem -cert cert.pem -www
```

在新的终端窗口中，创建虚拟环境并安装 SDK for Python。

```
$ python3 -m venv test-env
source test-env/bin/activate
pip install botocore
```

创建一个名为 `check.py` 的新 Python 脚本，该脚本使用此开发工具包的底层 HTTP 库。

```
$ import urllib3
URL = 'https://localhost:4433/'

http = urllib3.PoolManager(
    ca_certs='cert.pem',
    cert_reqs='CERT_REQUIRED',
)
r = http.request('GET', URL)
print(r.data.decode('utf-8'))
```

运行您的新脚本。

```
$ python check.py
```

这将显示有关所建立的连接的详细信息。在输出中搜索“协议：”。如果输出为“TLSv1.2”或更高版本，则开发工具包默认为 TLS v1.2 或更高版本。如果它是较早的版本，则需要重新编译 OpenSSL 并重新编译 Python。

但是，即使 Python 的安装默认为 TLS v1.2 或更高版本，如果服务器不支持 TLS v1.2 或更高版本，则 Python 仍可能重新协商到 TLS v1.2 之前的版本。要检查 Python 是否不会自动重新协商到较早版本，请使用以下命令重新启动测试服务器。

```
$ openssl s_server -key key.pem -cert cert.pem -no_tls1_3 -no_tls1_2 -www
```

如果您使用的是较早版本的 OpenSSL，则可能没有可用的 `-no_tls_3` 标志。如果是这种情况，请删除该标志，因为您使用的 OpenSSL 版本不支持 TLS v1.3。然后，运行 Python 脚本。

```
$ python check.py
```

如果您正确安装了 Python 但未针对 TLS 1.2 之前的版本进行重新协商，则应收到 SSL 错误。

```
$ urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='localhost', port=4433): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1108)')))
```

如果您能够建立连接，则需要重新编译 OpenSSL 和 Python 以禁用对早于 TLS v1.2 的协议进行协商。

## 编译 OpenSSL 和 Python
<a name="enforcing-tls-compile"></a>

为了确保开发工具包或 AWS CLI 不对 TLS 1.2 之前的任何版本进行协商，您需要重新编译 OpenSSL 和 Python。要执行此操作，请复制以下内容以创建脚本并运行脚本。

```
#!/usr/bin/env bash
set -e

OPENSSL_VERSION="1.1.1d"
OPENSSL_PREFIX="/opt/openssl-with-min-tls1_2"
PYTHON_VERSION="3.8.1"
PYTHON_PREFIX="/opt/python-with-min-tls1_2"


curl -O "https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz"
tar -xzf "openssl-$OPENSSL_VERSION.tar.gz"
cd openssl-$OPENSSL_VERSION
./config --prefix=$OPENSSL_PREFIX no-ssl3 no-tls1 no-tls1_1 no-shared
make > /dev/null
sudo make install_sw > /dev/null


cd /tmp
curl -O "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz"
tar -xzf "Python-$PYTHON_VERSION.tgz"
cd Python-$PYTHON_VERSION
./configure --prefix=$PYTHON_PREFIX --with-openssl=$OPENSSL_PREFIX --disable-shared > /dev/null
make > /dev/null
sudo make install > /dev/null
```

这会编译具有静态链接的 OpenSSL 的 Python 版本，该版本不会自动协商早于 TLS 1.2 的任何版本。这也会在 `/opt/openssl-with-min-tls1_2` 目录中安装 OpenSSL，并在 `/opt/python-with-min-tls1_2` 目录中安装 Python。运行此脚本后，请确认安装新版本的 Python。

```
$ /opt/python-with-min-tls1_2/bin/python3 --version
```

这应该打印出以下内容。

```
$ Python 3.8.1
```

要确认此新版本的 Python 不协商早于 TLS 1.2 的版本，请使用新安装的 Python 版本（即 `/opt/python-with-min-tls1_2/bin/python3`）重新运行 [确定当前支持的协议](#enforcing-tls-supported) 中的步骤。