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

2022-07-13 10:49:38 +08:00
 wangyu17455

前言:朋友的 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)

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/865848

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX