V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
austinchou0126
V2EX  ›  宽带症候群

使用 sniproxy 隐藏 SSL 握手时的域名,以躲过 ISP 嗅探

  •  3
     
  •   austinchou0126 · 2019-11-27 14:36:04 +08:00 · 12079 次点击
    这是一个创建于 1829 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在论坛上有不少同学反馈,由于将家中 NAS 的服务暴露到了公网,其中包含了管理页面的 HTTP 或者 WebDAV,导致 ISP 发现并断网发文通知整改。其中有部分回帖称其没有使用 HTTPS 而导致流量被运营商嗅探到。但使用了 HTTPS 服务就万无一失吗?不是的。就算使用了 HTTPS,也有可能在 SSL 握手时域名遭到泄漏,导致运营商可以通过域名形式访问到用户开启的网页服务。

    当然,运营商如何操作的,对于我们来说是一个黑盒,运营商可能通过抓包等方式获取请求中的明文的 SNI 信息。要确保万无一失,您还需要使用加密的 SNI。

    需要注意的是,如果您的 ISP 未分配给您互联网上的地址,此篇教程不适用您的情况。请移步 frp 进行端口映射。


    我们假设以下的这种情况:

    某用户使用了群晖的 NAS,默认 5001 为 DSM 的 HTTPS 连接方式,默认的 5006 为 WebDAV 的 HTTPS 连接方式。而且某用户使用了群晖自带的 DDNS 服务,注册的域名为:customname.synology.me

    用户在路由器上做好了端口映射的设置( 5001:5001,5006:5006 ),暴露给公网的端口,已经不包含 HTTP 明文传输的网页服务了。

    某段时间,该个用户因为使用了 BT 等软件造成短时间的流量过大,导致进入运营商的关注列表。运营商使用了端口扫描的方式嗅探该用户的端口。

    扫描下来,发现用户的路由器上开放了两个端口,5001 和 5006,且嗅探时返回可能为 HTTPS 协议。

    运营商使用:openssl s_client -connect x.x.x.x:5001 嗅探 HTTPS 的握手信息:

    …
    CONNECTED(00000003)
    depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
    verify return:1
    depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
    verify return:1
    depth=0 CN = customname.synology.me
    …
    

    运营商使用 https://customname.synology.me:5001 顺利打开 NAS 的管理页面,判定用户违规架设了 HTTP 类服务。一键三连。


    在这个过程中,关键之处在于:运营商一定要掌握到你的域名地址信息,且能通过 IP + 端口或者域名 + 端口的组合形式访问到。例如 DSM 使用的 Web 服务器,默认只绑定了一个域名和一个证书,在 SSL 握手时服务器会主动发送该证书,导致域名的泄漏。所以我们要做的,就是始终不让运营商掌握到我们使用的域名(通过 HTTPS ),而且要保证,当运营商起疑心,通过技术手段扫描我们的端口时,不能使其访问成功(通过 sniproxy )。

    通过 sniproxy ,我们可以做到:

    • 不暴露自己的域名信息
    • 阻断 IP + 端口的 HTTPS 访问(不出现证书错误页)
    • 只有匹配到正确的域名时才允许访问

    下面直接给出设置的过程,以我自己的 DS918+ 为例,DS918+ 支持 Docker,我将使用 Docker 方式运行 sniproxy。如果您的 NAS 并未提供 Docker 支持,您也可以通过其他方式运行 sniproxy,例如树莓派等等。

    1. 在 DSM 的 Docker 中,搜索 Image:austinchou0126/sniproxy
    2. 下载 Image,创建一个 Container,创建时设置如下:Port Settings 中,删去容器端口为 80 的条目,手动设置一个未占用的端口,例如将 15001 映射至容器的 443 端口(请不要选择默认的 Auto,否则会由 Docker 自动分配一个端口)
    3. Environment 中,添加环境变量:SNIPROXY_LISTEN0_PROTO=tls、SNIPROXY_LISTEN0_PORT=443、SNIPROXY_LISTEN0_FALLBACK=127.0.0.1:4443 (这里选择任一一个无法访问的端口,以阻断不带域名的 HTTPS 请求)、SNIPROXY_TABLE0_SRC0=customname.synology.me (这里填入您的 DDNS 域名)、SNIPROXY_TABLE0_DEST0=x.x.x.x:5001 (这里填入您的 NAS IP 和 DSM 的端口),更多的环境变量请参考 README
    4. 创建并运行这个 Container,此时,您就拥有了一个端口为 15001 的 sniproxy 实例,将会把带有 customname.synology.me 域名访问的 HTTPS 请求转发给 x.x.x.x:5001
    5. 使用 openssl s_client 进行验证和测试:如果通过 IP + 端口访问,将不返回任何一个证书;如果通过域名 + 端口访问,将返回一个正确的证书信息。测试方式:(openssl s_client -connect x.x.x.x:5001openssl s_client -connect x.x.x.x:5001 -servername customname.synology.me
    6. 配置您的路由器的端口映射,将原本直接映射至 NAS 的端口经由 sniproxy 进行转发
    7. 对于其他的 HTTPS 服务(例如 WebDAV ),执行同样的步骤

    配置后流量:Router[:5001] <-—> Docker on NAS[:15001] <-—> NAS[:5001]

    相比于使用 VPN 或者内网穿透这两种方式,使用 sniproxy 有以下的优点:

    • 延续原来的操作方式,而不必改动其他设置,几乎兼容所有的应用
    • 公网可访问
    • 不需要经过中间服务器中转,速度即宽带的最大上行速度

    最后,我建议大家,如果您继续选择将服务暴露给在互联网上,请做好以下的防范措施:

    • 尽量开启 NAS 管理的二步验证
    • 在出口路由器上关闭 ICMP 响应
    • 任何暴露的网页类型服务,请务必使用 HTTPS
    • 使用 sniproxy 来隐藏 SSL 握手时的域名信息
    • 这里补充说明一下,使用默认端口的好处是:在群晖的 App 中,无需再次输入自定义的端口号,只需要输入域名即可。您也可以不适用默认端口,这都取决于您。

    如果您觉得这篇文章对您有帮助,欢迎在 GitHub 上给我的这个 项目 点个 Star,并且分享给有需要的人。

    原文地址: https://blog.evianzhow.com/hide-your-domain-using-sniproxy/

    拓展阅读

    第 1 条附言  ·  2019-11-27 15:12:37 +08:00
    有 V 友觉得我对运营商如何嗅探的预期假设是错误的,这里我也没办法解释,毕竟是一个黑箱。
    如果您觉得有用,您自己收藏并使用即可。
    确实,通过 sniproxy 是我能想到的、除了用 VPN 以外,能够在公网环境下使用 Web 服务的最安全的方式了。因为我有公网 IP,我使用的很多 App 都通过 WebDAV 访问。我还在使用了群晖 DS apps 系列,但我又不想每次使用都连 VPN,也不能忍受 QuickConnect 的龟速。
    所以每个人根据自己的需求来配置吧,真的哪天我这个方法也被找上门的话,那我就乖乖使用 VPN 就得了。
    45 条回复    2023-03-14 13:17:11 +08:00
    ZRS
        1
    ZRS  
       2019-11-27 14:45:51 +08:00 via iPhone
    如果运营商都做到这份上了,对家宽的入站 TLS 请求做 SNI 嗅谈也是很容易的
    austinchou0126
        2
    austinchou0126  
    OP
       2019-11-27 14:52:26 +08:00 via Android
    @ZRS 手动狗头保命。
    那我这么想,那我用假的 TLS 请求给大量的 IP 群发,制造 flooding 是不是也可以误伤好多人?除非运营商再针对 TLS 的状态做一次筛选
    justs0o
        3
    justs0o  
       2019-11-27 14:54:06 +08:00
    都说过多少次了,运营商通过分光镜像,7 层 DPI。不使用类似 VPN 这种无解
    直接给你们运营商用的设备
    https://i.loli.net/2019/11/27/7kICs3uWPaJLbK9.jpg
    justs0o
        4
    justs0o  
       2019-11-27 14:55:36 +08:00
    系统串接或并接于 IP 骨干网上,提供 10G、40G POS 接口,从网络第三层到第七层对每一个 IP 包进行解析
    ZRS
        5
    ZRS  
       2019-11-27 14:58:53 +08:00 via iPhone
    @austinchou0126 嗅探拿到域名之后连一次就能判断了,你文章里折腾这么一圈还不如上个不存在域名的自签证书…
    austinchou0126
        6
    austinchou0126  
    OP
       2019-11-27 14:59:22 +08:00
    @justs0o 我相信可以。
    不是杠,那要是有这样设备,被罚的话岂不是一大片人,既然有这么精准的设备,一抓一个准啊。
    filter valid tls -> check sni -> 测试一下 -> 告知书
    目前看到的暂时是个例现象
    justs0o
        7
    justs0o  
       2019-11-27 15:00:49 +08:00
    @austinchou0126 该设备就在上海电信的城域网骨干上,某位大佬说误封概率很低。
    3dwelcome
        8
    3dwelcome  
       2019-11-27 15:01:07 +08:00
    @austinchou0126 运营商现在监控技术今非昔比,我看到过后台的记录的访问详细记录,想封真是随时封掉。
    什么时候访问 HTTPS 能完全不暴露 SNI 就好了。
    austinchou0126
        9
    austinchou0126  
    OP
       2019-11-27 15:02:19 +08:00
    @ZRS 你上了一个自签的证书,SSL 握手里是没有域名信息了。然后呢?网警当着你的面,Chrome 里忽略不安全的证书继续访问,不一样可以访问到么?
    我这个方法,可以避免嗅探。当然我前面也说了,运营商通过抓包获取到的 SNI,不在讨论的范围内。
    austinchou0126
        10
    austinchou0126  
    OP
       2019-11-27 15:02:43 +08:00
    @3dwelcome ESNI 离我们还太远了
    justs0o
        11
    justs0o  
       2019-11-27 15:03:15 +08:00
    @austinchou0126 不是网警,是不良信息处理中心,每天都在搞这个
    austinchou0126
        12
    austinchou0126  
    OP
       2019-11-27 15:04:27 +08:00
    @ZRS @justs0o
    我不否认各位说的,通过 VPN 方式连回去使用,这样确实是目前最安全最没有后顾之忧的选择。但也意味着,要在移动设备上访问内网服务的话,都必须先开一个 VPN,有些设备没法配置 VPN,例如小米电视。
    justs0o
        13
    justs0o  
       2019-11-27 15:05:55 +08:00
    @austinchou0126 只有 VPN,不然过不了 dpi,以前只管政企,现在民用也管
    ZRS
        14
    ZRS  
       2019-11-27 15:06:11 +08:00 via iPhone
    @austinchou0126 你给的完全是错误的方案啊…为猜想出来的运营商手段给了一个奇怪的错误对应方式。出发点就有问题…
    carlist
        15
    carlist  
       2019-11-27 15:39:07 +08:00
    下载量大的时候被嗅探搞挂刷了午餐肉固件的网件路由又不是一次两次了,只能第二天早上重启路由
    但是墙梯直接被联通 ban 了只能电信,双线负载均衡都不好用的说
    Jirajine
        16
    Jirajine  
       2019-11-27 15:48:00 +08:00 via Android   ❤️ 1
    ESNI 真的还很远吗?也许各大主流网站支持的会很慢,但自己部署的话,一些实验性的 patch ( https://github.com/cloudflare/tls-tris/pull/172 )加上 Firefox nightly,已经可以尝试使用了。
    alphatoad
        17
    alphatoad  
       2019-11-27 16:04:43 +08:00 via iPhone
    这个问题没有运营商内鬼谁也不知道他们到底是怎么搞的
    Worst case dns 指向家宽就搞你
    sni……我不觉得是问题,只要公网能访问就有足够的理由搞你
    deorth
        18
    deorth  
       2019-11-27 17:33:27 +08:00
    了解了一下 ESNI,结果需要 dns 服务商支持。像是群晖或者我用的 tplink 自带的 ddns 不太可能支持这种东西
    cnyang
        19
    cnyang  
       2019-11-27 17:34:20 +08:00
    tls1.3 不久干这事的吗,没必要造轮子吧
    cwbsw
        20
    cwbsw  
       2019-11-27 17:38:31 +08:00
    @austinchou0126
    小米电视是啥意思? VPN Server 架在任意设备上都可以啊。
    Jirajine
        21
    Jirajine  
       2019-11-27 17:56:19 +08:00 via Android
    @deorth 也不是多难的需求,就是添加一个 TXT 记录里面写上自己的公钥而已,这种不支持但你自己的域名肯定可以支持的,用 cloudflare 托管或者拿个小鸡自建 ns 权威服务器都行。
    scukmh
        22
    scukmh  
       2019-11-27 18:33:09 +08:00 via iPhone
    @Jirajine 但是目前只有 Firefox 的开发者预览版支持?
    allin1
        23
    allin1  
       2019-11-27 18:38:15 +08:00
    @scukmh 我记得 70 就有了。etwork.security.esni.enabled
    ZeroKong
        24
    ZeroKong  
       2019-11-27 19:15:20 +08:00
    话说你们有深圳的案例么。。。昨天我问了深圳电信 10000 号。
    他们说他们允许这么做???这是为啥???我都被弄蒙了
    ljy2345
        25
    ljy2345  
       2019-11-27 20:50:25 +08:00
    我的宽带的用户就是电信公司他们查什么
    https://imgur.com/iaFNrC3
    https://imgur.com/p80UzwV
    NSAgold
        26
    NSAgold  
       2019-11-28 02:04:31 +08:00 via Android
    套 cdn,网页服务端口仅允许 cdn 回源。
    justs0o
        27
    justs0o  
       2019-11-28 08:05:03 +08:00
    @NSAgold 也没用,回源的流量电信可以镜像分光进行 dpi
    Chingim
        28
    Chingim  
       2019-11-28 09:01:41 +08:00 via Android
    firefox 支持 esni。再加上 doH doT 美滋滋。


    我在公司就用,不想被网管统计。
    brMu
        29
    brMu  
       2019-11-28 09:12:04 +08:00
    我印象中 nginx 在配置 tls1.3 后,sni 不是强制加密的,意思就是看浏览器,如果浏览器支持 esni,那么整个过程就不会泄漏域名,如果浏览器不支持,那么 sni 还是明文发送的,而且目前好像只有 firefox 浏览器才支持 esni。

    所以请教一下楼主:
    你的这个是 server 端强制了必须走 esni 吗?
    你用非 firefox 浏览器可以打开吗?比如 chrome,360 浏览器?
    austinchou0126
        30
    austinchou0126  
    OP
       2019-11-28 10:01:07 +08:00
    @brMu 不是 ESNI 的解决方案
    这个方案说的很清楚了,只是解决了端口扫描时被发现 HTTPS 以及域名泄露的可能性,无法解决 SNI 泄漏
    brMu
        31
    brMu  
       2019-11-28 11:15:29 +08:00
    @austinchou0126 那就是说如果运营商有监控设备,一旦有访问,还是可以监控到访问的域名是什么?
    xunandotme
        32
    xunandotme  
       2019-11-28 16:54:07 +08:00
    ericww
        33
    ericww  
       2019-11-28 19:14:06 +08:00 via iPhone
    @ljy2345 查业务工单,查关联用户,查光口位置,想找到你有什么不能查的?
    techon
        34
    techon  
       2020-01-04 01:05:46 +08:00
    真要涉及敏感问题,分分钟找你喝茶。一般家庭用户,完全看人家网警的心情,毕竟我们还是人治社会。。
    brMu
        35
    brMu  
       2020-04-16 14:33:54 +08:00
    如果运营商有监控设备,当你在外访问家里的设备时,家里设备会返回证书,此时又被监控设备抓取到了这个证书,不就知道你的证书信息了吗?证书信息里有域名,再尝试访问这个域名不就行了?
    brMu
        36
    brMu  
       2020-04-16 14:42:57 +08:00
    而已客户端也会发送 Client Hello 包,这个包里也会带有 sni 信息,也就是域名,监控设备同样可以抓取到。
    binkcn
        37
    binkcn  
       2020-04-26 11:28:52 +08:00   ❤️ 1
    @brMu ESNI 了解一下,抓包实测 V2EX 已经启用 ESNI 了,无法在 Client Hello 里面看到 server_name 。

    当然了,现在的关键问题是服务器虽然支持 ESNI,但是客户端浏览器默认仍然采用 SNI 直接发送明文 server_name 的话,还是会悲剧,譬如用 Chrome 访问 V2EX,或者 Firefox 不强制开启 ESNI 的情况下。

    不过,这个解决起来并不难了,题主提到的 sniproxy 可以自己修改一下,强制检测 tls 版本必须要求 v1.3,并且 Client Hello 不能包含 server_name 即可。

    过些天我有空的时候搞一下,有结果后我回再来回这个帖子并且 Share 解决方案。
    brMu
        38
    brMu  
       2020-04-26 14:18:57 +08:00
    @binkcn 解释的很清晰,明白了,非常感谢,等你的大招!
    binkcn
        39
    binkcn  
       2020-04-27 14:17:21 +08:00
    @brMu 昨天部署好 sniproxy 之后仔细想了想,其实现阶段来说这样做意义并不大。

    首先,假设按照预期在 NAS 上部署好 sniproxy+esni,并且实现我说的丢弃包含 server_name 的 tls 包,那么我想从外部访问这个 https,仍然需要浏览器支持,目前来说只有 Firefox 经过配置之后可以实现。

    也就是说需要请求方支持(修改一些高级设置)才可以正常浏览,如果是这样的话还不如用传统的 VPN 回家或者 FRP 方案,毕竟我们选择 https 协议的意义就在于:“随时随地方便且安全的访问位于家里 NAS 上的 https 服务”,但是现在并不方便,门槛略高。

    所以,只能等到主流浏览器在无需用户干预的情况下默认支持 tlsv1.3 & esni 时,这个方式才有意义。
    brMu
        40
    brMu  
       2020-04-28 14:04:48 +08:00
    @binkcn 老哥说的有理,那就再等等看,我现在也是用的通道先到家里再开别的。
    binkcn
        41
    binkcn  
       2020-04-28 15:25:03 +08:00
    @brMu 握手,我目前也是隧道回家:)
    guanyin9cn
        42
    guanyin9cn  
       2021-09-02 16:15:42 +08:00
    没说明白,sniproxy 为什么就能隐藏掉 sni ? 怎么做到隐藏掉你的证书?域名信息?
    不是杠,按照你的意思,现阶段还能通过 sniproxy 访问 google 服务?

    另外,根据 tls 握手过程,证书是明文传输的。证书里就有你的域名信息
    leiakun
        43
    leiakun  
       2021-09-03 08:20:29 +08:00   ❤️ 1
    @guanyin9cn 现在 Firefox 隐藏 sni 已经升级到 ECH 了,esni 已经被弃用了。证书密钥可以通过 DoH 分发。
    信息参考:
    http://mozilla.com.cn/thread-426460-1-1.html
    https://blog.mozilla.org/security/2021/01/07/encrypted-client-hello-the-future-of-esni-in-firefox/
    YGBlvcAK
        44
    YGBlvcAK  
       2023-03-11 21:52:24 +08:00 via Android
    这个方案怎么样?通过二级目录代理,比如 https://abc.com/qwert ,只有正确输入二级目录 qwert 才会有返回,如果运营商试探直接访问 https://abc.com 则不做任何返回。
    好处就是即使运营商嗅探到了 sni ,也无法通过域名打开网页,只有正确的二级目录才能打开,而二级目录抓包是抓不到的,除非证书劫持
    austinchou0126
        45
    austinchou0126  
    OP
       2023-03-14 13:17:11 +08:00
    @YGBlvcAK 也是一个很不错的思路。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2846 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 132ms · UTC 12:02 · PVG 20:02 · LAX 04:02 · JFK 07:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.