![如何诊断/修复文件下载时的 CloudFormation/autoscaling SSL 错误](https://linux22.com/image/771120/%E5%A6%82%E4%BD%95%E8%AF%8A%E6%96%AD%2F%E4%BF%AE%E5%A4%8D%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E6%97%B6%E7%9A%84%20CloudFormation%2Fautoscaling%20SSL%20%E9%94%99%E8%AF%AF.png)
我有一个由 AWS CloudFormation 创建的自动扩展组。它在 Amazon Linux 2 上运行。上周,它运行良好。现在,新实例在尝试下载 phpMyAdmin 时会抛出“证书已过期”错误。它似乎cfn-init
运行yum
良好,并且可以从 S3 中抓取文件,但在抓取远程文件时不起作用(似乎使用 Python 就可以)。
编辑:见下文,但我最初以为这是 Python 脚本的问题。我不再确定这是真的,因为它在不同的自动缩放组中抓取不同的文件时工作正常。所以......现在我认为这实际上是 phpMyAdmin 上的证书的问题,但是......我不确定。而且我仍然不知道如何进一步诊断。
/var/log/cfn-init.log:
2021-10-06 10:08:24,895 [INFO] -----------------------Starting build------------
-----------
2021-10-06 10:08:24,896 [DEBUG] Not setting a reboot trigger as scheduling suppo
rt is not available
2021-10-06 10:08:24,898 [INFO] Running configSets: default
2021-10-06 10:08:24,899 [INFO] Running configSet default
2021-10-06 10:08:24,906 [INFO] Running config config
2021-10-06 10:08:34,173 [DEBUG] Installing/updating ['mod_ssl', 'ksh', 'httpd']
via yum
2021-10-06 10:08:37,523 [INFO] Yum installed ['mod_ssl', 'ksh', 'httpd']
2021-10-06 10:08:37,523 [DEBUG] No groups specified
2021-10-06 10:08:37,523 [DEBUG] No users specified
2021-10-06 10:08:37,523 [DEBUG] No sources specified
... [successfully installs some files from S3 ... ]
2021-10-06 10:08:37,621 [DEBUG] Writing content to /tmp/phpmyadmin.tgz
2021-10-06 10:08:37,621 [DEBUG] Retrieving contents from https://www.phpmyadmin.
net/downloads/phpMyAdmin-latest-all-languages.tar.gz
2021-10-06 10:08:37,640 [ERROR] SSLError
Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages
/urllib3/connectionpool.py", line 544, in urlopen
body=body, headers=headers)
File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages
/urllib3/connectionpool.py", line 341, in _make_request
self._validate_conn(conn)
File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages
/urllib3/connectionpool.py", line 762, in _validate_conn
conn.connect()
File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages
/urllib3/connection.py", line 238, in connect
ssl_version=resolved_ssl_version)
File "/usr/lib/python3.7/site-packages/cfnbootstrap/packages/requests/packages/urllib3/util/ssl_.py", line 265, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "/usr/lib64/python3.7/ssl.py", line 423, in wrap_socket
session=session
File "/usr/lib64/python3.7/ssl.py", line 870, in _create
self.do_handshake()
File "/usr/lib64/python3.7/ssl.py", line 1139, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1091)
...
但如果我登录机器,下载wget
就可以了,编辑不再正确: 所以我不认为这是远程站点的问题,我认为这是与cfn-init
相关的 Python 脚本有关的问题。
编辑:从 CloudFormation 创建的另一个自动扩展组可以进行远程下载:
...
2021-10-07 04:21:10,855 [DEBUG] Writing content to /tmp/mysql80.rpm
2021-10-07 04:21:10,855 [DEBUG] Retrieving contents from https://dev.mysql.com/g
et/mysql80-community-release-el7-2.noarch.rpm
2021-10-07 04:21:11,425 [DEBUG] Setting mode for /tmp/mysql80.rpm to 000600
2021-10-07 04:21:11,425 [DEBUG] Setting owner 0 and group 0 for /tmp/mysql80.rpm
...
因此,它可以从 成功下载https://dev.mysql.com/
,但从 失败并显示“证书过期” https://www.phpmyadmin.net
,即使wget
通过浏览器直接访问那里不会显示任何错误。
结束编辑
关于如何调试这个问题有什么想法吗?
答案1
简短回答:
使用 openssl 查找是否存在过期的证书:
openssl s_client -showcerts -connect <falingwebsite.com>:443 | grep "certificate has expired"
获取新的、未过期的证书并将其附加到 AWS 包 ca_bundle:
cat <newcert>.pem >> /path/to/your/python/env/lib/python3.9/site-packages/cfnbootstrap/packages/requests/cacert.pem
长答案:
我最终编写了一些 Python 脚本来尝试下载服务器端证书,以查看下载过程中是否出了问题。我从未直接使用下载证书urllib3
,但在 StackOverflow 上查找,@clockwatcher 发现了实际的问题,而且它似乎可能会影响其他人,而不仅仅是 phpMyAdmin。
这与DST Root CA X3 到期,该事件发生于 9 月 30 日。AWS 未将新证书包含在其捆绑的已批准证书中,因此您必须手动添加新证书。
您可以从以下位置获取自签名的 ISRG Root X1 pem 文件LetsEncrypt,然后按照上面的方法将其添加到文件cfnbootstrap
中。ca_cert.pem
现在,这解决了在有一台正在运行的机器的情况下的问题;然而,对于自动缩放组来说,这仍然是一个问题,因为没有简单的方法来使用
AWS::CloudFormation::Init:
config:
files:
/path/to/file:
source: https://somewhere.using.letsencrypt.com/file
行为。因此,使用该范例的 CloudFormation 模板中的任何地方都需要重写,以便您实际想要的文件和 LetsEncrypt 证书都作为wget
该commands:
部分的一部分下载。例如,
01_get_phpmyadmin:
command: !Join ["",
["wget -O phpmyadmin.tgz ",
"https://www.phpmyadmin.net/downloads/",
"phpMyAdmin-latest-all-languages.tar.gz"]]
cwd: /tmp