协议原理
理解 AnyTLS 为何而生,以及它在认证、连接复用与流量整形上的设计选择。
要解决的问题
当代理协议把 TLS 流量再套一层 TLS 传输时(即“TLS in TLS”,嵌套 TLS 握手),外层与内层握手叠加会产生可被统计学方法识别的特征—— 例如握手阶段特有的数据包长度序列。审查方可以据此判断一条连接“疑似代理”,而无需解密内容。
TLS in TLS 是什么
指在一条 TLS 连接内部,又承载了另一层 TLS 流量(如浏览器访问 HTTPS 网站的流量经代理再被 TLS 封装)。 两层握手的叠加是产生指纹的根源。核心思路
AnyTLS 作为 “Any in TLS” 的一个参考实现,把精力集中在两件事上:
- 合理的连接复用:减少频繁握手带来的特征与延迟。
- 控制数据包长度模式:通过可配置的填充方案,打散并改变握手阶段的包长序列。
认证
客户端与服务端通过共享的密码进行认证。连接建立时,客户端需提供与服务端一致的密码,否则无法建立会话。 这也是实践中最常见的连接失败原因——两端密码不一致。
会话复用
AnyTLS 在 TLS 之上实现了一个会话层,对底层连接进行多路复用。其复用策略倾向于:
- 优先复用最新建立的会话,以承载新的请求;
- 及时清理最老、空闲的会话,控制资源占用。
这样既能显著降低代理建连延迟,又能避免连接长期堆积。
PaddingScheme
默认的填充方案仅是一个示例,官方无法保证默认参数不会被识别。因此协议把填充方案设计成由服务端下发、可动态更换:一旦某套特征被列入黑名单,运营者可以低成本地切换到另一套方案,改变流量形态。
设计哲学
实现成本低廉、易于改变的流量特征,更有可能持续地阻碍审查研究。让“改变特征”变得廉价,是 PaddingScheme 的核心价值。PaddingScheme 语法
填充方案是一个文本文件,逐行描述“第 N 个数据包应当被整形成怎样的长度”。一个简化示例:
padding.txt
stop=3
0=900-1400
1=900-1400
2=900-1400stop=N:从第N个包开始不再做填充整形。序号=长度规则:为指定序号的包定义目标长度,例如900-1400表示在该区间内取值。- 多个长度区间可用逗号分隔;部分实现支持以
c开头的“检查”符号控制是否需要补足。
以实现为准
PaddingScheme 的完整语法随版本演进而变化。配置前请对照你所使用的 anytls-go 版本说明,确认序号、区间与特殊符号的精确含义。服务端通过 --padding-scheme ./padding.txt 加载方案,相关用法见 服务端部署。