【问题标题】:Alternative for get_server_certificate() with Proxy configured配置了代理的 get_server_certificate() 的替代方案
【发布时间】:2018-12-03 04:57:58
【问题描述】:

我正在尝试通过调用 ssl.get_server_certificate() 来获取目标网站的证书。如果在我的服务器上配置了代理,则此请求超时(否则工作正常)。有没有办法将代理设置传递给 ssl 以获取目标服务器的证书?或者是否有任何其他替代方法可以获取目标网站的证书以尊重代理设置。

另外,目标网站不断变化,因此无法将它们添加到防火墙规则中以避免超时。

self.host = 'target-website.com'
self.port = 443
PROXY = (''proxy_ip_addr', 3128)
current_cert = ssl.get_server_certificate((self.host, self.port),
                                              ssl_version=ssl.PROTOCOL_TLSv1)

【问题讨论】:

    标签: ssl proxy ssl-certificate


    【解决方案1】:

    get_server_certificate 不支持代理。 但是使用一些代码,您可以使用 HTTP CONNECT 请求通过代理创建隧道,将隧道升级到 SSL,然后获取证书:

    import socket
    import ssl
    
    host  = ('target.example.com',443)
    proxy = (proxy_ip,proxy_port)
    
    # connect to proxy
    s = socket.socket()
    s.connect(proxy)
    
    # create tunnel to target
    s.send("CONNECT {}:{} HTTP/1.0\r\n\r\n".format(*host))
    buf = s.recv(8192)
    assert(buf[9:12] == '200') # HTTP/1.1 200 ...
    
    # upgrade socket to ssl - ignore certifcate errors since we only want
    # to get the certificate and don't transfer sensitive data
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    cert = ctx.wrap_socket(s, server_hostname = host[0]).getpeercert(True)
    print(ssl.DER_cert_to_PEM_cert(cert))
    

    【讨论】:

    • 我的代理服务器需要身份验证才能连接。我添加了那段代码,我得到了 200 个响应。但是,当我进行 cert = ctx.wrap_socket(s, server_hostname = host[0]).getpeercert(True) 调用时,我得到 File "/usr/lib64/python2.7/ssl. py”,第 678 行,在 getpeercert self._check_connected() 文件中“/usr/lib64/python2.7/ssl.py”,第 638 行,在 _check_connected self.getpeername() 文件中“/usr/lib64/python2.7/ socket.py",第 224 行,在方法中返回 getattr(self._sock,name)(*args) socket.error: [Errno 107] 传输端点未连接
    • 对不起,我得到的错误是:文件“/usr/lib64/python2.7/ssl.py”,第 348 行,在 wrap_socket _context=self) 文件“/usr/lib64/python2 .7/ssl.py”,第 609 行,在 init self.do_handshake() 文件“/usr/lib64/python2.7/ssl.py”,第 831 行,在 do_handshake self._sslobj 中。 do_handshake() ssl.SSLEOFError: EOF 发生违反协议 (_ssl.c:579)
    • " EOF 违反协议" - 可能是您的代理认为它不喜欢您的(可能是某些防火墙策略)或端点有问题根据您的要求(也许需要客户证书?)。如图所示的代码对我有用。我建议检查其他客户端是否可以通过您的代理连接到特定服务器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2018-01-08
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多