根据我用clash的经验,两种条件满足其中一个就不会发送sni
- server是ip地址且servername为空,验证证书是否和server匹配
- servername是ip地址,server随便是什么,验证证书是否和servername匹配
我一直以来依赖这个特性来用ip证书达到不发送sni的目的,但是当我突然想着试了一下Xray后我发现其实大家的tls的逻辑是一样的,上面这两个条件满足其中一个同样可以不发送sni,验证证书的逻辑也是一样的,那么我就在想reality并不依赖ca,也就是说验证证书这一步其实是验证预构建好的一对公私钥,而不是看servername,那我是不是也一样可以偷自己的纯ip证书,最后是成功了,我差点以为失败了,因为windows服务器的防火墙忘记开了,那么我来放一下配置(关键部分)
{
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "xxx",
"port": 1443,
"users": [
{
"id": "xxx",
"alterId": 0,
"security": "chacha20-poly1305"
}
]
}
]
},
"streamSettings": {
"network": "grpc",
"security": "reality",
"realitySettings": {
"show": false,
"fingerprint": "chrome",
"serverName": "1.1.1.1",
"publicKey": "xxx",
"shortId": "xxx"
},
"grpcSettings": {
"serviceName": "xxx"
}
}
}
]
}JSON{
"inbounds": [
{
"tag": "vmess-Reality",
"protocol": "vmess",
"port": 1443,
"settings": {
"clients": [
{
"id": "xxx",
"alterId": 0
}
]
},
"streamSettings": {
"network": "grpc",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "127.0.0.1:443",
"serverNames": [
""
],
"privateKey": "xxx",
"shortIds": [
"xxx"
]
},
"grpcSettings": {
"serviceName": "xxx",
"multiMode": false
}
}
}
]
}JSON这其实也没有什么花里胡哨的东西,就是很普通的配置,服务端servername是空的,而客户端的servername是1.1.1.1,就是这么写得没有错,需要写的我都用xxx来代替了,由于没有sni所以服务端servername直接放空就行了,客户端由于纯ip不会发送sni所以随便写个什么ip都不会发送sni,dest是我偷我自己的ip证书所以是127.0.0.1,我也试过用htttps://ip:1443是可以访问到网站的。
这么做有什么好处吗,没有什么特别的好处,只是不会暴露域名了。
这个方法的唯一问题在于必须要签个ip证书出来,不然可以说是毫无伪装,总不可能访问我的ip然后跳个别人的ip证书出来吧。为什么这是问题呢,因为肯定有很多人只会一键脚本,而acme目前没有任何一家ca支持ip证书,我之前说过zerossl自动续签那个要收费,免费的要手动签,我相信很多人完全不知道证书的签发流程,根本不知道怎么手动签,而且http验证比dns验证在手动操作的角度来说更复杂,ip证书只能http验证。