【问题标题】:Python HTTPS Proxy TunnellingPython HTTPS 代理隧道
【发布时间】:2014-08-04 18:21:44
【问题描述】:

我正在尝试在 python 中创建一个 http 代理。到目前为止,除了 https 之外的所有东西都可以正常工作,因此下一步是实现 CONNECT 方法。

我对进行 https 隧道时需要发生的一系列事件感到有些困惑。 据我了解,连接到谷歌时我应该有这个:

浏览器 -> 代理

CONNECT www.google.co.uk:443 HTTP/1.1\r\n\r\n

然后代理应该建立到 google.co.uk 的安全连接,并通过发送确认:

代理 -> 浏览器

HTTP/1.1 200 Connection established\r\n\r\n

在这一点上,我希望浏览器现在可以继续执行它首先要执行的操作,但是,我要么一无所获,要么得到一串我无法 decode() 的字节。我一直在阅读与 ssl 隧道有关的所有内容,我认为我应该将所有字节从浏览器转发到服务器,反之亦然。但是,这样做时,我得到:

HTTP/1.0 400 Bad Request\r\n...\r\n

发送 200 代码后,接下来我应该做什么?

连接方法的代码sn-p:

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

if headers["Method"] == "CONNECT":
    client = ssl.wrap_socket(client)

    try:
        client.connect(( headers["Host"], headers["Port"] ))
        reply = "HTTP/1.0 200 Connection established\r\n"
        reply += "Proxy-agent: Pyx\r\n"
        reply += "\r\n"
        browser.sendall( reply.encode() )
    except socket.error as err:
        print(err)
        break

    while True:
        now not sure

非常感谢您的帮助!

【问题讨论】:

    标签: python http proxy connect tunnel


    【解决方案1】:

    找到相关问题的答案后:HTTPS Proxy Implementation (SSLStream)

    我意识到目标服务器(在本例中为 google.co.uk)端口 443 上的初始连接不应加密。因此我删除了

    client = ssl.wrap_socket(client)
    

    line 继续使用纯文本隧道而不是 ssl。一旦

    HTTP/1.1 200 Connection established\r\n\r\n
    

    消息发送完毕,浏览器和端服务器会通过代理形成自己的ssl连接,所以代理不需要做任何与实际https连接相关的事情。

    修改后的代码(包括字节转发):

    # If we receive a CONNECT request
    if headers["Method"] == "CONNECT":
        # Connect to port 443
        try:
            # If successful, send 200 code response
            client.connect(( headers["Host"], headers["Port"] ))
            reply = "HTTP/1.0 200 Connection established\r\n"
            reply += "Proxy-agent: Pyx\r\n"
            reply += "\r\n"
            browser.sendall( reply.encode() )
        except socket.error as err:
            # If the connection could not be established, exit
            # Should properly handle the exit with http error code here
            print(err)
            break
        
        # Indiscriminately forward bytes
        browser.setblocking(0)
        client.setblocking(0)
        while True:
            try:
                request = browser.recv(1024)
                client.sendall( request )
            except socket.error as err:
                pass
            try:
                reply = client.recv(1024)
                browser.sendall( reply )
            except socket.error as err:
                pass
    

    参考资料:

    HTTPS Proxy Implementation (SSLStream)

    https://datatracker.ietf.org/doc/html/draft-luotonen-ssl-tunneling-03

    http://www.ietf.org/rfc/rfc2817.txt

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-08
      • 1970-01-01
      • 2011-05-22
      • 2018-02-14
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      相关资源
      最近更新 更多