为通过 HTTPS 隧道的请求设置 CA 包
Set CA bundle for requests going through HTTPS tunnel
我正在尝试通过 HTTPS 隧道发送 HTTPS 请求。也就是说,我的代理需要 HTTPS 连接。它还需要一个客户端证书。
我正在使用 Requests' proxy features。
import requests
url = "https://some.external.com/endpoint"
with requests.Session() as session:
response = session.get(
url,
proxies={"https": "https://proxy.host:4443"},
# client certificates expected by proxy
cert=(cert_path, key_path),
verify="/home/savior/proxy-ca-bundle.pem",
)
with response:
...
这可行,但有一些限制:
- 我只能为与代理的 TLS 连接设置客户端证书,不能为外部端点设置客户端证书。
-
proxy-ca-bundle.pem
仅验证与代理的 TLS 连接中的服务器证书。来自外部端点的服务器证书似乎被忽略了。
有什么方法可以用requests
解决这两个问题吗?我想为外部端点设置一组不同的 CA。
我也尝试过使用 http.client
和 HTTPSConnection.set_tunnel
,但据我所知,它的隧道是通过 HTTP 完成的,我需要 HTTPS。
查看源代码,requests
目前似乎不支持这个"TLS in TLS",即。为代理请求提供两组 clients/CA 包。
我们可以使用 PycURL 简单地包装 libcurl
from io import BytesIO
import pycurl
url = "https://some.external.com/endpoint"
buffer = BytesIO()
curl = pycurl.Curl()
curl.setopt(curl.URL, url)
curl.setopt(curl.WRITEDATA, buffer)
# proxy settings
curl.setopt(curl.HTTPPROXYTUNNEL, 1)
curl.setopt(curl.PROXY, "https://proxy.host")
curl.setopt(curl.PROXYPORT, 4443)
curl.setopt(curl.PROXY_SSLCERT, cert_path)
curl.setopt(curl.PROXY_SSLKEY, key_path)
curl.setopt(curl.PROXY_CAINFO, "/home/savior/proxy-ca-bundle.pem")
# endpoint verification
curl.setopt(curl.CAINFO, "/home/savior/external-ca-bundle.pem")
try:
curl.perform()
except pycurl.error:
pass # log or re-raise
else:
status_code = curl.getinfo(curl.RESPONSE_CODE)
PycURL 将使用 PROXY_
设置与代理建立 TLS 连接,向其发送 HTTP CONNECT 请求。然后它将通过与外部端点的代理连接建立一个新的 TLS 会话,并使用 CAINFO
包来验证这些服务器证书。
我正在尝试通过 HTTPS 隧道发送 HTTPS 请求。也就是说,我的代理需要 HTTPS 连接。它还需要一个客户端证书。
我正在使用 Requests' proxy features。
import requests
url = "https://some.external.com/endpoint"
with requests.Session() as session:
response = session.get(
url,
proxies={"https": "https://proxy.host:4443"},
# client certificates expected by proxy
cert=(cert_path, key_path),
verify="/home/savior/proxy-ca-bundle.pem",
)
with response:
...
这可行,但有一些限制:
- 我只能为与代理的 TLS 连接设置客户端证书,不能为外部端点设置客户端证书。
-
proxy-ca-bundle.pem
仅验证与代理的 TLS 连接中的服务器证书。来自外部端点的服务器证书似乎被忽略了。
有什么方法可以用requests
解决这两个问题吗?我想为外部端点设置一组不同的 CA。
我也尝试过使用 http.client
和 HTTPSConnection.set_tunnel
,但据我所知,它的隧道是通过 HTTP 完成的,我需要 HTTPS。
查看源代码,requests
目前似乎不支持这个"TLS in TLS",即。为代理请求提供两组 clients/CA 包。
我们可以使用 PycURL 简单地包装 libcurl
from io import BytesIO
import pycurl
url = "https://some.external.com/endpoint"
buffer = BytesIO()
curl = pycurl.Curl()
curl.setopt(curl.URL, url)
curl.setopt(curl.WRITEDATA, buffer)
# proxy settings
curl.setopt(curl.HTTPPROXYTUNNEL, 1)
curl.setopt(curl.PROXY, "https://proxy.host")
curl.setopt(curl.PROXYPORT, 4443)
curl.setopt(curl.PROXY_SSLCERT, cert_path)
curl.setopt(curl.PROXY_SSLKEY, key_path)
curl.setopt(curl.PROXY_CAINFO, "/home/savior/proxy-ca-bundle.pem")
# endpoint verification
curl.setopt(curl.CAINFO, "/home/savior/external-ca-bundle.pem")
try:
curl.perform()
except pycurl.error:
pass # log or re-raise
else:
status_code = curl.getinfo(curl.RESPONSE_CODE)
PycURL 将使用 PROXY_
设置与代理建立 TLS 连接,向其发送 HTTP CONNECT 请求。然后它将通过与外部端点的代理连接建立一个新的 TLS 会话,并使用 CAINFO
包来验证这些服务器证书。