为通过HTTPS隧道传输的请求设置CA证书束

5
我正在尝试通过HTTPS隧道发送HTTPS请求,也就是说我的代理服务器要求使用HTTPS进行CONNECT,并且需要客户端证书。 我正在使用Requests的代理功能
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:
        ...

这个方法能够起作用,但有一些局限性:

  1. 我只能为与代理的TLS连接设置客户端证书,而不能为外部终端点设置。
  2. proxy-ca-bundle.pem仅验证与代理的TLS连接中的服务器证书。来自外部终端点的服务器证书似乎被忽略了。

是否有任何方法可以使用requests解决这两个问题?我想为外部终端点设置不同的CA集合。

我还尝试使用http.clientHTTPSConnection.set_tunnel,但据我所知,它的隧道是通过HTTP完成的,而我需要HTTPS。

1个回答

4

从源代码来看,似乎 requests 目前不支持 "TLS in TLS",即为代理请求提供两组客户端/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包来验证那些服务器证书。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接