最近我以合法手段要到了学校一台服务器的使用权限,就打算尝试一下绕过校园网计费。于是研究了一下
作为中国的程序员,“代理”这两个字应该是十分熟悉的。所谓代理,就是让自己的网络流量通过服务器流向网站。但之前我一直没有详细了解过它们的实现,趁这个机会学习了一下。
代理有多种HTTP
,SSL
,Socks5
,FTP
等等。但常用的一般是HTTP
和Socks5
两种代理。为了达到我使用校园网的目的,我优先尝试了Socks5
代理。
Socks5
Socks5代理因为是直接建立双方连接,所以不关心流量走的是什么协议。无论是HTTPS还是HTTP都可以走Socks5代理。以下是来自Wiki的说明
SOCKS是一种网络传输协议,主要用于客户端与外网服务器之间通讯的中间传递。。
当防火墙后的客户端要访问外部的服务器时,就跟SOCKS代理服务器连接。这个代理服务器控制客户端访问外网的资格,允许的话,就将客户端的请求发往外部的服务器。
这个协议最初由David Koblas开发,而后由NEC的Ying-Da Lee将其扩展到版本4。最新协议是版本5,与前一版本相比,增加支持UDP、验证,以及IPv6。
根据OSI模型,SOCKS是会话层的协议,位于表示层与传输层之间。
然后按照RFC1928我实现了一个Socks5代理服务器。
Socks5代理启动!然后......连接失败
在尝试向外发送了几个UDP包和TCP请求之后,我推断,学校分这个服务器的时候,肯定没有给服务器网络,只是在网关做了映射。查看了一下IE的配置,找到了学校分配给服务器的代理服务器。用socks这个第三方库使用了一下代理。然而......问题又来了,无法访问HTTP网站是什么操作???看了日志,说是只支持CONNENT HTTP Proxy。
socks
这个第三方库支持三种代理
Socks4
,Socks5
和HTTP
。安装方式是pip install pysocks
HTTP代理
通过谷歌得知,HTTP代理分两种。
-
在HTTPS技术还没出来的时候,人们代理网站,只需要把请求的URI带上完整的网址就行了。代理服务器会代替你访问这个网站,然后把结果回馈给你。
-
在HTTPS普及之后,这种操作已经不行了,因为证书对不上。所以有了新的操作:CONNECT 方法。
用户向代理服务器发送CONNECT (domain|IPV4|IPV6):Port (HTTP/1.1 | HTTP/1.0 | HTTP/2.0)
的数据包,代理服务器视情况返回一个状态。当客户端接收到200状态的时候就意味着代理服务器与目标服务器建立了TCP连接,可以直接发送普通的请求过去。此时数据包会由一个TCP连接发送到代理服务器,代理服务器原封不动的将数据包转发给目标服务器。
这种方法就像是Socks5代理的阉割版,代理服务器不关心你们使用的是什么交互方式,它只需要把两个TCP连接拼在一起就行了。
那么,我们上面提到的不支持的HTTP代理就是第一种代理了。看了看socks的源代码,嗯,只支持第二种代理。
但学校这台代理服务器的逻辑是什么?我想搞清楚。发送了一个错误的包过去,果然从错误页面拿到了这台代理服务器的信息—— squid2.6。一番谷歌,squid的默认配置就是只允许向443端口使用CONNECT方法。
解决
自己手写了一个Socks代理转HTTP代理的代码,发现怎么搞都没用。因为普通的HTTP代理帮你发个包接个包就直接切断连接了!然而我是不会这样轻易的狗带的。
一通电话打到了网管老师那里,一番解释之下,老师开启了所有端口的CONNECT方法。
社会工程学万岁!
后续
所谓生命不息,折腾不止。当我使用SSTap将我的所有TCP流量走代理之后,我便想UDP也能走代理了(有点无耻)。
我想,只要将一个UDP包要传递的数据解析出来,通过TCP转发给云服务器,让云服务器替学校那台服务器转发UDP(秘技: 双重转发),虽然可能导致延迟略高,但至少能用了!毕竟我不是一个游戏党,对UDP的延迟没有要求。