SNI 是什么,为什么配错了就握手失败
节点配置里的 sni 字段决定 TLS 握手时报哪个域名。它是明文传输的,也正因如此成了最容易出问题的一项。本文说明它的作用、和 Host 的区别,以及三种典型的配错场景。
本文目录(6 节 · 约 2 分钟) +
- 01 为什么需要它
- 02 SNI 和 Host 的区别
- 03 三种典型的配错场景
- 04 在不同协议里它叫什么
- 05 怎么排查
- 06 小结
一句话结论:SNI 是 TLS 握手时客户端明文告诉服务器「我要访问哪个域名」的那个字段。 服务器据此决定拿哪张证书出来。配错了服务器给不出对应证书,握手就失败——表现为节点连不上,但错误信息往往很笼统。
为什么需要它
一台服务器的一个 IP 上,通常托管着很多个网站。客户端连过来时,TLS 握手发生在 HTTP 请求之前——这时候服务器还不知道你要访问哪个域名(那个信息在加密之后的 HTTP 头里),可它必须先拿出一张证书来。
拿哪张?
SNI(Server Name Indication)就是为了解决这个先有鸡还是先有蛋的问题:客户端在握手的第一个包里,明文附上要访问的域名。服务器看到之后拿对应的证书出来,握手继续。
关键在「明文」两个字——SNI 是 TLS 加密建立之前发送的,所以链路上的任何观测者都能看到你要连哪个域名。这也是为什么会有 ECH(Encrypted Client Hello)这类后续方案,但它目前部署还不广泛。
SNI 和 Host 的区别
这两个经常被搞混,因为在普通网站访问中它们通常是同一个值。
| SNI | Host | |
|---|---|---|
| 在哪一层 | TLS 握手 | HTTP 请求头 |
| 加密与否 | 明文 | 在 TLS 内部,加密 |
| 谁用它 | 服务器选证书 | 服务器选站点/后端 |
在代理配置里,两者经常故意设成不同的值——比如 SNI 报一个大站的域名(让握手看起来平常),而 WebSocket 的 Host 头填真实的伪装域名。所以你会在同一个节点配置里同时看到 sni 和 ws-opts.headers.Host,它们各管一层,不是重复配置。
三种典型的配错场景
一、连的是 IP,没设 SNI
节点直接填了服务器 IP,而服务端配置了基于域名的证书。握手时客户端不报 SNI(或报了 IP),服务器不知道给哪张证书,可能给一张默认证书——然后客户端验证失败。
改法:在节点配置里显式设 sni 为证书上的域名。
二、SNI 和证书域名不匹配
证书签给 a.example.com,SNI 却报了 b.example.com。服务器可能给出证书,但客户端一验证发现域名对不上,直接中断。
这时候正确的做法是把 SNI 改对,不是打开 allowInsecure。 后者会关闭整个证书校验,等于放弃 TLS 的身份验证,中间人可以解密你的全部流量——用一个安全问题去掩盖一个配置问题。
三、启用了 TLS 却完全没设 SNI 也没设 Host
有些服务端能容忍,有些直接拒绝握手。这种情况报错通常最含糊,就是「连接失败」。
用节点链接解析器解开链接时,如果发现 security=tls 但既没有 sni 也没有 host,工具会专门提示这一点——它是那种「不一定错,但很可能是问题源头」的情况。
在不同协议里它叫什么
字段名不统一,看到下面这些指的都是同一件事:
sni(VLESS / Trojan / Hysteria2 的 URI 参数)servername(Clash 配置里 VMess / VLESS 节点的字段名)peer(部分 Trojan 配置的写法)
Reality 里的 sni 稍有不同:它填的是借用的那个真实网站的域名,而不是你自己的域名——因为 Reality 本来就不用自己的证书。
怎么排查
如果某个节点连不上,而其它节点正常:
两个工具都在你的浏览器里运行,链接和配置不会上传。
小结
- SNI 是握手时明文报的域名,服务器据此选证书
- 它和 HTTP 的 Host 不是一回事,在代理配置里经常故意设成不同值
- 域名不匹配时应该改 SNI,不是开
allowInsecure - 不同协议里它可能叫
sni、servername或peer
相关文章
Reality 是什么,它和普通 TLS 差在哪
节点链接里出现 security=reality、pbk、sid 这些参数时,说明它用的是 Reality。本文说明它借用真实网站 TLS 特征的原理、为什么不需要自己的域名和证书,以及 pbk / sid / fp 各是什么。
订阅地址打开是一大串乱码,那到底是什么
在浏览器里打开机场订阅地址,看到的往往是一长串没有换行的字符。那不是加密,是 Base64 编码的节点清单。本文说明它的结构、为什么要编码、以及三种常见的订阅返回格式怎么区分。
规则写对了却不生效?多半是顺序放错了
Clash 的规则从上往下逐条匹配、命中即停,所以一条宽泛的规则放在前面,会让它后面所有具体规则永远不执行。本文说明正确的排列顺序、GEOIP 为什么必须靠后,以及怎么验证某个域名到底命中了哪条。