Trojan 报文格式
TLS 握手
- 客户端首先执行一次标准的 TLS 握手。
- 如果握手失败,服务器会像普通 HTTPS 服务器一样关闭连接。
- 一些实现还会对纯 HTTP 探测返回类似 nginx 的响应。
初始请求
TLS 建立后,首个应用数据包为:
+-----------------------+---------+----------------+---------+----------+
| hex(SHA224(password)) | CRLF | Trojan Request | CRLF | Payload |
+-----------------------+---------+----------------+---------+----------+
| 56 | 0x0D0A | Variable | 0x0D0A | Variable |
+-----------------------+---------+----------------+---------+----------+
Trojan Request
Trojan Request 使用类 SOCKS5 格式:
+-----+------+----------+----------+
| CMD | ATYP | DST.ADDR | DST.PORT |
+-----+------+----------+----------+
| 1 | 1 | Variable | 2 |
+-----+------+----------+----------+
- CMD 值:0x01 CONNECT,0x03 UDP ASSOCIATE。
- ATYP 值:0x01 IPv4,0x03 DOMAINNAME,0x04 IPv6。
- DST.ADDR 为目标地址,DST.PORT 使用网络字节序。
- SOCKS5 字段细节:https://tools.ietf.org/html/rfc1928
UDP ASSOCIATE 帧格式
当 CMD 为 UDP ASSOCIATE 时,每个 UDP 数据报在 TLS 流中的帧格式为:
+------+----------+----------+--------+---------+----------+
| ATYP | DST.ADDR | DST.PORT | Length | CRLF | Payload |
+------+----------+----------+--------+---------+----------+
| 1 | Variable | 2 | 2 | 0x0D0A | Variable |
+------+----------+----------+--------+---------+----------+
- Length 为负载大小,使用网络字节序。
- Payload 为原始 UDP 数据报。
注意事项
- 首个 TLS 记录可在请求后立即携带负载,从而减少数据包数量与长度模式。
- 客户端通常会提供本地 SOCKS5 代理,并将本地 SOCKS5 请求转换为 Trojan 请求。