本文介绍了如何将HTTPS流量从SOCKS代理转发到HTTP代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个SOCKS代理,如果关闭链接,它可以同时处理HTTP和HTTPS流量。

I have written a SOCKS proxy which works with both HTTP and HTTPS traffic if chaining is turned off.

如果打开链接并且转发主机和端口属于过滤HTTP代理然后只有HTTP流量可以流动。 HTTPS流量不会流动并报告SSL错误。

If chaining is turned on and the forwarding host and port belong to a filtering HTTP proxy then only HTTP traffic can flow. HTTPS traffic does not flow and reports an SSL error.

请注意,当请求直接来自浏览器而不是来自SOCKS服务器时,HTTP代理会处理HTTPS流量。

Note that the HTTP proxy does handle HTTPS traffic when the request is coming direct from the browser and not from the SOCKS server.

例如,如果我向发生以下情况:

As an example if I make a request to https://www.google.com the following occurs:

1)客户端发送SOCKS 5问候语,告诉我们哪些auth方法可以接受。

1) Client sends a SOCKS 5 greeting to let us know which auth methods are acceptable.

2)服务器以NO_AUTH响应

2) Server responds with NO_AUTH

3)客户端发送连接请求(包括预期的目标主机和端口)。

3) Client sends a connection request (which includes the intended destination host and port).

4)服务器创建套接字并将其连接到HTTP代理服务器并使用GRANTED响应客户端

4) The server creates and connects a socket to the HTTP proxy server and responds to the client with GRANTED

5)然后SOCKS服务器收到以下请求(隐藏/控制字符已全部替换为其字符代码,以便您可以看到正在发生的事情):

5) The SOCKS server then receives the following request (the invisible/control characters have all been replaced with their character codes so you can see what's going on):

\u0016\u0003\u0001\u0000Ñ\u0001\u0000\u0000Í\u0003\u0003áp¥@Ia¹\u0001„Ä\u0006 É;š‰‰4\u001dýà•J>Ü6¢Þ\fö\u001c%\u0000\u0000(À+À/\u0000žÌ\u0014Ì\u0013À\nÀ\tÀ\u0013À\u0014À\u0007À\u0011\u00003\u00002\u00009\u0000œ\u0000/\u00005\u0000\n\u0000\u0005\u0000\u0004\u0001\u0000\u0000|\u0000\u0000\u0000\u0013\u0000\u0011\u0000\u0000\u000ewww.google.comÿ\u0001\u0000\u0001\u0000\u0000\n\u0000\b\u0000\u0006\u0000\u0017\u0000\u0018\u0000\u0019\u0000\u000b\u0000\u0002\u0001\u0000\u0000#\u0000\u00003t\u0000\u0000\u0000\u0010\u0000\u001b\u0000\u0019\u0006spdy/3\bspdy/3.1\bhttp/1.1uP\u0000\u0000\u0000\u0005\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0000\u0012\u0000\u0000\u0000\r\u0000\u0012\u0000\u0010\u0004\u0001\u0005\u0001\u0002\u0001\u0004\u0003\u0005\u0003\u0002\u0003\u0004\u0002\u0002\u0002

如你所见,它完全不可读,但是我们已经知道用户打算从最初的SOCKS连接消息(步骤3)开始,所以我们可以创建并发出以下连接请求:

As you can see, its completely unreadable, but we already know where the user intends to go from the initial SOCKS connection message (step 3) so we can create and issue the following connect request:

CONNECT www.google.com:443 HTTP/1.1\r\nUser-Agent: MySocksServer\r\nProxy-Connection: keep-alive\r\nHost: www.google.com\r\n\r\n

6)这个新构建的CONNECT被发送到我们正在链接的HTTP代理,此代理检查其过滤规则和响应:

6) This newly constructed CONNECT is sent to the HTTP proxy that we are chaining to, this proxy checks against its filter rules and responds with:

HTTP/1.1 200 Connection Established\r\nVia: 1.1 HTTPserverName\r\nX-WebMarshal-RequestID: AN_ID_STRING\r\n\r\n

7)这是在我们的SOCKS服务器中收到的,并被转发(未修改)到客户端。在我的调试中,我在发送请求之前直接监视套接字,并且可以看到客户端套接字已连接。

7) This is received in our SOCKS server and is forwarded (unmodified) to the client. In my debugging I am monitoring the sockets directly before the send request and can see that the client socket is connected.

8)引发的下一个事件是一个错误,错误,SOCKET_NOT_CONNECTED,对套接字运行另一次检查确认客户端套接字确实不再连接。

8) The next event raised is an error, with the error, SOCKET_NOT_CONNECTED, running another check on the sockets confirms that the client socket is indeed no longer connected.

为什么我的套接字会在步骤7和8之间关闭?我没有正确遵循协议吗?我看不出我错过了什么。我想我以某种方式处理CONNECT方法错误了?

Why would my Socket be getting closed between steps 7 and 8 here? Have I not followed the protocol correctly? I can't see what I am missing. I guess I am handling the CONNECT method wrong in some way?

如果我不修改SOCKS服务器收到的请求(即将其转换为CONNECT请求)并且而是将不可读数据直接转发到HTTP代理,然后HTTP代理的日志显示:

If I do not modify the request received by the SOCKS server (i.e. convert it into a CONNECT request) and instead forward on the unreadable data direct to the HTTP proxy then the Logs for the HTTP proxy show either:

Badly formated request: \u0016\u0003\u001
Bad request received.

OR

Failed to read request: Client closed connection. (0)
1Request took 0 ms + 23 ms idle time


推荐答案

7)这是在我们的SOCKS服务器中收到并转发(未修改)到客户端...

7) This is received in our SOCKS server and is forwarded (unmodified) to the client...

这是错误的。您在SOCKS代理中生成CONNECT请求,因此您应该将此请求的响应保留给您自己,而不是将其转发给客户端。您应该做什么:

This is wrong. You generate the CONNECT request in your SOCKS proxy and therefore you should keep the response to this request to yourself and not forward it to the client. What you should do:


  • 如果您从客户端收到SSL握手的开始(\ x16 \ x03 ... )你应该缓冲它。

  • 然后你创建CONNECT请求并将其发送给代理。 Host头和Proxy-Connection头与CONNECT没有任何意义,因此您无需添加它们。

  • 读取代理对CONNECT请求的响应。如果状态代码不是200则出现问题,您应该关闭与客户端的连接。没有简单的方法将错误信息传输到客户端。

  • 如果状态代码是200转发,缓冲的ClientHello通过代理从客户端到服务器,然后转发到客户端和服务器(通过代理隧道)。

  • If you receive the start of the SSL handshake from the client ("\x16\x03... ") you should buffer it.
  • Then you create the CONNECT request and send it to the proxy. The Host header and Proxy-Connection headers have no meaning with CONNECT so you don't need to add them.
  • Read the response from the proxy to the CONNECT request. If status code is not 200 something is wrong and you should close the connection to the client. There is no easy way to transfer the error information to the client.
  • If status code is 200 forward the buffered ClientHello from the client to the server through the proxy and from then on forward everything between client and server (through the proxy tunnel).

这篇关于如何将HTTPS流量从SOCKS代理转发到HTTP代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 14:43