# 代理技术浅析
> 自2012年来,我国实施网络审查制度,在互联网国际出口设置流量访问控制。为了绕过流量审查,许多网民通过代理技术访问海外服务器,同时十年来防火墙也在不断升级优化自身的控制策略,在矛与盾的对抗之中又催生了许多新技术。本文不带任何政治立场,仅从技术角度分析防火墙的各种控制策略,同时简要介绍几种代理技术的原理。
## 1.GFW原理
**Great Firewall**采取海外黑名单,境内白名单的控制策略,基于此策略主要有以下几种访问控制方法:
### 1.1 DNS劫持
防火长城对所有经过骨干网国际出口路由的位于[TCP](https://zh.m.wikipedia.org/wiki/传输控制协议)与[UDP](https://zh.m.wikipedia.org/wiki/用户数据报协议)的53端口上的[域名](https://zh.m.wikipedia.org/wiki/DNS)查询请求进行[IDS](https://zh.m.wikipedia.org/wiki/入侵检测系统)检测,一经发现处于黑名单关键词中相匹配的域名查询请求,防火长城作为中间设备会向查询者返回错误结果,比真的回复更早到达。
### 1.2 IP封锁
#### 1.2.1 Access Control List
早期技术实现中,会使用访问控制列表(ACL)技术来封锁特定的IP地址。
基本原理如下:想在某个路由器上切断对某个IP地址的访问,那么只要把这个IP地址配置加入ACL中,并且针对这个IP地址规定一个控制动作(比如丢弃)。当有报文经过这个路由器的时候,在转发报文之前首先对ACL进行匹配,若这个报文的目的IP地址存在于ACL中,那么根据之前ACL中针对该IP地址定义的控制动作进行操作,丢弃此报文。由此切断对这个IP的访问。
ACL可以工作在链路层或是网络层,对不同源地址或目的地址设置不同的处理策略。如果工作在链路层,控制对象就从IP地址变成链路层的MAC地址。
从ACL的工作原理可以看出来,是在正常报文转发的流程中插入了一个匹配字符串的操作,会影响到报文转发的效率,如果需要控制的IP地址比较多,则ACL列表会更长,匹配时间也更长,报文的转发效率会更低,这对于骨干路由器来讲开销过大。
#### 1.2.2 路由扩散技术
现在主要采用效率更高的路由扩散技术封锁特定目的IP地址。
基本原理如下:故意配置错误的静态路由信息,将需要拦截的IP地址配置在特殊设置的黑洞路由上,再通过动态路由协议将相应配置路由扩散
到公网中,黑洞路由对发来的报文可以什么也不做,也可以做虚假回应,也可以对这些报文进行分析统计,获取更多的信息。
路由扩散技术将ACL条件匹配拦截行为转为路由器的常规转发行为,从而提高拦截效率。
### 1.3 深度包检测
深度包检测是一种基于应用层的流量检测和控制技术,相较普通的报文检测,DPI可对报文内容和协议特征进行检测。
比如基于特征字的识别技术,对特征二进制序列进行匹配;再比如行为模式识别技术,针对特定用户的时空特征进行分析。
被认为在防火长城部署了的深度包检测包括:
- HTTP协议的传输内容是未经过加密的,中间设备可以窃听。防火长城对 HTTP回复的检测在2008年末终止,对HTTP请求的Host字段的检测仍然存在。
- 早期TLS版本中,服务器握手响应,包括站点证书,是未被加密的,所以可以用于识别出访问站点。自TLS 1.3开始,ServerHello之后的握手信息,包括站点证书,也会被加密后传输,一般可以认为能防止对证书信息的检测。
- 服务器名称指示(SNI)是TLS的一个扩展协议,该协议下,在握手过程开始时客户端告诉它正在连接的服务器要连接的主机名称。由于SNI信息并未加密,审查者可以识别出用户访问的网站域名。这种检测是在2018年8月部署的,在关于加密服务器名称指示的IETF草案发布刚刚1个月后。
## 2. 代理技术
为了绕过流量审查,通常做法是找一个不在黑名单中的海外服务器做代理,向其发送网络包再转发,如此一来目的IP地址为合法地址,不受DNS劫持和 IP封锁影响。同时对网络包内容段进行加密,以规避深度包检测。以下为几种常用技术:
### 2.1 Secure Shell
SSH是一种在不安全网络上提供安全远程登录的协议,本质并非代理技术,工作在应用层。
基本流程如下:
Client端向Server端发起SSH连接请求。
Server端向Client端发起版本协商。
协商结束后Server端发送Host Key公钥 Server Key公钥,随机数等信息。到这里所有通信是不加密的。
Client端返回确认信息,同时附带用公钥加密过的一个随机数,用于双方计算Session Key。
进入认证阶段。从此以后所有通信均加密。
认证成功后,进入交互阶段。
### 2.2 Virtual Private Network
按照VPN协议分,常见的VPN种类有:IPsec、SSL、GRE、PPTP和L2TP等。
这里仅仅介绍IPsec VPN技术,IPsec是一系列协议族的统称,包括IKE(Internet Key Exchange,因特网密钥交换),AH(Authentication Header,身份验证标头)以及ESP(Encapsulating Security Payload,封装安全载荷协议),通过ESP来保障IP数据传输过程的机密性,使用AH/ESP提供数据完整性、数据源验证和抗报文重放功能。
![在这里插入图片描述](http://cdn.lcx-blog.top/img/1.png)
IPSec协议可以设置成在两种工作模式下运行:一种是隧道(tunnel)模式,另一种是传输(transport)模式。通常使用隧道模式,原理如下:
增加新的IP(外网IP)头,其后是ipsec包头,之后再将原来的整个数据包封装,由此绕过ip封锁。同时为了防止深度包检测,使用AH/ESP加密数据并进行完整性验证,大致流程如下
![在这里插入图片描述](http://cdn.lcx-blog.top/img/222.png)
![IPsec加密验证过程](http://cdn.lcx-blog.top/img/download.png)
ESP 协议号为50, AH 协议号为51 ,IKE端口号为500。IPSec工作在网络层,可以对站点间传输的所有数据进行保护。
### 2.3 Socks5
Socks5的运行过程大致如下:
![](http://cdn.lcx-blog.top/img/client-socks5_f.jpg)
#### 2.3.1 浏览器和socks5代理建立TCP连接
浏览器和服务器之间多了一个中间人,即socks5,因此浏览器需要跟socks5服务器建立一条连接。
SOCKS是会话层的协议,位于表示层与传输层之间,SOCKS 服务默认监听 1080 端口,在代理转发前会先进行TCP连接。
#### 2.3.2 socks5协商阶段
在浏览器正式向socks5服务器发起请求之前,双方需要协商,包括协议版本,支持的认证方式等,双方需要协商成功才能进行下一步。协商的细节与METHOD 相关。
**第一步**,客户端向代理服务器发送代理请求,其中包含了代理的版本和认证方式:
| VER | NMETHODS | METHOD |
| ---- | -------- | -------- |
| 1B | 1B | 1 ~ 255B |
- VER:版本号
- X’04’:Socks4协议
- X’05’:Socks5协议
- NMETHODS:方法数目,该字段指明METHOD字段长度
- METHOD :方法列表,表名客户端支持的方法
**第二步**,代理服务器从给定的方法列表中选择一个方法并返回选择报文
| VER | METHOD |
| ---- | ------ |
| 1B | 1B |
VER字段应与请求一致,METHOD字段应从请求METHOD列表中选取。
- X’00‘ 无需认证
- X’01‘ GSSAPI
- X’02‘ 用户名/密码
- X’03‘~X’7F’ IANA 指定
- X’80‘~X’FE’ 为私有方法保留
- X’FF‘ 无可接受方法, 表示方法列表中的所有方法均不可用,客户端收到此信息必须关闭连接。
**第三步**,在确定了认证METHOD之后根据所选择的METHOD会有一系列认证通信,此处不展开说明。
#### 2.3.3 socks5请求阶段
协商成功后,浏览器向socks5代理发起一个请求。请求的内容包括,它要访问的服务器域名或ip,端口等信息。
**第四步**,一旦认证方法对应的协商完成,客户端就可以发送请求细节了。如果认证方法为了完整性或者可信性的校验,需要对后续请求报文进行封装,则后续请求报文都要按照对应规定进行封装。SOCKS 请求为如下格式:
| VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
| ---- | ---- | ---- | ---- | -------- | -------- |
| 1 | 1 | 1 | 1 | Variable | 2 |
字段含义如下:
- VER 版本号,socks5的值为`0x05`
- CMD
- `0x01`表示CONNECT请求
- `0x02`表示BIND请求
- `0x03`表示UDP转发
- RSV 保留字段,值为`0x00`
- ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型。
- `0x01`表示IPv4地址,DST.ADDR为4个字节
- `0x03`表示域名,DST.ADDR是一个可变长度的域名
- `0x04`表示IPv6地址,DST.ADDR为16个字节长度
- DST.ADDR 一个可变长度的地址值
- DST.PORT 目标端口,固定2个字节
#### 2.3.4 socks5 relay阶段
**第五步**,scoks5收到浏览器请求后,解析请求内容,然后向目标服务器建立TCP连接。
SOCKS 服务端会根据请求类型和源、目标地址,执行对应操作,并且返回对应的一个或多个报文信息。
**第六步**,回复报文,客户端与服务端建立连接并完成认证之后就会发送请求信息,服务端执行对应请求并返回如下格式的报文:
| VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
| ---- | ---- | ----- | ---- | -------- | -------- |
| 1 | 1 | X‘00’ | 1 | Variable | 2 |
- VER协议版本: X‘05’
- REP 回复字段(回复类型):
- X‘00’ 成功
- X‘01’ 常规 SOCKS 服务故障
- X‘02’ 规则不允许的连接
- X‘03’ 网络不可达
- X‘04’ 主机无法访问
- X‘05’ 拒绝连接
- X‘06’ 连接超时
- X‘07’ 不支持的命令
- X‘08’ 不支持的地址类型
- X‘09’ 到 X’FF’ 未定义
- RSV 保留字段
- ATYP 地址类型
- IPV4 X‘01’
- 域名 X‘03’
- IPV6 X‘04’
- BND.ADDR 服务端绑定地址
- BND.PORT 服务端绑定端口 (网络字节序)
对于连接请求,返回的报文里面 BND.PORT 为服务端用来连接目标地址所使用的端口,而 BND.ADDR 则包含了对应的 IP 地址。返回的 BND.ADDR 的值( IP 地址)一般与客户端连接的 SOCKS 服务端地址不一定相同,因为此类服务往往是多台机器提供服务。 SOCKS 服务端会使用目标地址、端口和客户端源地址、源端口信息来执行连接请求(建立对应关系)。socks5既充当socks服务器,又充当relay服务器。实际上这两个是可以被拆开的,当我们的socks5 server和relay server不是一体的,就需要告知客户端relay server的地址,这个地址就是BND.ADDR和BND.PORT。
当我们的relay server和socks5 server是同一台服务器时,`BND.ADDR`和`BND.PORT`的值全部为0即可。
#### 2.3.5 数据传输阶段
经过上面步骤,我们成功建立了浏览器 –> socks5,socks5–>目标服务器之间的连接。这个阶段浏览器开始把数据传输给scoks5代理,socks5代理把数据转发到目标服务器。socks5服务器收到请求后,解析内容。如果是UDP请求,服务器直接转发; 如果是TCP请求,服务器向目标服务器建立TCP连接,后续负责把客户端的所有数据转发到目标服务。
基于socks5,衍生出shadow socks(使用自行设计的协议进行加密通信),shadowsocksR(添加了流量混淆)等开源应用,目前已产生一条规模不小的产业链。
### 2.4 torjan
目前的GFW已经开始采用**主动探测**的方式。具体来说,当GFW发现一个可疑的无法识别的连接时(大流量,随机字节流,高位端口等特征),将会**主动连接**这个服务器端口,重放之前捕获到的流量(或者经过一些精心修改后重放)。Shadowsocks服务器检测到不正常的连接,将连接断开。这种不正常的流量和断开连接的行为被视作可疑的Shadowsocks服务器的特征,于是该服务器被加入GFW的可疑名单中。这个名单不一定立即生效,而是在某些特殊的敏感时期,可疑名单中的服务器会遭到暂时或者永久的封锁。该可疑名单是否封锁,可能由人为因素决定。
与Shadowsocks相反,Trojan不使用自定义的加密协议来隐藏自身。相反,使用特征明显的TLS协议(TLS/SSL),使得流量看起来与正常的HTTPS网站相同。
对于被动检测,Trojan协议的流量与HTTPS流量的特征和行为完全一致。而HTTPS流量占据了目前互联网流量的一半以上,且TLS握手成功后流量均为密文,几乎不存在可行方法从其中分辨出Trojan协议流量。
对于主动检测,当防火墙主动连接Trojan服务器进行检测时,Trojan可以正确识别非Trojan协议的流量。与Shadowsocks等代理不同的是,此时Trojan不会断开连接,而是将这个连接代理到一个正常的Web服务器。在GFW看来,该服务器的行为和一个普通的HTTPS网站行为完全相同,无法判断是否是一个Trojan代理节点。这也是Trojan推荐使用合法的域名、使用权威CA签名的HTTPS证书的原因: 这让你的服务器完全无法被GFW使用主动检测判定是一个Trojan服务器。
因此,就目前的情况来看,若要识别并阻断Trojan的连接,只能使用无差别封锁(封锁某个IP段,某一类证书,某一类域名,甚至阻断全国所有出境HTTPS连接)或发动大规模的中间人攻击(劫持所有TLS流量并劫持证书,审查内容)。
## 结语
各种各样的代理技术基本原理都是相通的,即建立一条本机客户端-防火墙-代理服务端-目标服务器的通道,他们的不同主要体现在以下两点。
1.所处层级不同。比如其中shadowsocks,V2Ray,trojan工作在会话层,只能代理通过浏览器的流量,而网络游戏大多通讯在传输层,只能通过工作在网络层的VPN来代理加速。
2.流量特征不同,但不管是自行设计还是依托https进行伪装,只要有心就一定可以找出不同于正常通信的明显特征,即使不能实时拦截,也可以对代理服务端进行封锁。
## 参考
> [1]维基百科编者. 防火长城[G/OL]. 维基百科, 2022(20220422)[2022-04-22]. [https://zh.wikipedia.org/w/index.php?title=%E9%98%B2%E7%81%AB%E9%95%BF%E5%9F%8E&oldid=71269690](https://zh.wikipedia.org/w/index.php?title=防火长城&oldid=71269690).
>
> [2]周益旻, 刘方正, 王勇. 基于混合方法的IPSec VPN加密流量识别[J]. 计算机科学, 2021, 48(4):8.
>
> [3] Koblas, D., "SOCKS", Proceedings: 1992 Usenix Security Symposium.
代理技术浅析