人间工作P 人间工作P
主站 (opens new window)
首页
  • Bukkit开发教程
投喂
关于
  • 分类
  • 标签
  • 时间线
  • 友情链接

人间工作P

我每天都好困… 最近在学习和进行 VOCALOID 创作
主站 (opens new window)
首页
  • Bukkit开发教程
投喂
关于
  • 分类
  • 标签
  • 时间线
  • 友情链接
  • 我在防 DDoS 网络攻击这块的一些个人见解

    • 前言
      • 之前我是怎么做的
        • 现在我是怎么做的
          • 学习Web的策略,不要暴露源站
            • 具体做法
              • 尾声
                • 彩蛋
                MrXiaoM
                2024-09-18
                Minecraft
                目录

                我在防 DDoS 网络攻击这块的一些个人见解

                运营 Minecraft 服务器,尽可能低成本地防 DDoS 的一次尝试

                本文是我在 QQ空间的说说 (opens new window) 的补全。
                我并非网络相关从业者,仅业余研究,个别专有名词可能出错,请见谅。

                防 DDoS,简单来说就是一句话:得加钱。

                # 前言

                开 Minecraft 服务器的,提供网络服务的,稍微做大了之后,总会得罪同行或者用户,就免不了受到网络攻击。

                网络有很强的匿名性,网络攻击也一样。

                攻击者可以从「国外」的木马劫持大量用户(俗称僵尸网络),针对一个IP发动攻击,诸如 UDP Flood,TCP SYN Flood 等等,攻击者对僵尸网络中的设备有完全控制权,他们想怎么打就能怎么打,使得你的服务器无法为正常的用户提供服务。又因为攻击来自世界各地的被控制设备,以我们普通用户的视角,从技术上几乎不可能跟踪到攻击者。

                攻击者还可以从「国外」的匿名邮箱向网络服务提供者(我)发动挑衅,炫耀自己瘫痪网络服务的所谓「高光时刻」和「展示优越感」。

                我两次提及国外,就是因为虽然《中华人民共和国刑法》中有规定「破坏计算机信息系统罪」,但是攻击者的匿名性极高,以我个人开发者的角度考虑,国家没有必要浪费宝贵的网安资源,为了一个无足轻重的互联网服务把攻击者揪出来。也不是在说我国的法律存在漏洞或者执法人员不作为,而是站在互联网的视角,这是相当困难的一件事。即使国家全力帮助,也不一定能揪出来,因为这涉及了跨国的所谓「隐私」网络服务,别国不一定给数据。所以,当资金不足时(如个人业余开设网络服务,常见于 Minecraft 服主),遇到了网络攻击是非常无奈的一件事。

                我本来不想说,西方对于「隐私」的自由,变成了犯法者「隐藏自己」的自由。这是很悲哀的。

                # 之前我是怎么做的

                综上所述,在相当长一段时间里,我的应对策略就是不管,毕竟我可控的范围只有路由的下游,也就是服务器。网络流量先经过路由再传输到服务器,我编写软件拒绝了流量又怎么样,量大的时候依然占用服务器算力,过了阈值之后路由还是会把应当传输到服务器的流量指向黑洞。

                回到了那句话,想要提升防御,得加钱。对于个人来说,购买防御会对月租产生巨大影响,使得防御成为服务器的最大支出,所以,我也没什么办法,你爱打我我让你打个够吧。防御跟不上,但精神不能怂,来「威胁」我,必骂回去。

                今年二月左右,服务器被攻击过,攻击者还通过匿名邮件服务 proton.me 发来了「预告」,

                btw,经过之后群友的确认,对方是冒充成维塔斯的,维塔斯拒不承认这是他。

                攻击者并没有达到他承诺的“打到服务商退机”,打了几天就没动静了。

                反正没打了,那我也不管什么攻击了。

                # 现在我是怎么做的

                2024年9月17日,中秋节,下午13点半左右受到攻击,当时我没看服务器,下午14点左右,在我向群里的人公布服务器被攻击后,我又收到了一封匿名邮件

                看着很像2月的老熟人啊,但是严谨来说,我也只能说和他很像,一样说僵尸网络不算资源(这次还截了在 FinalShell 执行 botnet 命令的图来炫耀,我就懒得放出来了,没啥好看的),一样不勒索纯攻击,很像,不一定是。这次可能是虚了,只打了几个小时,下午四点多就没打了。

                看他不回复我就把 proton.me 这个域的邮件全部拒收了,他会一击脱离我也会一击脱离。

                事不过三,我开始想怎么能低成本的尽可能防范 DDoS 攻击。

                # 学习Web的策略,不要暴露源站

                Web 的什么策略我不知道,毕竟我不是相关从业人员,只是业余搞网络安全的,我只记得有个机制是有源站和节点(负载均衡?),源站是 Web 服务器的核心逻辑,而节点用于分担服务器负担,顺带过滤掉一部分无用流量。

                攻击者尽管打,只能打死节点,除了节点服务器和源站管理员,没有人知道源站的IP,源站一直是安全的,不会因为网络攻击而进入流量黑洞。

                在这个模式下,攻击者打死节点之后,管理员可以迅速恢复服务的正常访问,只需要再建一个节点就行了,毕竟源站没进黑洞,不需要等解封时间。建节点的成本是很低的,国外最低有 8¥/mon 的(配置太低了,没租过),还支持支付宝和 Paypal 支付,我租的 16¥/mon 的作为备用。尽管打,大不了我这个月多租几个节点(只租一个月),一些节点不公开,只给部分信任的玩家使用。

                这个价钱,总比每个月千把块托管费升级 300G 或更多一点的防御好多了吧?对于像是我的服务器一样有点名堂但不是特别火的服务器,是支付不起那么高的托管费的。虽然这个方法不能 100% 扛住,但至少能保证服务不会中断很久。

                以上想法我已经基本实现了,未经过测试,理论是可以做到快速恢复正常访问的。
                现在源站IP还是暴露的,我在等下一次攻击者来攻击源站,因为现在攻击者没在攻击,玩家还要正常游戏,不能打断玩家。等攻击者来攻击,我再向机房申请换一个 IPv4 地址,测试这套机制的效果。

                # 具体做法

                正如你所见,节点服务器的配置非常低,这才能让我们低成本地去租赁它。首先就是要找一个服务商,能够稳定地出租这么低价的云服务器,并且起码要有 25565 端口使用(如果你不在乎这个,其它端口也没关系)。

                补充:主要使用的节点请尽可能购买中国大陆境内的大带宽云服务器,除非你想让玩家延迟人均 200ms。国外的低成本云服务器用来兜底。
                国内便宜的、带独立IP的云服务器不好找,毕竟国内金子带宽,没办法,我也没找到。我现在在用 60¥/mon 的不限流量 25M 上下对等带宽的云服务器凑合着用。
                btw,尽量不要买限制流量、流量耗尽时降带宽的云服务器。就我服务器而言,一天下来,上行加下行要跑 200G,付流量费肉疼。

                所谓「节点」的实现方法是「反向代理」,这里我使用的反向代理软件是开源的 hopper-rs (opens new window),在 x86 架构的 Debian Linux 系统上运行。

                首先下载 hopper-rs 到 /opt/hopper 目录,以下命令在 root 用户下运行

                mkdir /opt/hopper
                chmod u+x .
                wget -O hopper.tar.xz https://github.com/BRA1L0R/hopper-rs/releases/download/v0.6.2/hopper-rs_null_x86_64-unknown-linux-musl.tar.xz
                xz -d hopper.tar.xz
                tar -xvf hopper.tar
                chmod u+x hopper
                
                1
                2
                3
                4
                5
                6

                是的,hopper-rs 不会自己创建配置文件,所以配置文件得你自己来。 创建 Config.toml,将 <节点端口> 替换成一个该节点需要开放的服务器端口号 (比如25565),将 <源站IP> 替换为你自己的服务器IP,后面的端口号先待定,之后要改,反正肯定不是你之前进服的端口。

                listen = "0.0.0.0:<节点端口>"
                [routing]
                default = { ip-forwarding = "proxy_protocol", ip = "<源站IP>:25560" }
                
                1
                2
                3

                然后先别急着启动,要修改源站的服务端配置

                  修改 config.yml

                  listeners:
                    # 假如这是你原有的配置
                  - query_port: 25565
                    # ... 以下省略
                    # 然后在缩进结束之前,添加以下配置
                    # 这里的端口 25560 就是上面提到的端口,如有冲突,自行设定
                  - query_port: 25560
                    motd: ''
                    tab_list: GLOBAL_PING
                    query_enabled: false
                    # 重点是这里,把代理协议打开
                    proxy_protocol: true
                    ping_passthrough: false
                    priorities:
                    - lobby
                    bind_local_address: true
                    host: 0.0.0.0:25560
                    max_players: 200
                    tab_size: 60
                    force_default_server: true
                    # 这里缩进结束
                  
                  # 别忘了要把IP转发打开 (好像默认是开的)
                  ip_forward: true
                  
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  12
                  13
                  14
                  15
                  16
                  17
                  18
                  19
                  20
                  21
                  22
                  23
                  24

                  修改 velocity.toml

                  # 将监听端口设置为 25560,跟上面提到的一样
                  bind = "0.0.0.0:25560"
                  # 把haproxy协议打开
                  # 注意,因为 Velocity 似乎没有跟 BungeeCord 一样的多重监听器(我不常用,我不确定),
                  # 开启之后玩家可能无法正常直连进入服务器,需要通过反向代理节点进服。
                  haproxy-protocol = true
                  
                  1
                  2
                  3
                  4
                  5
                  6

                  如果你是单纯的单端,没有用到 BungeeCord 或 Velocity,还需要做一步额外配置, 在上面的 Config.toml 中,将 proxy_protocol 改为 bungeecord, 在服务端 spigot.yml 中,将 bungeecord 开启。

                  以上配置均为重启服务端生效。

                  配置完了,在节点服务器 cd 到 /opt/hopper 目录,执行命令 ./hopper,并使用 Minecraft 客户端尝试连接,检查反向代理是否工作正常。确认正常后,以下开始配置系统服务(开机启动)。

                  首先创建文件 hopper.service

                  [Unit]
                  Description=hopper-rs
                  After=network.target
                  
                  [Service]
                  ExecStart=/opt/hopper/hopper
                  WorkingDirectory=/opt/hopper
                  Restart=always
                  
                  [Install]
                  WantedBy=multi-user.target
                  
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11

                  然后执行以下命令即可

                  cp hopper.service /usr/lib/systemd/system/
                  systemctl daemon-reload
                  systemctl enable hopper
                  systemctl start hopper
                  
                  1
                  2
                  3
                  4

                  最后执行

                  systemctl status hopper
                  
                  1

                  查看服务是否正常运行即可。

                  hopper-rs 的占用很小,主程序加上配置文件的储存占用不到 5MB,运行内存占用目测不到 100MB,比较适合在低配的机器上运行。

                  而且配置也不算复杂,我只要配置好一次,写个脚本,需要创建节点的时候,购买云服务器后上传执行就完成了。

                  补充:为了避免被扫出源站,请不要使用与本教程相同的 25560 端口,并且应当配置好防火墙,

                  • 将原本的 25565 禁止外网访问,如果你不需要在内网直连可以直接删掉
                  • 将代理端口 (如 25560) 设为仅能由节点服务器访问

                  各个系统有各个系统的配置方法,请通过搜索引擎搜索方法。

                  # 尾声

                  这就是我现阶段针对 DDoS 做出的一些尽可能的挽救措施,不让服务器的可用性被攻击者和流量黑洞牵着走。最坏的情况是攻击者把所有节点都攻陷了,但这时源站依然是没事的,这样你就可以在后台更新服务器玩法,给玩家建立期待,而不是干等着攻击者停止攻击,浪费时间。

                  # 彩蛋

                  题外话,在2月被攻击到7月被攻击的这几个月间隔时间里,3389 端口一直在被刷 RDP 请求,看日志估计是在暴力破解 Administrator 的密码。

                  我的应对措施是开源的 RDP 自动封禁软件 fail2ban-win。
                  同时因为 Administrator 太过常用,而且我们服务器后台有良好的用户习惯,根本没人在用 Administrator 这个账户,于是我决定把这个账户弃用,禁止远程控制登录的同时,将密码改到了上百位,并且我没有保存密码。

                  这还不够,我修改了 fail2win,使得所有试图登录 Administrator 失败的 IP 都有 50% 的几率被添加到防火墙黑名单。正如你所见,我禁用了远程控制登录,登录 Administrator 必失败,这个账户变成了一个捕兽夹,封禁了非常多肉鸡的 IP。如图所示 (opens new window),图太大了,就只放链接吧。

                  编辑 (opens new window)
                  #网络
                  上次更新: 2025/04/03, 23:23:45
                  最近更新
                  01
                  记一次从 Sonatype OSSRH 迁移到 Maven Central Publishing Portal
                  04-24
                  02
                  构建 Paper 衍生服务端(Purpur、Folia 等)时使用代理避免拉取失败
                  02-24
                  03
                  Gradle 杂交不同编译目标(Java)的模块到一个jar
                  01-29
                  更多文章>
                  Theme fork from Vdoing | Copyright © 2018-2025 人间工作P | 友情链接
                  • 跟随系统
                  • 浅色模式
                  • 深色模式
                  • 阅读模式