一条 Trojan 节点在 Clash 订阅里通常就这么长。
proxies:
- name: "香港 Trojan"
type: trojan
server: hk01.example.com
port: 443
password: "your-password-here"
udp: true
sni: hk01.example.com
skip-cert-verify: false
没有加密方式,没有 UUID,没有 alterId。认人的东西只有一个 password。Mihomo 文档对它的说明只有一句,必须,trojan 服务器密码。
那个密码到了线路上变成 56 个字符
官方协议文档给的结构很短。TLS 握手完成之后,客户端立刻发一段东西过去,格式是这样。
+-----------------------+---------+----------------+---------+----------+
| hex(SHA224(password)) | CRLF | Trojan Request | CRLF | Payload |
+-----------------------+---------+----------------+---------+----------+
| 56 | X'0D0A' | Variable | X'0D0A' | Variable |
+-----------------------+---------+----------------+---------+----------+
第一段是密码算 SHA224 之后写成十六进制,固定 56 个字符。中间那段 Trojan Request 照抄了 SOCKS5 的写法,一个字节的 CMD、一个字节的 ATYP、目标地址和两个字节的端口。CMD 只有两个取值,X'01' 是 CONNECT,X'03' 是 UDP ASSOCIATE。ATYP 区分 IPv4、域名和 IPv6。
整个协议就这么点内容,没有额外的握手轮次,也没有时间戳和自带的加密层。保密和完整性全部由外面那条 TLS 连接负责,所以 Xray 文档在 Trojan 出站页面上写明,Trojan 必须配合传输安全 TLS 使用。Mihomo 的节点示例里也找不到 tls: true 这一行,sni、alpn、skip-cert-verify 这些 TLS 字段直接挂在节点上,默认就是开着的。
这也解释了为什么 Trojan 节点几乎都用 443 端口。它想让自己在流量里和普通 HTTPS 网站长得一样,换个古怪端口反而显眼。
UDP 走的是另一套包格式,每个包自带地址、端口、长度和一个 CRLF。这解释了为什么 Trojan 节点在 Mihomo 里还要单独写 udp: true,转发能力由机场那端决定。
密码不对的连接会被丢给一个网页
这是 Trojan 设计里最有意思的一处。协议文档的描述是,遇到「其他协议」的流量,服务器在一个预设端点和客户端之间开一条隧道,默认是本机 80 端口的 HTTP 服务。
放到实际场景里。有人拿浏览器直接访问你的机场节点地址,或者有探测程序对着 443 端口试各种请求,它们发过去的东西里没有那 56 个字符,服务器不会关连接也不会报错,而是把这条连接接到后面那个普通网站上。探测的人看到的是一个正常网页和一张正常证书。
代价是机场得准备一个域名和有效证书,还得在后面挂一个能见人的站点。这部分是服务端的活,用户在订阅里看不到。Trojan 节点的 sni 填的就是那个域名。
想验证的话有个土办法。把节点地址原样贴进浏览器地址栏,配得规矩的 Trojan 服务器会回一个页面,内容多半是 nginx 默认页或者机场随便挂的一个静态站。这不能证明节点好不好用,只能说明服务端那边的回落配置在工作。要留意的是,有些机场的节点地址是套了 CDN 的域名,这时候看到的页面来自 CDN 而不是节点本身。
和 VLESS 加 TLS 摆在一起看
两种做法外面都是一条真 TLS 连接,里面都靠一个短头部认人。差别在几个具体位置。
| 看哪一处 | Trojan | VLESS 加 TLS |
|---|---|---|
| 认人的东西 | password 的 SHA224 哈希 |
uuid |
| 验证失败怎么办 | 协议规定转给预设的后端网页 | 协议没有规定,看外层方案 |
| 外层能不能省 | 不能,Xray 文档写明必须配 TLS | 不能,Xray 文档写明必须配传输安全层 |
| 流控字段 | 无 | flow,可填 xtls-rprx-vision |
| 常见搭档 | 域名加证书 | 域名加证书,或者 REALITY |
Xray 那边还有一条区别值得留意。XTLS Vision 这套流控最初在 Xray v1.6.2 里放出来时,发布说明写明测试期间只支持 VLESS,不支持 Trojan。想用 Vision 的人只能走 VLESS 那条路。Xray 的 Trojan 页面给的建议是在公网场景下开 Mux,理由是 TLS 里再套一层 TLS 会留下可被统计的特征,这个问题后来催生了 AnyTLS。
还有一件事挺反直觉。V2Fly 文档的 VLESS 页面顶上挂着弃用提示,推荐的替代品正是 Trojan。同一个协议在 Xray 那边被当成上一代方案,在 V2Fly 那边被当成推荐项,两个项目的分歧在这里表现得很明显。
两个原始实现都停在几年前
查 Trojan 资料的人早晚会翻到那两个仓库,然后发现它们很久没动了。
trojan-gfw 是最初的 C++ 实现,最后一个正式版 v1.16.0 发布于 2020 年 6 月 10 日,仓库最后一次提交在同年 11 月 8 日。Go 语言的 trojan-go 停得稍晚,最后一版 v0.10.6 是 2021 年 9 月 14 日,同一天有最后一次提交。
协议没跟着停。现在机场那端跑的多半是 Xray 或 sing-box 的 Trojan 服务端,你这边的 Mihomo、sing-box 各有一套自己的实现,互相之间按协议文档对齐。这也是为什么 Trojan 节点在各家客户端里都能用,不需要装什么特别的东西。
trojan-go 留下的痕迹还在。Mihomo 的 trojan 节点里有一组 ss-opts 字段,文档写明它启用的是 trojan-go 的 shadowsocks AEAD 加密,可选算法有三个。这一项默认关着,机场用到的不多。
订阅里那几个可选字段各管什么
除了密码,Mihomo 的 trojan 节点还能带这些。
sni是 TLS 握手时报出去的域名,通常和server一致,走 CDN 或前置域名时会不同。alpn声明应用层协议,常见写法是h2加http/1.1。client-fingerprint让客户端模仿某个浏览器的 TLS 指纹,可填chrome、random等。skip-cert-verify写true时客户端不校验服务器证书,这一项由机场在订阅里定。network默认 tcp,支持ws和grpc,机场走 CDN 时会用到。smux是多路复用开关,默认关闭。
sing-box 那边字段更少,一条 trojan 出站只有 server、server_port、password 和一个 tls 对象,另外可以带 multiplex 和 transport。
{
"type": "trojan",
"tag": "hk-trojan",
"server": "hk01.example.com",
"server_port": 443,
"password": "your-password-here",
"tls": { "enabled": true, "server_name": "hk01.example.com" }
}
本站收录的 28 家机场里,资料写明用 Trojan 的有 2 家,极连云和灵动云,后者的页面上 VLESS 和 Trojan 混着写。数据来自机场自述与站长资料,核对日 2026-08-09。没标的 20 家订阅里有没有 Trojan 节点,导进 Clash Verge Rev 看一眼类型标签就知道,具体认法在按字段认协议那篇里。