如何诊断/修复文件下载时的 CloudFormation/autoscaling SSL 错误

如何诊断/修复文件下载时的 CloudFormation/autoscaling SSL 错误

我有一个由 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 证书都作为wgetcommands:部分的一部分下载。例如,

        01_get_phpmyadmin:
          command: !Join ["",
                       ["wget -O  phpmyadmin.tgz ",
                        "https://www.phpmyadmin.net/downloads/",
                        "phpMyAdmin-latest-all-languages.tar.gz"]]
          cwd: /tmp

相关内容