主要探究现代代理的起源,希望能在大厦将倾、独木难支时能够有一线生机。
0x00 术语
终端
- Local Client(本地客户端):有权限,可以理解为 User Agent(用户代理),发起最初的请求和接收最终的响应。
- Proxy Client(代理客户端):有权限,安装在本地,接收从 Local Client 发起的请求并转发给 Proxy Server。
- Proxy Server(代理服务器):有权限,安装在服务器,接受从 Proxy Client 发起的请求并转发给 Remote Server。
- Remote Server(远程服务器):无权限,接受从 Proxy Server 发起的请求并返回响应。
协议
- Proxy Protocol(代理协议):目前主流是 HTTP 和 Socks 5。
- Encryption Protocol(加密协议):Proxy Client 和 Proxy Server 之间使用的加密数据传输协议,也是反审查工作的地方。
- Origin Protocol(源协议):明文数据传输协议。
0x01 白话 Socks 5
代理
代理嘛,就是把直接做的事交给别人做并达成一致的结果。比如我就喜欢把领导交给我的事交给别人做,这样我才能写自己喜欢的代码。
放在网络通信上就是从浏览器直接浏览页面,变成浏览器请求一个中转服务器,中转服务器再把请求转发至远程服务器,远程服务器处理完请求后返回响应,顺着链路返回浏览器。
协议
或者说约定。我和你之间想要进行沟通,起码我俩说的话互相都得理解含义。
Socks 5 协议的第一步可以理解为问好。 现在本地客户端尝试进行 Socks 5 沟通。
第一步是发送 0x05 0x02 0x00 0x01 四个字节组成的数组给代理客户端。
0x05 代表协议版本 5。接触较多的同学应该知道除了 5 还有 4、4a 等等,这个不展开说了。0x02 代表支持 2 种认证方式。后面接着的字节数组长度等于这个值,在这里代表 0x00 的无需认证和 0x01 需要用户名密码认证,加起来总数为 2。注意这里是本地客户端支持的认证方式,具体应用哪种是由代理客户端决定的!
代理客户端收到了问好,然后根据实际情况回答本地客户端。比如 0x05 0x00,第一个还是版本号 5,第二个是选择的认证方式,这里简化一下直接用 0x00 无需认证,就不说其余的认证方式了。
第二步本地客户端收到了无需认证的回答,然后发送 0x05 0x01 0x00 0x01 [地址字节数组] [端口字节数组]。
0x05 就不啰嗦了,接着的 0x01 其实还有 0x02、0x03 两种值,分别代表连接、绑定和 UDP 连接,这个解释起来篇幅很长,具体的可以看 RFC。0x00 是固定的保留位,不要更改。再接着的 0x01指的是想要请求的地址的类型,还有 0x03、0x04 两种值分别代表 IPv4、域名和 IPv6,我也不知道 0x02 去哪了,强迫症有点忍不了。后面跟着的第一个变长字节数组就是远程服务器的地址了,根据前面的类型进行处理就好。第二个 2 长度的定长字节数组代表端口,可以猜猜为什么要用 2 个字节装端口。
好了,代理客户端已经收到了远程服务器的地址,现在可以直接建立和远程服务器的连接。建立连接后返回 0x05 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 给本地客户端。0x05 不说了,接着的 0x00 表示成功连接远程服务器的状态,有很多种状态,什么失败啊、拒绝啊之类的。接着的 0x00 是固定的保留位。然后是 0x01 代表 IPv4 连接,接着的 4 个 0x00 地址和 2 个 0x00 端口代表默认使用代理客户端的地址和端口。
呼,手打好累。此时此刻本地客户端和代理客户端已经完成了协议的握手,而且代理客户端已经和远程服务器建立了连接。一切已经就绪,当本地客户端接收到了代理客户端的回答后,就会将没有代理时直接访问远程服务器的请求发送给代理客户端,代理客户端转发给远程服务器……
0xFF 示例项目
基于 RFC 1928 - SOCKS Protocol Version 5 协议的代理服务,使用简单的 AES-CTR 流式加密,不建议在生产环境使用。
本项的最终目的是为了实现一个简单的代理服务框架,开发者可以根据框架搭建私有的代理服务。
欢迎佬们提出各种相关问题。