保护 MTA:SA 服务器免受 DDoS 攻击

发布于 阅读时间 32 分钟

一台 MTA:SA 服务器提供三项彼此独立的服务:22003 UDP 上的游戏、22005 TCP 上的 HTTP 服务器、22126 UDP 上的 ASE 查询。每一项该怎么加固,以及攻击到多大规模就只能靠服务器前面的网络过滤。

Multi Theft Auto: San Andreas 服务器在 DDoS 攻击下的表现,和任何其他 GTA 多人项目都不一样,因为它同时对外提供三项彼此独立的网络服务:22003 UDP 上的游戏流量、22005 TCP 上一个完整的 HTTP 服务器,以及 22126 UDP 上的 ASE 查询。这三项服务可以被分别攻击,而且各自的故障表现都不同。本文先讲您不花额外费用就能自己加固的部分,然后讲这些措施在线路的物理条件面前到哪里为止,最后讲一套对 MTA:SA 有效的 DDoS 防护必须在服务器前面的网络里做到什么。

如果攻击正在进行,最要紧的问题是三项服务里被打的是哪一项。玩家仍然连着,但加入时再也下载不到资源,那么被打的是 22005 上的 HTTP 服务器。服务器从服务器浏览器里消失,而已经连上的玩家照常游戏,那么被打的是 22126 上的 ASE 查询。所有连接同时中断,那么要么 22003 是目标,要么线路被打满了。本文所有内容针对运行在 Debian 12、Debian 13、Ubuntu 22.04 LTS 或 Ubuntu 24.04 LTS 上的 MTA 服务器,命令以 root 身份书写,普通用户请在前面加上 sudo。

MTA:SA 服务器为什么经常成为 DDoS 攻击的目标

MTA:SA 项目是称手的目标,因为它们必须自己公开地址。一台服务器只有在向主服务器列表注册、并随后回答来自外部的查询之后,才会出现在游戏内的服务器浏览器里。那份列表以明文形式给出 IP 地址和端口,因此攻击者根本不需要事先做侦察。

其次是这个圈子本身。德语区和巴西的角色扮演服务器、漂移服务器以及 DayZ 类玩法的移植项目争夺同一批玩家,而在主要游戏时段的一次宕机最引人注目。一个被封禁的玩家、一个闹翻的团队或者一个竞争项目,既不需要什么本事,也花不了多少钱,就能让一个晚上彻底作废。可以直接购买的攻击服务在圈子里叫 booter 或 stresser,每月几欧元卖的正好是两种结果:让 MTA 服务器离线几分钟,或者用延迟尖峰把它变得不能玩。DDoS 攻击在技术上是什么、有哪些攻击类型,请看文章 什么是 DDoS 攻击?。

在技术上,MTA:SA 有两处比其他多人联机修改版更便于攻击者下手。第一,查询位于一个独立的 UDP 端口上,只要一个字节就能换来一份好几千字节的回应。第二,每一台 MTA 服务器都自带一个 HTTP 服务器,它把所有资源的客户端文件交付出去,而且不需要任何登录,谁问就给谁。

真正相关的那些端口

一台 MTA:SA 服务器正好需要三个端口:22003 UDP 用于游戏,22005 TCP 用于内置 HTTP 服务器,22126 UDP 用于 ASE 查询。第三个端口不是可以自由选择的设置项,而是由游戏端口加 123 固定推导出来的。把 serverport 设成 22010 的人,查询就落在 22133 上。

端口 协议 用途 mtaserver.conf 中的指令 是否必须对公网开放?
22003 UDP 游戏流量、连接建立、同步和语音传输 <serverport>22003</serverport> 是
22005 TCP 内置 HTTP 服务器:资源下载、webadmin、resourcebrowser <httpport>22005</httpport> 是,只要下载还没有挪到外部
22126 UDP ASE 查询:服务器浏览器、主服务器列表、状态页面、Discord 机器人 由 <serverport> 加 123 推导出来 仅为了在服务器浏览器里有条目
22 TCP 运营者的 SSH 访问 不在 mtaserver.conf 中 否,仅限您自己的地址
3306 TCP 游戏模式背后的 MariaDB 或 MySQL 不在 mtaserver.conf 中 否,绑定到 127.0.0.1

随附的 mtaserver.conf 里有两个细节就是这样写的,却常常被忽略。httpport 可以和 serverport 使用同一个数值,因为一个是 TCP 端口,另一个是 UDP 端口。另外 serverip 的值是 auto,也应该保持不变:写死一个值会把 ASE 套接字绑定到正好这个地址上,地址一变,列表里的条目就坏了。

ASE 查询协议,以及它为什么是一个放大器

ASE(All-Seeing Eye)是一个纯 UDP 查询协议:数据包的第一个字节决定回应内容,完全没有连接建立过程。MTA 服务器认识五种查询,并在 22126 上回答它们:

  • s 是完整的 ASE 查询。回应以 EYE1 开头,内容包括服务器名称、游戏类型、地图名称、版本、是否设有密码、玩家数、通过 setRuleValue 设置的全部规则列表,随后是每一个已连接玩家的名称、分数和延迟。这份回应没有大小上限。
  • b 和 r 是供游戏内服务器浏览器使用的精简查询。回应以 EYE2 开头,并在源代码中被截断到 1340 字节,以避免分片。
  • x 返回一条缩短的状态信息,v 只返回 ASE 版本标识。

问题就从这里来。一次请求只有一个字节的负载,在线路上是 29 字节(20 字节 IP 头、8 字节 UDP 头、1 字节负载)。一份 1400 字节负载的回应,在线路上是 1428 字节。两者之比约为 49 倍,而且因为 UDP 没有连接建立过程,源地址可以伪造。于是攻击者可以把您的服务器当作放大器去打第三方目标,完全不必进入您的游戏。在完整查询下,这个系数会随玩家数、以及您的游戏模式设置的每一条规则一起变大。

MTA 自己带了两道内置的刹车,值得了解,因为它们解释了为什么有些洪水攻击有效、有些无效。服务器对每个源地址在六秒内最多回答五次查询,随后七秒内忽略这个地址。此外,它把回应缓存十秒,而不是每次请求都重新拼一份。但是,一旦列表里同时有超过 100 个不同的源地址,按源地址的计数就会被完全跳过。而来自僵尸网络或伪造源地址的分布式洪水攻击,正好就是这种情况,所以内置的刹车对一次认真的攻击没有用。

在花钱之前,您自己能做的事

这一节最长,而且是故意的。配置干净的 MTA 服务器能靠自己扛住小型和中型攻击,无论它放在谁那里。

1. 清点:到底有什么在监听?

先看清楚您的服务器对外提供了什么。不要猜,要查:

ss -lntup

应该出现的是 MTA 进程的三行:UDP 上的 0.0.0.0:22003、TCP 上的 0.0.0.0:22005 和 UDP 上的 0.0.0.0:22126。如果那里还出现了 0.0.0.0:3306 上的数据库、一个 Web 服务器或者一个被遗忘的语音服务,就该把它关掉。从外面做一次端口扫描,就能看到攻击者眼中的样子:

nmap -Pn -sU -p 22003,22126 YOUR.SERVER.IP.ADDRESS
nmap -Pn -p 22005 YOUR.SERVER.IP.ADDRESS

服务器自己也带了一个控制台命令。在服务器控制台里用 openports 就能检查这三个端口是否都能从外部访问。

2. 只保留 MTA 真正需要的那三个端口

用 UFW 的话,一份可用的初始配置如下,而且顺序必须完全照此执行,以免把自己关在门外:

ufw allow 22/tcp comment 'SSH'
ufw allow 22003/udp comment 'MTA 游戏'
ufw allow 22005/tcp comment 'MTA HTTP'
ufw allow 22126/udp comment 'MTA ASE'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

包含自救办法的完整说明见文章 设置 UFW 防火墙。在 KernelHost 的 KVM 根服务器和独立服务器上,即使线路被打满,您也可以在紧急情况下通过客户中心里的 VNC 控制台进入系统。

数据库不该暴露在公网上。如果 ss -lntp | grep 3306 显示 0.0.0.0:3306,请在 /etc/mysql/mariadb.conf.d/50-server.cnf 中写上 bind-address = 127.0.0.1 这一行,然后重启该服务。

3. 给 ASE 端口限速,又不从服务器列表里消失

与 SA-MP 不同,MTA:SA 的查询位于一个独立端口上,所以您可以在不影响游戏运行的前提下给它限速。这是这种架构在实践中最大的好处:一条作用在 22126 上的规则不会把任何一个玩家踢出去。

用 nftables 放在一张自己的表里,这样规则集就不会和 UFW 互相干扰:

nft add table inet mtaguard
nft add chain inet mtaguard input '{ type filter hook input priority -150 ; policy accept ; }'
nft add rule inet mtaguard input udp dport 22126 meter aseperip '{ ip saddr limit rate over 3/second burst 6 packets }' drop
nft add rule inet mtaguard input udp dport 22126 limit rate over 2000/second burst 500 packets drop
nft list table inet mtaguard

第一条规则限制每一个单独的源地址,第二条限制整个端口。两条一起才起作用:如果只按地址限制,分布式洪水攻击就会从许多单一来源之间的缝隙里穿过去。这里的数值定得很紧,而这在此处是站得住脚的,因为真正的服务器浏览器只每隔几秒才查询您的服务器一次。用 iptables 时,hashlimit 模块能做到同样的事:

iptables -A INPUT -p udp --dport 22126 -m hashlimit --hashlimit-name mta_ase \
  --hashlimit-mode srcip --hashlimit-above 3/sec --hashlimit-burst 6 \
  --hashlimit-htable-expire 30000 -j DROP

把这个端口彻底关掉的做法是一次权衡,不是什么秘诀:没有 ASE,您的服务器就会从游戏内的服务器浏览器里消失,自然的新玩家来源也就没了。如果您还是想这么做,只写 <ase>0</ase> 是不够的。在源代码中,端口的开放取决于互联网模式和局域网模式的逻辑或,因此只要 <donotbroadcastlan>0</donotbroadcastlan> 还写着,套接字在 <ase>0</ase> 之下依然是开着的。真想关掉这个端口的人,两个值都要设:

<ase>0</ase>
<donotbroadcastlan>1</donotbroadcastlan>

对一个还在成长的项目来说,更实在的路子是:端口保持开放,给它限速,并且让您的游戏模式不要用 setRuleValue 公开多余的规则,从而把放大效应压小。每一条规则都会出现在完整查询里,把回应变大。

4. 给内置 HTTP 服务器减压

在 MTA:SA 上,22005 上的 HTTP 服务器是一块独立的攻击面,因为每一个加入的玩家都要在那里下载所有运行中资源的全部客户端文件。一个带自制模型的角色扮演项目,很快就是好几百兆字节,分散在成百上千个单独文件里。内置的这个服务器是故意做得简单的:没有压缩,工作线程的数量固定。只要几十个并发请求,就足以让真正的玩家在加载界面上卡好几分钟。

最有效的措施是把下载完全从游戏服务器上挪走。MTA 自己就把要交付的文件准备好了,位置在 mods/deathmatch/resource-cache/http-client-files。您用 nginx 或 lighttpd 把这个目录发布出去,然后把地址写进 mtaserver.conf:

<httpdownloadurl>http://cdn.your-domain.tld/mta</httpdownloadurl>

这一下就带来两件好事。下载走的是一个专门为此而生的 Web 服务器,而且不再经过您游戏服务器的地址。如果这个 Web 服务器放在另一台机器上,或者放在内容分发网络后面,那么针对下载的洪水攻击就打不到游戏运行了。要注意:如果外部地址写错了或者访问不到,MTA 会不声不响地切回内置服务器。

如果继续使用内置服务器,那就用上它自己的那些上限。在 mtaserver.conf 中:

<httpmaxconnectionsperclient>5</httpmaxconnectionsperclient>
<httpdosthreshold>20</httpdosthreshold>
<http_dos_exclude></http_dos_exclude>
<httpthreadcount>8</httpthreadcount>

httpmaxconnectionsperclient 把每个客户端的并发连接限制为 5,允许范围是 1 到 8。httpdosthreshold 限制单个 IP 地址在短时间内可以建立多少连接,默认值是 20。http_dos_exclude 把个别地址排除在外,例如您自己的状态页面。httpthreadcount 决定工作线程的数量,默认值 8,范围 1 到 20。值调高对大量小文件有帮助,但要占用计算时间,而这份时间就从游戏运行那里少掉了。

另外请想清楚,同一个端口上还交付了什么。webadmin 和 resourcebrowser 这两个资源在随附的配置里是启动状态,通过 22005 在浏览器里就能打开。管理界面不该毫无防护地放在公网上:请在 acl.xml 里配好干净的权限,建立一个使用长随机密码的独立账号,用不到这个资源时就把它停掉。

5. 用好 mtaserver.conf 里的内置上限

MTA 自带的防护上限比多数项目用到的要多。有些写死在源代码里,有些在 mtaserver.conf 中。下表汇总了在攻击时真正起作用的那些:

上限 默认值 允许范围 针对
每个源地址的 ASE 查询数(写死在源代码中) 六秒内 5 次,随后忽略七秒 不可配置 单点的查询洪水攻击,不含分布式
ASE 回应的缓存(写死在源代码中) 10 秒 不可配置 重复查询造成的计算负载
每个源地址的加入次数(写死在源代码中) 30 秒内 4 次,随后忽略 30 秒 不可配置 来自单个地址的连接洪水攻击
httpdosthreshold 20 1 到 100 按地址的 HTTP 连接洪水攻击
httpmaxconnectionsperclient 5 1 到 8 单个客户端的并发下载
httpthreadcount 8 1 到 20 资源下载时的排队
player_triggered_event_interval 1000 毫秒 50 到 5000 来自客户端的事件洪水攻击
max_player_triggered_events_per_interval 100 1 到 1000 来自客户端的事件洪水攻击
maxplayers 32 不限 完整查询的大小和槽位耗尽
bandwidth_reduction medium none、medium、maximum 服务器满员时的出站带宽

有三个设置值得认真决定。maxplayers 默认是 32,应该与实际情况相符:每多一个槽位都会让完整查询变大,也会增加攻击者可以占掉的连接数。bandwidth_reduction 默认是 medium,取值 maximum 能明显降低出站负载,但要牺牲同步精度。而 <password></password> 不费什么力气就能把您的服务器变成一个封闭圈子,同时列表里的条目还留着:这是应对正在进行的连接洪水攻击最快的紧急手段。

6. 把连接洪水攻击和事件洪水攻击区分开

有两种攻击模式打的不是线路,而是游戏逻辑,而且它们经常被弄混。

连接洪水攻击会快速地一个接一个建立真实连接,直到所有槽位被占满,或者服务器跟不上建立连接的速度。MTA 自己把这一点限制为每个源地址 30 秒内四次连接,随后忽略这个地址 30 秒。刹车当前在做什么,用控制台命令 debugjoinflood 就能看到。这个上限是按地址生效的,一个有上千个地址的僵尸网络会绕过它。对付它,有用的是服务器密码、游戏模式里的白名单,以及作用在 22003 上的速率限制。

事件洪水攻击则来自已经连上的玩家:一个被改过的客户端在循环里不停调用 triggerServerEvent,直到服务器拿不出计算时间为止。MTA 出厂时允许每个玩家每秒 100 个事件,超出之后会带着一条关于事件洪水攻击的提示把人踢掉。如果您的游戏模式用到很多小事件,请在下调这个值之前先核对一遍:设得太紧,它会把自己的玩家踢出去。

除此之外,服务器端的规则和别处一样:永远不要依赖客户端一起发过来的数值,要从事件的发送方确定是哪个玩家,并且给一切会触发数据库查询的东西加上限。一个未经校验、会发起查询的事件,就足以在完全没有网络攻击的情况下把一台服务器拖停。

7. 服务器列表、IP 地址,以及它还会泄露什么

您的 IP 地址保不住秘密。任何连过一次的玩家都知道它,主服务器列表里的条目本来就把它公开了。在前面加一个域名也没用:客户端只解析一次名称,之后就直接和这个地址通信。

您该检查的是,还有什么地方会泄露您的地址。MTA 项目里典型的泄露点有:DNS 里旧的 A 记录和 AAAA 记录、同一台机器上的项目网站、一个带状态显示的 Discord 机器人(它公开读取 ASE 查询)、带有旧主机名的 TLS 证书,以及项目早期的论坛帖子。由此得出一条许多项目学得太晚的规则:当您迁到一个受保护的地址上时,请同时更换旧地址。旧地址留着,它就会留在每一个扫描数据库里,攻击就会绕过防护。

mtaserver.conf 里有两项直接关系到可见性。<serverip>auto</serverip> 保持 auto,除非您非常清楚为什么不这样做。另外 <owner_email_address> 应该填上:这一项缺失或填错,可能会影响在主服务器列表中的可见性。

8. 记录日志,让您在紧急时刻手里有数据

最重要的一步是几乎没人事先做的那一步:在一切正常的时候先建立基线。没有正常值,事后您就说不清每秒 4 万个数据包是很多,还是就是个普通的周五晚上。用 apt-get install -y vnstat sysstat 让测量常驻运行。

事件发生时,先把三个端口分开来看。下面四条命令就够了:

sar -n DEV 1 10
nstat -az | grep -E 'Udp(InDatagrams|InErrors|NoPorts|RcvbufErrors)'
tcpdump -ni eth0 -c 200 -q 'udp port 22126'
ss -tn state established '( dport = :22005 or sport = :22005 )' | wc -l

解读起来比看上去简单。如果缓冲区错误在 CPU 负载很低的情况下上升,说明到达的流量比进程能处理的更多。如果某个核心跑满,而流量看起来正常,那问题在游戏模式里,不在网络上。如果 22126 上的抓包里有大量只带一个字节负载的数据包,那就是一次 ASE 洪水攻击。如果 22005 上的开放连接数长期停在四位数,那被打的是 HTTP 服务器。用 tcpdump 时有一条铁律:一定要用 -c 限制数量,满载状态下抓包会让本来已经过载的服务器更吃力。如何逐项解读这些数值,见文章 在服务器上识别 DDoS 攻击。

服务器日志本身在 logs/server.log,脚本日志在 logs/scripts.log。两个路径都写在 mtaserver.conf 里,可以改到别处。

这些措施到哪里为止

现在说没有任何配置文件能解决的那一部分。前面所有措施都跑在您的服务器上,也就是线路的末端。防火墙规则处理的是已经跑过网线的数据包。您可以把它丢弃,但没法让它没被发出来。

算一下就清楚了。一台典型的游戏服务器挂在 1 Gbit/s 上,也就是每秒 125 兆字节,在 64 字节的小包情况下约为每秒 149 万个数据包。针对这个量级的游戏服务器项目的攻击通常在 5 到 50 Gbit/s 之间,也就是您线路的五倍到五十倍。到那时,您后面的 nftables 规则写得好不好已经无关紧要,因为您玩家的数据包在更早的地方就已经过不来了。

其中数据包速率往往比带宽更早出事。普通的服务器内核视 CPU 和网卡而定,每秒处理几十万个数据包之后就会开始丢弃。因此一次连您线路三分之一都填不满的攻击,也能把服务器打瘫,因为计算时间都花在丢弃上了。运营者的体验是“负载根本不高,可是什么都没了”。

在 MTA:SA 上还多出第三个上限,而且它是最早触发的。服务器在同一个处理流程里读取所有网络端口。22126 上的一次查询洪水攻击会把这个流程占住,以至于真正玩家的同步数据包在接收缓冲区里就过期了,而这远在线路被打满之前就会发生。进程并不会崩溃,只是变慢,玩家看到的是橡皮筋效应。HTTP 服务器同理:它和游戏运行共用计算时间。

为了让您对现实中的量级有个概念:在 KernelHost 的服务器上,曾经过滤过一次打向语音服务器、超过 473.4 Gbit/s、每秒超过 4150 万个数据包的攻击,以及一次打向游戏服务器、超过 112.2 Gbit/s、每秒超过 870 万个数据包的 UDP 洪水攻击。第一例约为 1 Gbit/s 线路所能承载带宽的 473 倍,数据包速率约为它的 28 倍。这种情况没有任何本地设置可用。流量型攻击必须在服务器前面的网络里就被终结。

KernelHost 用什么来应对

每台服务器都标配的持续防护

KernelHost 的每一台服务器都处在一套持续生效、分两级的过滤后面:

  • 第 1 级:全球清洗网络中 17 Tbps 的清洗能力。流量型攻击在靠近来源的地方就被清洗掉,根本不会到达法兰克福的数据中心。
  • 第 2 级:法兰克福本地的 Arbor 实时过滤,容量 3.2 Tbps。就在服务器前面,逐个数据包地识别并丢弃与协议相关的攻击特征。

有三点是关键。防护持续生效,所以不存在让您服务器离线的识别阶段。而且不使用黑洞路由:被攻击的地址留在网络里,被丢弃的只有恶意数据包,真正玩家的连接照常继续。它也不额外收费,而是自服务器开通起就包含在每个服务器套餐中,从 KVM 根服务器、游戏服务器一直到独立服务器。过滤在第 3、4 和 7 层上、在任意 TCP 或 UDP 端口上进行,也就是 22003 UDP、22005 TCP 和 22126 UDP 同时进行。运行地点是德国法兰克福的 maincubes 数据中心。哪些游戏和协议有专属策略,见文章 实时游戏服务器 DDoS 防护。

针对长期被攻击项目的 Advanced DDoS Protection

有些项目不是偶尔被打,而是被有针对性地连打几周。为此有 Advanced DDoS Protection,每月 50.00 欧元起,PrePaid 预付费,没有最低合约期。区别不在于容量更大,而在于控制权:

  • 一个专用防护 IP,来自法兰克福的核心网络。您的服务器会在 KernelHost 网络内部切换到它,您这边不需要做任何改造。
  • 按端口和协议自行管理的防护规则,就在客户中心里。这一点在 MTA:SA 上正是关键:您可以为 22003 UDP、22005 TCP 和 22126 UDP 分别设置规则,而不是把三项差别很大的服务一刀切。
  • 改动实时生效,不用开工单,也不用等。因此您可以在攻击进行当中随时调整。
  • 与具体游戏匹配的防护策略。Multi Theft Auto 有独立的策略,Web 服务器、语音服务器以及可以放在同一个防护地址后面的自研 TCP 或 UDP 程序同样有。

两级防护对比

对比项 标配的持续防护 Advanced DDoS Protection
价格 包含在每个服务器套餐中,不额外收费 每月 50.00 欧元起,PrePaid 预付费
启用 自服务器开通起即生效,无需设置 下单、拿到防护 IP,服务器随即被切换过去
过滤能力 17 Tbps 全球清洗,加上法兰克福 3.2 Tbps 的 Arbor 实时过滤 同一套基础设施,外加自定义规则
地址 套餐自带的服务器 IP 额外的专用防护 IP
规则管理 预先配置好,自动运行 在客户中心自行管理,按端口和协议分开
防护策略 自动识别攻击特征 可按游戏选择策略,包含 Multi Theft Auto
黑洞路由 否 否
适用于 常规情况,偶尔被攻击也够用 长期被有针对性攻击的项目
合约期 与服务器套餐绑定 PrePaid 预付费,没有最低合约期,没有退订通知期,也没有开通费

对大多数 MTA:SA 项目来说,标配的持续防护配上干净的服务器配置就够了。Advanced DDoS Protection 针对的是有人把这件事当成私人恩怨的情况。

常见错误及解决办法

“我把 22126 封了,服务器果然不在任何列表里了,可查询还是一直进来”:那说明套接字还开着。只要 <donotbroadcastlan>0</donotbroadcastlan> 还设着,单独一个 <ase>0</ase> 并不会关闭这个端口。请用 ss -lnup | grep 22126 检查是不是真的没有东西在监听了。

“玩家卡在加载界面,游戏本身跑得很正常”:这不是针对 22003 的攻击,而是 22005 上的 HTTP 服务器到了极限。请用 httpdownloadurl 把下载挪到外部,并检查 httpmaxconnectionsperclient 和 httpthreadcount。

“服务器从服务器浏览器里消失了,上面的玩家却毫无察觉”:那被打的只有 22126。对已经连上的玩家没有后果,对新玩家的流入则有。正确的做法是只给这一个端口限速,而不是给游戏端口限速。

“我们换了 IP 地址,两个小时以后又离线了”:攻击者拿到新地址的渠道和旧地址是同一个,多半是列表里的条目、一个带状态查询的 Discord 机器人,或者一条旧的 DNS 记录。换地址只是争取时间,不是解决办法。

“我们在 22003 上按地址设了每秒 20 个数据包的速率限制”:这太紧了。单个玩家在同步活跃时就已经超过它,而同一个 NAT 地址后面的多个玩家还要共用同一份额度。这样您是在把自己的玩家踢出去。相比之下,在 22126 上把数值设得紧一些反倒没问题。

“我们被防火墙把自己关在门外了”:重启没有用,因为 UFW 会在开机时恢复自己的规则。在 KernelHost,请打开客户中心里的 VNC 控制台,在那里执行 ufw disable。VNC 控制台独立于虚拟机自身的网络运行。

“我原来的主机商把我的 IP 地址封了”:那就是黑洞路由。主机商用它保护自己的网络,对您来说结果和一次成功的攻击完全一样,而且通常在攻击结束后还要持续几个小时。有疑问时请直接问清楚:是过滤还是黑洞路由。这个答案对您可用性的影响,比任何硬件参数都大。

“我们就这么等攻击过去”:奏效的攻击会被重复。请记录带时区的时间点、持续时长、峰值数据和被打的端口。支持工单需要的正是这些信息,这样过滤才能有针对性地跟上。

要点总结

  • 一台 MTA:SA 服务器正好需要三个端口:22003 UDP 用于游戏,22005 TCP 用于内置 HTTP 服务器,22126 UDP 用于 ASE 查询。第三个由游戏端口加 123 固定推导出来。
  • ASE 查询位于一个独立端口上,因此可以给它限速而不把任何一个玩家挡在外面。这是与 SA-MP 最重要的区别,后者的游戏和查询共用同一个端口。
  • 22126 上一个字节的请求就能换来最多好几千字节的回应,而且源地址可以伪造。因此一个不限速的 ASE 端口既是目标,也是放大器。
  • MTA 内置的刹车按源地址生效:六秒内五次查询,30 秒内四次加入。当同时出现超过 100 个源地址时,查询计数会被跳过,分布式洪水攻击于是照样穿过去。
  • 22005 上的内置 HTTP 服务器是一块独立的攻击面。用 httpdownloadurl 把下载挪到外部 Web 服务器上的人,就把它从游戏运行里拿走了。
  • 跑在服务器上的一切只能决定小型攻击的结果。1 Gbit/s 的线路在每秒约 149 万个数据包处到顶,与您规则的质量无关。
  • KernelHost 的两级持续防护包含在每个服务器套餐中,不额外收费,并且不使用黑洞路由。想自己按端口控制规则的人,可以再加上每月 50.00 欧元起的 Advanced DDoS Protection。

如果您的项目已经放在 KernelHost,过滤就一直在工作,您什么都不用打开。若仍然发现异常,请带上时间段、端口和观察到的表现开一个 支持工单,以便为您的地址调整规则。攻击正在进行时,您还可以通过 WhatsApp 紧急聊天联系我们:+43 650 8209883。如果您还托管在别处并且经常被打,迁到法兰克福是更短的路:紧急情况下的后续步骤见文章 严重的 DDoS 攻击:该怎么办?。

常见问题

一台 MTA:SA 服务器真正需要哪些端口?
正好三个:22003 UDP 用于游戏流量,22005 TCP 用于内置 HTTP 服务器,22126 UDP 用于 ASE 查询。前两个在 mtaserver.conf 里写作 serverport 和 httpport,第三个不能自由选择,而是由游戏端口加 123 固定推导出来。其余一切都不该暴露在公网上:SSH 请限制到您自己的地址,数据库请绑定到 127.0.0.1。
为什么 ASE 端口 22126 在 MTA:SA 上是一处独立的风险?
因为在那里,一个字节的请求就会触发一份好几千字节的回应。完整的 ASE 查询会返回服务器名称、地图名称、所有已设置的规则,以及每一个已连接玩家的名称、分数和延迟,而且它没有大小上限。由于 UDP 没有连接建立过程,源地址可以伪造。因此一个不限速的 ASE 端口有两重身份:攻击的目标,同时也是打向第三方目标的放大器。
我可以给查询端口限速而不把自己的玩家挡在外面吗?
可以,而这正是 MTA 架构的好处。与 SA-MP 不同,查询位于一个独立端口上,因此在 22126 UDP 上限速不会碰到任何一个玩家。每个源地址每秒三个数据包已经很宽松了,因为真正的服务器浏览器只每隔几秒才查询一次。请再补一条针对整个端口的规则,否则分布式洪水攻击会从许多单一来源之间的缝隙里穿过去。
把 ase 设为 0 就足以关闭这个端口吗?
不够。在源代码中,ASE 套接字的开放取决于互联网模式和局域网模式的逻辑或。因此只要 donotbroadcastlan 还是 0,端口在 ase 为 0 的情况下依然开着,并继续回答查询。真想关掉这个端口的人,两个值都要设:ase 设为 0,donotbroadcastlan 设为 1。之后请用 ss -lnup | grep 22126 检查是不是真的没有东西在监听了。这样一来,服务器也会从游戏内的服务器浏览器里消失。
我的服务器现在不正常。三项服务里被打的是哪一项?
从症状就能判断。玩家仍然连着,但加入时再也下载不到资源,那么被打的是 22005 上的 HTTP 服务器。服务器从服务器浏览器里消失,而已经连上的玩家照常游戏,那么被打的是 22126 上的 ASE 查询。所有连接同时中断,那么要么 22003 是目标,要么线路被打满了。改动任何东西之前,请先用 sar -n DEV 1 10 和 nstat 测一测。
服务器明明在运行,为什么玩家卡在加载界面?
因为每一个加入的玩家都要通过 22005 上的内置 HTTP 服务器下载运行中资源的全部客户端文件。这个服务器是故意做得简单的:没有压缩,工作线程的数量固定。最有效的措施是用 httpdownloadurl 把下载挪到一台外部 Web 服务器上,由它交付 resource-cache/http-client-files 目录。这样针对下载的洪水攻击就打不到游戏运行了。
MTA 内置的查询刹车能保护我吗?
只能挡住单点的洪水攻击。服务器对每个源地址在六秒内最多回答五次查询,随后七秒内忽略这个地址,此外还会把回应缓存十秒。但是,一旦列表里同时有超过 100 个不同的源地址,这个计数就会被完全跳过。而在分布式洪水攻击或伪造源地址的情况下,这恰恰就是常态。
服务器上的一道防火墙足以应对 DDoS 攻击吗?
对付小型攻击和不讲究的机器人够用,对付流量型攻击不够。服务器上的每一条规则处理的都是已经跑过您线路的数据包。1 Gbit/s 的线路相当于每秒 125 兆字节,在 64 字节的小包情况下能承载每秒约 149 万个数据包。线路一旦被打满,您玩家的数据包在更早的地方就已经过不来了,与您规则集的质量完全无关。
在 KernelHost,我的服务器会在攻击期间离线吗?
不会。我们不使用黑洞路由,您的 IP 地址留在网络里,被丢弃的只有恶意数据包。防护分两级:全球清洗网络中 17 Tbps 的清洗能力,以及法兰克福 3.2 Tbps 的 Arbor 实时过滤。它持续运行,不需要先对攻击做出反应,因此没有识别阶段。三个 MTA 端口是同时过滤的。
KernelHost 的 DDoS 防护要额外付费吗?
不要。两级持续防护包含在每个服务器套餐中,不额外收费,自服务器开通起即生效,从 KVM 根服务器、游戏服务器一直到独立服务器。您既不用订购,也不用开启或配置。另外可以加购 Advanced DDoS Protection,每月 50.00 欧元起,PrePaid 预付费,没有最低合约期,也没有开通费。
什么时候需要额外加上 Advanced DDoS Protection?
当您的项目不是偶尔被打,而是被有针对性地连打几周,并且您想自己掌控过滤时。您会获得一个专用防护 IP,并在客户中心里自行按端口和协议管理防护规则。这一点在 MTA:SA 上正是关键:22003 UDP、22005 TCP 和 22126 UDP 可以分别设置规则。改动实时生效,Multi Theft Auto 有独立的防护策略。

Multi Theft Auto MTA:SA MTA DDoS 防护 游戏服务器防护 22003 端口 ASE 查询 mtaserver.conf Advanced DDoS Protection