HTTP(S)、SOCKS5代理原理详解
一、HTTP(S)代理
首先,我们要清楚,HTTP代理一词中的HTTP指的是客户端和代理服务器之间正式的应用层消息转发前进行协商使用的协议。HTTPS代理严格来说并不存在,只是TLS消息也可以走HTTP代理
我们通过WireShark抓帧来分析HTTP代理的原理,这里我们使用到开源软件goproxy,GitHub地址https://github.com/snail007/goproxy,它可以作为HTTP、SOCKS5代理,同时其还有很多有关计算机网络的强大功能
1.网络拓扑图
2.我们在192.168.163.103(后文省略为103,充当HTTP代理服务器)上开启WireShark,捕获IP为103对应的网络适配器的流量sudo wireshark
3.在103的8080端口启动HTTP代理服务器proxy http --local-type tcp --local 192.168.163.103:8080
4.在192.168.163.101(后文省略为101,充当客户端)上输入curl --proxy http://192.168.163.103:8080 http://httpforever.com/
等待HTML的内容输出到终端
5.在103的WireShark过滤栏上输入((ip.src == 192.168.163.101 and ip.dst == 192.168.163.103) or (ip.src == 192.168.163.103 and ip.dst == 192.168.163.101)) or ((ip.src == 192.168.163.103 and ip.dst == 146.190.62.39) or (ip.src == 146.190.62.39 and ip.dst == 192.168.163.103))
这样,就能过滤出103-101和103-146.190.62.39(httpforever.com的IP地址,后文省略为39)之间的帧
6.分析捕获到的帧
首先是101和103之间进行的TCP三次握手,101和103建立起TCP连接
然后101发送给103一个HTTP消息
在一般HTTP消息的红框部分本应该是不包含协议、域名、端口的URL,如下图
但这里URL是完整的,此处的http://httpforever.com/被称为absolute URI
当这个HTTP请求被代理服务器接收后,代理服务器通过DNS解析得到httpforever.com的IP地址,然后也通过TCP三次握手,建立起103和39之间的TCP连接(一般来说,代理服务器的IP应该是公网IP,这样才能起到掩盖客户端真实公网IP的作用。但我们这里是分析HTTP代理的原理,所以给代理服务器的是私有IP)
代理服务器将收到的HTTP消息的absolute URI部分更改为不带协议、域名、端口的URL,此处也就是/,其余地方不变,发送给39。39返回响应消息给103,103将其转发给101
在上图中我有一个尚未解决的问题,网络适配器设置以太帧的mtu最大为1500,帧的长度大约1518,但捕获到的帧中有些完全超出了1518。我怀疑其可能和网络适配器为虚拟网络适配器有关
后面的帧就是与101和103、103和39之间的四次挥手有关
下面我们通过抓帧分析TLS消息是否也能走HTTP代理
1.让103上的WireShark重新捕获帧
2.在101上输入curl --proxy http://192.168.163.103 https://www.zhihu.com/
注意此时的协议为HTTPS
后面的帧就是与101和103、103和39之间的四次挥手有关
3.分析捕获到的帧
在过滤栏输入((ip.src == 192.168.163.103 and ip.dst == 192.168.163.101) or (ip.src == 192.168.163.101 and ip.dst == 192.168.163.103)) or ((ip.src == 192.168.163.103 and ip.dst == 182.131.24.233) or (ip.src == 182.131.24.233 and ip.dst == 192.168.163.103))


同样,首先是101和103的三次握手
然后101给103发送了一个HTTP请求,该请求的请求方法为CONNECT,同时后面跟着域名:端口。代理服务器进行DNS解析,获取域名对应的IP,然后建立103和182.131.24.233(后面省略为233)之间的TCP连接
如果代理服务器和待访问服务器之间的TCP连接建立成功,那么103会给101发送一个请求行中包含connection established的响应。如果TCP连接建立失败,则不会发送
客户端收到来自代理服务器的响应消息,便直接将TLS握手消息发送给代理服务器,代理服务器不做任何处理直接转发给待访问服务器。待访问服务器的响应经代理服务器之手不做任何修改转发给客户端。此时就好像客户端和待访问服务器之间的代理服务器不存在一样,就好像客户端和待访问服务器之间建立了一条隧道
因为HTTPS的对称加密的密钥是通过公钥加密得到的,代理服务器也无法获取对称加密的密钥,进而无法获取HTTPS的未加密内容
二、SOCKS5代理
SOCKS5是一个应用层协议,用于在客户端和代理服务器之间进行协商
客户端首先建立与SOCKS5代理服务器的TCP连接,在TCP连接上双方基于SOCKS5协议进行协商。协商内容包括客户端是否有使用该代理服务器的权限、客户端待访问的服务器的域名或IP和端口
之后代理服务器建立与待访问服务器之间的TCP连接,连接建立成功则代理服务器通过SOCKS5协议告知客户端可以开始发送报文。此时,就好像客户端和待访问服务器之间建立了一条隧道
SOCKS5协议的内容可以参考https://jiajunhuang.com/articles/2019_06_06-socks5.md.html
关于SOCK5的WireShark抓帧分析暂时就不写了,以后可能会补上