V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wangyu17455
V2EX  ›  程序员

使用支持 websocket 的 cdn 保护 mc 服务器

  •  
  •   wangyu17455 · 85 天前 · 3352 次点击
    这是一个创建于 85 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言:朋友的 mc server(java 版,1.12.2,日均玩家 10-15 人,mod 服),在多次遭受 ddos 攻击之后,朋友找到我,询问有没有一种方法可以以较低的成本保护他的 mc 服务器。

    最开始考虑的方案是高防 ip ,高防 ip 的好处是操作简便,无需任何多余的设置,缺点则是价格贵,防御和机器配置绑定,若是购买通用高防服务器,想要获得足够的防御,需要购买对于 mc 开服来说过多核心(比如 8 核 e5)的服务器,若是购买 mc 专用的高防 ip ,则面临着超售严重和价格昂贵的问题。

    随后又考虑了 cdn 方案(在玩家的客户端架设正向代理将 tcp 连接转为 websocket 连接经过 cdn 传输到 mc server),我最先想到了经常被 mjj 拿来拯救被墙机器的 cloudflare(下文将简称为 cf),通过 cf 的边缘节点走 cf 的内网回源到 mc 服务器,期间尝试了优选 ip 等一系列骚操作,但是最终因为延迟问题被迫放弃。

    随后我将视角转向了国内 cdn ,国内 cdn 厂商相比 cf 有两大不足,一是需要备案,二是不免费+只能后付费,可以被有心人很轻易地刷出天价账单,但是胜在延迟低。可选的加速方式有全站加速(可以加速任意基于 tcp 的协议)和 http 加速,在价格上,全站加速的价格远高于普通的 cdn 的 1g0.2 元的均价,不考虑,最终决定使用支持 websocket 的 http 加速。此时只剩最后一个问题需要解决,如何避免被有心人刷出天价流量账单,经过我的多番寻找,最终找到了一个接近完美的方案:域前置。若是使用明文的 http 方案,攻击者可以加群下载客户端之后抓包获得加速域名,若是使用默认的 https 方案,会在两个地方暴露连接的域名,一是 dns 解析,二是 tls 握手中客户端发送的 sni ,对于 dns 解析,我们可以使用一种叫做 cname 拉平(对 cname 类型的 dns 查询直接在服务端进行递归的解析直到最终获得 ip)的方案,假设我们使用某 cdn 加速域名 example.com ,cdn 提供者会返回给我们一个 cname 域名,类似这种格式:example.com.xxx.yycdn.com ,对此域名进行递归的解析,一般来说会解析到 yycdn.com ,因此我们可以直接对 yycdn.com 建立 https 连接,而不必对带有我们域名 example.com 信息的的加速域名进行连接。对于 sni ,我们可以使用域前置技术,域前置技术简单地说就是 tls 握手中发送的 host A 和 http header 中发送的 host B 不一致,host A 放入 sni 中明文发送,而 host B 则是被 tls 连接保护,不会泄露。决定回源到哪个域名的是的是 host B,决定连接安全性的则是 host A ,只要 host A 的私钥或者百度的日志不泄露,那么 host B 就不会被解密出来(当然二进制文件里的 host B 字段也需要通过混淆 /加密 /加壳等方式保护好)。经过测试,距离较劲的玩家延迟增加了小于 20ms ,而较远的玩家延迟没有明显增加,日均玩家 10-15 人,一个月流量 500g 。以下是 demo

    yu1745/websocket_tunnel: 将 tcp 连接转为 websocket 连接使其可以通过 cdn 传输 支持域前置技术以隐藏域名 (github.com)

    54 条回复    2022-07-24 09:02:01 +08:00
    zhishixiang
        1
    zhishixiang  
       85 天前
    竟然有这么好的技术,我也是开 mc 服的,支持一下
    zhishixiang
        2
    zhishixiang  
       85 天前
    希望能出详细使用教程
    40huo
        3
    40huo  
       85 天前 via iPhone
    域名还是需要接入 cdn 吧,必须备案
    wangyu17455
        4
    wangyu17455  
    OP
       85 天前
    @zhishixiang 有什么不懂的可以在 github 上提 issue😋
    wangyu17455
        5
    wangyu17455  
    OP
       85 天前
    @40huo 不需要,百度的 cdn 不验证 txt ,随便填个 ddns 域名就能用
    40huo
        6
    40huo  
       85 天前 via iPhone
    @wangyu17455 神奇,阿里腾讯都是需要先验证的。另外 https 也可以抓包,加群下载客户端的情况还是会有风险。
    wangyu17455
        7
    wangyu17455  
    OP
       85 天前
    @40huo https 抓包只能抓到 sni ,而文中已经提到了,可以发送假的 sni 来防止暴露域名,这个假的 sni 可以是任意一个使用了百度云 cdn 进行加速的域名
    jackadm1n
        8
    jackadm1n  
       85 天前
    感谢大佬分享这么好的技术文章,学习了
    debugman66
        9
    debugman66  
       85 天前
    @wangyu17455 大佬,有个地方不太理解,此时原域名已经 cname 解析到了 example.com.xxx.yycdn.com
    如果域名暴露了会怎么样呢 可以解密出服务器的源 ip 吗还是
    libook
        10
    libook  
       85 天前
    V……VPN 是不是也可以。
    假设服务器本身就开了白名单机制,那么玩家群体就是确定的,每个玩家分配唯一的 VPN 密钥,有攻击就可以查出来是谁。
    40huo
        11
    40huo  
       85 天前
    @wangyu17455 #7 可以看下 https://github.com/mitmproxy/mitmproxy 和 burpsuite 的功能,通过安装系统根证书的方式,可以抓到 https 明文内容。
    wangyu17455
        12
    wangyu17455  
    OP
       85 天前
    @debugman66 原域名不解析到 cdn 给你的 cname 域名,加速仍然生效,至少百度是这样
    wangyu17455
        13
    wangyu17455  
    OP
       85 天前
    @40huo cdn 里打开 https 双向认证即可
    rev1si0n
        14
    rev1si0n  
       85 天前
    @libook 这样的话,VPN 得要服务器(或者直接架在 MC 服务器上),但是,这 VPN 也是个服务呀,DDOS 它就行了还是影响玩家
    wangyu17455
        15
    wangyu17455  
    OP
       85 天前
    @rev1si0n 理论上可能,实际上无法实现,限制代理的连接数和速度就可以,mc 客户端到服务器只需要一条连接,那么想要 ddos 就需要在所有发起 ddos 的机器上都运行一份这个代理程序
    rev1si0n
        16
    rev1si0n  
       85 天前
    @wangyu17455 有没有一种可能,DDOS 并不需要具体协议。
    wangyu17455
        17
    wangyu17455  
    OP
       85 天前
    @rev1si0n 在不反编译我的程序的情况下一台机器只能 mc server 建立一个被限速的连接,而且我还可以禁止代理程序多开,那么谈何 ddos 呢
    libook
        18
    libook  
       85 天前
    @rev1si0n #14 这样啊,我以为是针对 MC 联机协议的攻击……那就只能用 CDN 来扛了
    docx
        19
    docx  
       85 天前 via iPhone
    @wangyu17455 #5 百度智能云?
    wangyu17455
        20
    wangyu17455  
    OP
       85 天前
    @docx 目前只测试过这一家
    des
        21
    des  
       85 天前 via iPhone
    百度 cdn 用 websocket 我记得要申请?
    wangyu17455
        22
    wangyu17455  
    OP
       85 天前
    @des 在线实时开通,不需要等
    ChenYFan
        23
    ChenYFan  
       85 天前
    国内 Websocket 不好搞吧。。。这东西很容易拿来当梯子用,我没记错的话有些是要客服申请的
    wangyu17455
        24
    wangyu17455  
    OP
       85 天前
    @ChenYFan 算是漏洞,本来是要备案才能用,但是百度 cdn 添加加速竟然不需要任何的验证
    SomeBottle
        25
    SomeBottle  
       85 天前
    有点意思,感谢技术分享
    Les1ie
        26
    Les1ie  
       85 天前
    不少的 CDN 厂商在去年的这个时候修复了域前置的 bug ,没想到现在还有漏网之鱼 :)

    另外,现在的 MC 玩家越来越硬核了,域前置 websocket 都给整上了,我这通过 OpenVPN 联机玩 MC 的瑟瑟发抖 :(
    Sakura
        27
    Sakura  
       85 天前
    感谢技术分享
    cherryas
        28
    cherryas  
       84 天前
    看不懂,说错了别笑我,

    请求肯定会走 ip 对吧,抓到 ip 然后,ddoc 拉满,不就行了。
    Greenm
        29
    Greenm  
       84 天前
    @cherryas 只能看到 CDN 的 IP ,没有意义
    iqoo
        30
    iqoo  
       84 天前
    既然都用加壳的客户端了,不如搞个私有协议的敲门方案。
    jsq2627
        31
    jsq2627  
       84 天前
    还是能够被伪造证书 MITM 抓包获取 Host 。所以还需要配合 SSL Pinning 解决
    liaohongxing
        32
    liaohongxing  
       84 天前
    ddos 无脑发 tcp 包就可以了。流量大到将百度云 CDN 打垮。百度云 CDN 拉你入黑名单停 24 小时或者直接给你 cname 解析到源站去,国内 CDN 普遍不替你扛 ddos 攻击, 付钱另外说。
    ragnaroks
        33
    ragnaroks  
       84 天前
    我是做 csgo 社区服的,如果开服收益足够的话考虑下云堤;这个方案应该只有 CF 这种免费无限量抗 D 的适用。
    gam2046
        34
    gam2046  
       84 天前
    @wangyu17455 #17 ddos 本质并不向服务端发送数据,也不存在限速可以抵御 ddos 的情况(比如原始的 syn flood)。同时与你的应用层协议也无关,ddos 还是针对 tcp 设计的 bug 来实现的。当然现在的演变,不在局限于早期的 ddos ,也有一些基于应用层协议的 ddns 应用方式。但如果是返璞归真,纯真的 ddos ,只要是基于 tcp 的上层协议,无论做什么都逃不掉。区别只是攻击方与防守放谁愿意付出更大的成本。
    wangyu17455
        35
    wangyu17455  
    OP
       84 天前
    @liaohongxing 文章花费了大量的篇幅讲怎么藏域名,攻击者是不知道我的域名的,攻击者只能 ddos 我设置的假域名,也就是那个 host A
    wangyu17455
        36
    wangyu17455  
    OP
       84 天前
    @gam2046 朋友目前受到的攻击主要是 100g 以下的 udp 反射攻击,这个程序主要是为了防御这种攻击
    liaohongxing
        37
    liaohongxing  
       84 天前
    你没明白的我的意思

    CDN 探测到攻击后 ,后续的新请求 CDN 可以改变它那个 cname 的值直接指向你的源站 IP ,避过他的 CDN 系统,直接指向你的源站 ,后续的攻击洪水直接到达你的源站。

    攻击 abc.com -> cname -> abc.com.cdn.com -> 192.168.1.1(CDN) -> 192.168.1.0(CDN) -> 223.5.5.5(源站)

    CDN 探测到攻击后

    攻击 abc.com -> cname -> abc.com.cdn.com -> 223.5.5.5(源站)


    你这模式只适合 CF 这种免费替人扛 D 的服务商,国内普遍不免费替人扛 D
    wangyu17455
        38
    wangyu17455  
    OP
       84 天前
    @liaohongxing 假设我设置的假域名是 a.com ,真域名是 b.com ,我既不会向 a.com 连接,也不会向 b.com 连接,而是会向 a.com 递归解析到倒数第二层的 cname 连接,倒数第一层是 ip ,倒数第二层是一个不带任何前缀的所有使用了百度云 cdn 的域名共享的 cname ,我会向这个地址发起连接,然后此时你抓包抓到的是假域名 a.com 的 sni ,ddos 导致 a.com 回源与 b.com 无关,你只能向 a.com 发起 cc 攻击,如果你攻击代理程序监听的端口,我限速限连接数限多开就好了
    liaohongxing
        39
    liaohongxing  
       84 天前
    朝共享的顶级 cname 的 "IP" 发起连接这样是可以, 如果这一 IP 入口受到攻击,CDN 只能通过 BGP 或其他技术调度流量,牺牲这一节点, 如果这样,国内 CDN 一般都有惩罚机制 。限制你的使用

    如果只在 cname 这层 ,CDN 完全可以控制 cname 的指向的 IP 切走流量,不走它们 CDN 系统。
    shynome
        40
    shynome  
       84 天前 via Android
    有客户端了直接 VPN 不就好了
    wangyu17455
        41
    wangyu17455  
    OP
       84 天前   ❤️ 1
    @shynome 露了 ip 就要被打,不能露 ip
    LnTrx
        42
    LnTrx  
       84 天前
    如果 CDN 提供商不阻止、正向代理不被破解或多开,那确实有可行性
    LnTrx
        43
    LnTrx  
       84 天前   ❤️ 1
    @liaohongxing 在楼主的方案下,如果根据 DNS 或 SNI 攻击,CDN 是罚不到楼主域名上的
    noyle
        44
    noyle  
       84 天前
    @LnTrx 所以说这种情况对CDN危害很大。以前支持Domain Fronting的Google和Cloudfront都“修正”了这个bug了: https://en.wikipedia.org/wiki/Domain_fronting#Disabling
    hanguofu
        45
    hanguofu  
       84 天前
    楼主这个方案挺好!谢谢分享~
    Shiroka
        46
    Shiroka  
       84 天前 via iPhone
    CloudFlare Spectrum 好像就可以这么做,虽然在大陆用起来会很慢: https://www.cloudflare.com/zh-cn/products/cloudflare-spectrum/minecraft/
    geekvcn
        47
    geekvcn  
       84 天前 via Android
    15 人服务器收益那么高能覆盖成本?感觉亏本的事直接关了服务器得了
    wangyu17455
        48
    wangyu17455  
    OP
       84 天前
    @Shiroka cf pro 送 5g 流量,超出 1g1 刀,business 送 10g ,超出也是 1g1 刀,Enterprise 无限流量,其实即使没有延迟问题也不能直接用 Spectrum ,还是得 ws 中转,1g1 刀这价格就离谱
    lizhenda
        49
    lizhenda  
       84 天前
    思路不错哦
    40huo
        50
    40huo  
       83 天前 via iPhone
    @wangyu17455 再问下,cdn 上开 https 需要上传证书,这时候怎么处理呢,因为填的接入域名是个备案的,必须传自己备案域名的证书么
    wangyu17455
        51
    wangyu17455  
    OP
       83 天前 via Android
    @40huo 将 ddns 域名解析到国外 ip 上用 certbot 申请证书,过程手要快,花生壳等 ddns 解析到国外 ip 会光速封,然后再去收个手机验证码解锁域名,然后你就获得了一张 3 个月的证书
    hanguofu
        52
    hanguofu  
       83 天前 via Android
    也就是说上传给 cdn 的证书是假域名 host A 的证书?
    wangyu17455
        53
    wangyu17455  
    OP
       83 天前 via Android
    @hanguofu 是真域名的证书,虽然 tls 握手是和假域名握手,但是你不上传证书 cdn 不允许你开启 https
    wangyu17455
        54
    wangyu17455  
    OP
       74 天前
    寄!百度把 bug 修了,现在使用 cdn 必须备案了,不能添加 ddns 域名了
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2214 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 07:10 · PVG 15:10 · LAX 00:10 · JFK 03:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.