sing-box出站TLS指纹utls怎么配:字段、指纹值与官方不推荐的原因

搜“sing-box TLS 指纹”的人,手里通常已经有一个走 TLS 的节点(VLESS、Trojan 这类),想让客户端握手看起来更像浏览器。这篇按 sing-box 官方 TLS 文档整理 utls 的写法、指纹值和版本要求,再把官方的警告原样讲清楚:utls 能配,但官方明确不推荐把它当成抗封锁手段。

先说明一个前提:我没有在本机运行 sing-box 实测。下面的字段、版本号、指纹值都来自 sing-box 官方 TLS 文档,示例是我按字段说明拼出来的,没有跑通过,抄之前请对照你自己版本的官方文档。依据来源:sing-box 官方 TLS 文档。

先看版本:utls 是 1.10.0 才有的

官方文档的版本记录里,utls 这一项标在 sing-box 1.10.0 的变化里。再旧的版本里写 utls 不认。动手前先跑一眼:

1
sing-box version

版本不够先升级。改完配置先用 sing-box 自带的 check 命令过一下配置语法,再重启服务。

指纹是什么:ClientHello 里能认出来的特征

一次 TLS 握手,客户端发出的 ClientHello 里带了一串参数:TLS 版本、密码套件、扩展、椭圆曲线这些。检测方可以从这串参数里提取特征,判断握手像不像常见浏览器。Go 默认 TLS 栈的握手特征和浏览器不一样,这就是“指纹”会被认出来的原因。

utls 的做法是模仿浏览器的 ClientHello 结构,让握手看起来像某个浏览器。sing-box 里这个功能就叫 utls,只在出站(客户端)有效,入站(服务端)没有这个字段,服务端不用配它。

出站怎么写:tls 块里加 utls

以 VLESS 出站为例,只写和本文有关的字段,其余字段按你自己的节点情况填:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"type": "vless",
"tag": "vless-out",
"server": "your.domain.net",
"server_port": 443,
"uuid": "你的 UUID",
"tls": {
"enabled": true,
"server_name": "your.domain.net",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
}
}

要点:

  • utls 在 tls 块里面,不是出站顶层字段,别放错位置。
  • enabled 必须写 true,只写 fingerprint 不开 utls 不生效。
  • server_name 照常填证书对应的域名,和 utls 是两回事,各管各的。

sing-box 出站的通用写法,见sing-box和Xray里怎么配Hysteria2,那篇讲的是出站字段和版本要求的对照思路。

指纹值有哪些:默认是 chrome

官方文档列出的指纹值:

  • chrome:最常用;fingerprint 留空时也用 chrome。
  • firefox、edge、safari
  • 360、qq
  • ios、android
  • random、randomized

几点注意:

  • 旧版的几个 chrome 变体(chrome_psk、chrome_psk_shuffle、chrome_padding_psk_shuffle、chrome_pq、chrome_pq_psk)在 1.10.0 被移除了,写了会回落到 chrome,别再从旧教程里抄这些值。
  • random 和 randomized 的区别,官方文档只列出值、没有展开说明,我没有核对,不展开写,需要的话以实测为准。
  • 指纹值选哪个,没有“最强”的说法:选一个和你实际使用场景接近的就行,配了不等于隐身,原因见下一节。

官方为什么不推荐:原话要点

这是这篇最重要的一节。官方文档在 utls 一节开头就标了 Not Recommended,理由是:

  • uTLS 已经被研究者反复发现指纹漏洞。
  • 它只是复制 ClientHello 的结构,但浏览器用的是完全不同的 TLS 栈(Chrome 用 BoringSSL,Firefox 用 NSS),各自实现行为上的差别,单靠复制握手格式是复现不了的,所以仍然可能被检测出来。
  • 这个库缺乏积极维护,代码质量也不好,不适合用来对抗审查。
  • 官方的原话是:要做 TLS 指纹抗性,用 NaiveProxy,不要用 utls。

所以结论要摆正:utls 可以配,也确实能改掉 Go 默认栈的握手特征,但不要把它当成抗封锁主力。节点连不上的时候,先按常规顺序排查(版本、密码、域名、证书),不要一上来就怪指纹或者迷信换个指纹值能解决问题。NaiveProxy 的配置本文不展开,那是另一篇的量。

三个容易踩的点

  • engine 设了 apple 或 windows,utls 不生效:1.14.0 加入的 engine 字段如果设成 apple 或 windows,官方文档的不支持字段列表里明确有 utls。用默认的 go 引擎才行。
  • QUIC 不走这套:官方文档在 QUIC 支持一节只写了 ECH,utls 不在其中。Hysteria2、TUIC 这类走 QUIC 的出站,不要指望用 utls 改指纹。
  • fingerprint 留空就是 chrome:不写 fingerprint 或者写空,用的都是 chrome 指纹,不是“不启用”。想关掉 utls 是把 enabled 设成 false,不是把指纹值留空。

Reality 的背景和必备参数,见Reality协议是什么。Reality 本身有自己的握手验证机制,和 utls 是两套东西,不要混在一起配。

没有覆盖的

  • 各指纹值实际握手长什么样:我没有抓包实测,不给对比结论。
  • NaiveProxy 的配置:官方只给了方向,没有在这篇展开。
  • 入站(服务端)的 TLS 字段:utls 是客户端才有的,服务端那侧不在本文范围。