强制使用最低版本的 TLS - Amazon Command Line Interface
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文档仅适用于 Amazon CLI 版本 1。有关 Amazon CLI 版本 2 的相关文档,请参阅版本 2 用户指南

强制使用最低版本的 TLS

要提高与 Amazon 服务通信时的安全性,您应使用 TLS 1.2 或更高版本。使用 Amazon CLI 时,Python 用于设置 TLS 版本。

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

确定当前支持的协议

首先,使用 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

为了确保开发工具包或 Amazon 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)重新运行 确定当前支持的协议 中的步骤。