如何使用 urllib3 下载服务器 SSL 证书?
How to download server SSL certificate with urllib3?
标题确实是个问题 — 在尝试建立 HTTPS 连接时,我如何urllib3
从远程服务器下载 SSL 证书?
背景
在 ServerVault 领域,我试图弄清 a problem with AWS autoscaling groups 无法下载 phpMyAdmin 作为其初始化进程的一部分。作为尝试诊断的一部分,我现在在 Whosebug 的土地上,使用 python 脚本。我在这里:
#! /usr/bin/python3
import cfnbootstrap
from cfnbootstrap.packages import requests
from requests import utils
from requests.utils import DEFAULT_CA_BUNDLE_PATH
from requests.packages import urllib3
conn = urllib3.connection_from_url("https://dev.mysql.com/", retries=False)
conn.cert_reqs = 'CERT_REQUIRED'
conn.ca_certs = DEFAULT_CA_BUNDLE_PATH
response = conn.request("GET", "/get/")
conn.close()
print(response.status)
效果很好:
$ ./urltest.py
404
但是,如果我把它改成
conn = urllib3.connection_from_url("https://www.phpmyadmin.net", retries=False)
response = conn.request("GET", "/downloads/")
我运行进入我的问题:
$ ./urltest.py
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)
好像不太可能是证书过期了,好像我用浏览器手动去查了一下,万事大吉;但是,我想确切地了解 urllib3
认为哪些证书已过期。我该怎么做?
注意:我没有直接调用 certify.where()
,因为我不确定 AWS 在后台执行什么 shananigans,但因为他们的脚本是 auto-installed 作为启动实例的一部分,我对此无能为力,所以我尝试使用他们的内部进程。
问题是 Let's Encrypt DST Root CA X3 于 9 月 30 日到期 -- https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/。请求包不信任 ISRG Root X1 证书,并尝试使用过期的证书对其进行验证。
从 https://letsencrypt.org/certificates/ 下载 ISRG X1 PEM 并将其添加到 cfnbootstrap 库的 cacert.pem 文件。
cat isgrootx1.pem >> /path/to/your/python/env/lib/python3.9/site-packages/cfnbootstrap/packages/requests/cacert.pem
您可以通过以下方式找到 cacert.pem 的位置:
from cfnbootstrap.packages.requests.certs import where
print(where())
另外...我会更改您的代码以确保您实际使用的是 cfn 打包请求模块而不是独立请求。否则,您可能需要在这两个位置进行更新。
from cfnbootstrap.packages.requests.utils import DEFAULT_CA_BUNDLE_PATH
from cfnbootstrap.packages.requests.packages import urllib3
conn = urllib3.connection_from_url("https://www.phpmyadmin.net/", retries=False)
conn.cert_reqs = 'CERT_REQUIRED'
conn.ca_certs = DEFAULT_CA_BUNDLE_PATH
response = conn.request("GET", "/get/")
conn.close()
print(response.status)
如果您确实想要更新独立请求和使用 cfnbootstrap 打包的请求,请使用以下命令查找并更新两个 cacert 路径:
import requests
import cfnbootstrap.packages.requests
print(requests.certs.where())
print(cfnbootstrap.packages.requests.certs.where())
标题确实是个问题 — 在尝试建立 HTTPS 连接时,我如何urllib3
从远程服务器下载 SSL 证书?
背景 在 ServerVault 领域,我试图弄清 a problem with AWS autoscaling groups 无法下载 phpMyAdmin 作为其初始化进程的一部分。作为尝试诊断的一部分,我现在在 Whosebug 的土地上,使用 python 脚本。我在这里:
#! /usr/bin/python3
import cfnbootstrap
from cfnbootstrap.packages import requests
from requests import utils
from requests.utils import DEFAULT_CA_BUNDLE_PATH
from requests.packages import urllib3
conn = urllib3.connection_from_url("https://dev.mysql.com/", retries=False)
conn.cert_reqs = 'CERT_REQUIRED'
conn.ca_certs = DEFAULT_CA_BUNDLE_PATH
response = conn.request("GET", "/get/")
conn.close()
print(response.status)
效果很好:
$ ./urltest.py
404
但是,如果我把它改成
conn = urllib3.connection_from_url("https://www.phpmyadmin.net", retries=False)
response = conn.request("GET", "/downloads/")
我运行进入我的问题:
$ ./urltest.py
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)
好像不太可能是证书过期了,好像我用浏览器手动去查了一下,万事大吉;但是,我想确切地了解 urllib3
认为哪些证书已过期。我该怎么做?
注意:我没有直接调用 certify.where()
,因为我不确定 AWS 在后台执行什么 shananigans,但因为他们的脚本是 auto-installed 作为启动实例的一部分,我对此无能为力,所以我尝试使用他们的内部进程。
问题是 Let's Encrypt DST Root CA X3 于 9 月 30 日到期 -- https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/。请求包不信任 ISRG Root X1 证书,并尝试使用过期的证书对其进行验证。
从 https://letsencrypt.org/certificates/ 下载 ISRG X1 PEM 并将其添加到 cfnbootstrap 库的 cacert.pem 文件。
cat isgrootx1.pem >> /path/to/your/python/env/lib/python3.9/site-packages/cfnbootstrap/packages/requests/cacert.pem
您可以通过以下方式找到 cacert.pem 的位置:
from cfnbootstrap.packages.requests.certs import where
print(where())
另外...我会更改您的代码以确保您实际使用的是 cfn 打包请求模块而不是独立请求。否则,您可能需要在这两个位置进行更新。
from cfnbootstrap.packages.requests.utils import DEFAULT_CA_BUNDLE_PATH
from cfnbootstrap.packages.requests.packages import urllib3
conn = urllib3.connection_from_url("https://www.phpmyadmin.net/", retries=False)
conn.cert_reqs = 'CERT_REQUIRED'
conn.ca_certs = DEFAULT_CA_BUNDLE_PATH
response = conn.request("GET", "/get/")
conn.close()
print(response.status)
如果您确实想要更新独立请求和使用 cfnbootstrap 打包的请求,请使用以下命令查找并更新两个 cacert 路径:
import requests
import cfnbootstrap.packages.requests
print(requests.certs.where())
print(cfnbootstrap.packages.requests.certs.where())