Team Fortress 2:保护 TF2 服务器免受 DDoS 攻击

发布于 阅读时间 30 分钟

一台 Team Fortress 2 服务器真正需要哪些端口,如何限制 A2S 查询、分片数据包、RCON 和速率而不从服务器浏览器里掉出去,以及攻击到多大规模就只能靠服务器前面的网络过滤。

一台 Team Fortress 2 社区服务器如果在晚上比赛进行到一半时同时失去所有玩家,随后好几分钟从服务器浏览器里消失,那很少是硬件问题。多数情况下是有人正在攻击 27015/UDP。本文讲的是怎样为 TF2 服务器做好 DDoS 防护:先是您在接下来十分钟里不花额外费用就能自己做的事,然后是这些措施在物理上到哪里为止,最后是它前面的网络里必须发生什么。

所有内容针对用 SteamCMD 安装的 Source 独立服务器(srcds_run -game tf),运行在 Debian 12、Debian 13、Ubuntu 22.04 LTS 或 Ubuntu 24.04 LTS 上。命令以 root 身份书写,普通用户请在前面加上 sudo。如果攻击正在进行:现在什么都不要改,也不要重启服务器,而是先保存第 9 节里的测量数据。攻击结束后,这些数据就没有了。

为什么 Team Fortress 2 服务器需要 DDoS 防护

Team Fortress 2 自 2011 年起免费可玩,而正是这一点改变了攻击的经济账。攻击者有无穷多的一次性账号,任何一个都不用花钱,被封禁也毫无损失。在一款买断制游戏里要花钱的事,在这里只花一分钟。

再加上一个把 TF2 与多数其他游戏区分开的特点:自 2016 年 7 月的“Meet Your Match”更新起,那个把新玩家自动分配到社区服务器的 Quickplay 就不存在了。新玩家会在休闲模式下进入 Valve 的服务器。社区服务器只能通过服务器浏览器找到。谁从这份列表里掉出去,对新玩家来说就几乎等于不存在,即使服务器进程运行得毫无问题。因此,一次只是把您的服务器挤出列表的攻击,目标其实已经达到了。

相应地,典型的目标是:有固定玩家的长期运行社区服务器(全天候 2Fort、Trade、Jailbreak、Surf、Dodgeball、Mann vs. Machine),在 ETF2L、RGL 和 ozfortress 的联赛体系中有固定比赛时间的联赛服务器,以及那些运营者刚刚封禁了某人的服务器。触发原因几乎从来不是技术上的。DDoS 攻击到底是什么,请看文章 什么是 DDoS 攻击?。

一台 TF2 服务器真正相关的那些端口

一台 TF2 服务器对外正好需要一个端口:27015/UDP。其余的要么可以关掉,要么应该受限,要么本来就只是出站。下面这张表是后文每一条防火墙规则的基础:

端口 协议 用途 是否可从外部访问
27015 UDP 游戏流量和 A2S 服务器查询共用同一个端口,通过 -port 设置 是,必需
27015 TCP RCON,通过 rcon_password 对服务器进行远程控制 否,仅限您自己的地址
27020 UDP SourceTV(STV),通过 tv_port 设置,可用 -nohltv 关闭 仅在您确实要转播时
27005 UDP 客户端端口,由玩家在出站方向使用(+clientport) 否,服务器上不需要放行
26900 起 UDP 服务器进程的 Steam 端口(-steamport),每多一个实例往上加一 否,仅出站连到 Steam
80 和 443 TCP 用于地图和内容的 FastDL(sv_downloadurl),前提是它在同一台主机上 仅当下载确实放在那里时

一台机器上有多个实例时,编号往上走:游戏用 27016、27017 等等,SourceTV 用 27021 和 27022。配置文件位于 tf/cfg/server.cfg,每次换地图时都会重新读取。

为什么共用的 27015 端口是最敏感的一点

在 TF2 上,游戏流量和服务器查询共用同一个 UDP 端口,没有单独的查询端口。一个 A2S_INFO 请求正好是 25 字节:四个字节 FF FF FF FF,一个字节 0x54,以及 20 字节长的字符串“Source Engine Query”加一个结尾的零。而带有服务器名称、地图、玩家数和标签的回应是它的好几倍。美国机构 CISA 在 TA14-017A 公告中把 Steam 协议的放大系数定为 5.5。

因为 UDP 没有连接建立过程,而发送方地址可以伪造,这在很多年里都是一个敞开的放大漏洞:攻击者用受害者的地址作为发送方去查询别人的 Source 服务器,这些服务器就把回应发给受害者。A2S_PLAYER 和 A2S_RULES 一直都要求先取一个 challenge,A2S_INFO 则不要求。直到 2020 年 12 月,Valve 才给 A2S_INFO 也补上了 challenge:服务器可以不返回回应,而是回一个 S2C_CHALLENGE,查询方必须把它重复回来,以此证明自己没有伪造发送方地址。

这缓解了反射攻击,但麻烦并没有结束。每一个查询数据包仍然会到您这里,并在被回应或被丢弃之前消耗计算时间。而直接冲着您服务器发洪水的攻击者,本来就不需要放大。

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

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

1. 清点:什么在监听,启动行又是怎么写的

在写下第一条规则之前,先看清楚您的服务器对外提供了什么。不要猜,要查:

ss -lntup

凡是绑定到 127.0.0.1 或 ::1 的,都不需要放行。凡是在 0.0.0.0 或 [::] 上的,都能从互联网访问到,包括某个统计插件顺带装上的 MySQL 数据库,以及放着您 FastDL 文件的那台 Web 服务器。请把结果和您的启动行对照:

./srcds_run -game tf -console \
  -port 27015 -steamport 26901 -nohltv \
  +maxplayers 24 +map ctf_2fort +sv_pure 1 \
  +sv_setsteamaccount YOUR_GSLT_TOKEN

这一行里的每一个端口都是一个有意的决定。底层怎么安装,见 用 SteamCMD 安装游戏服务器。

2. 只留 TF2 真正需要的那些端口

一台公开的 TF2 服务器对外正好需要一条放行规则,再加上给您自己地址的 RCON。用 UFW 的写法如下,而且顺序必须完全照此执行,以免把自己关在门外:

ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'TF2 游戏和 A2S'
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment 'RCON'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

请把 203.0.113.10 换成您自己的地址。SourceTV 在这里故意没有出现:不转播的人用 -nohltv 启动,干脆就不占用 27020/UDP。这把一台 TF2 服务器从外部可访问的 UDP 面积减了一半。如果您要转播联赛比赛,就加上 ufw allow 27020/udp,并且这时该设一个 tv_password。

包含自救办法的完整说明见 设置 UFW 防火墙而不把自己关在门外。如果还是出了事:KernelHost 的 KVM 根服务器和独立服务器可以通过客户中心里的 VNC 控制台访问,它独立于虚拟机自身的网络运行。

3. 限制 A2S 查询,又不从服务器浏览器里掉出去

这个题目下最昂贵的错误就在这里:一刀切地封掉 27015/UDP,或者粗放地对它限速,会把自己的玩家踢出去,并且按攻击者的意愿结束这场攻击。因为游戏流量和查询占用同一个端口,界线必须划在数据包类型之间,而不是划在端口上。

引擎为此自带三个控制台变量,它们应该写进 tf/cfg/server.cfg:

sv_max_queries_sec 3
sv_max_queries_sec_global 60
sv_max_queries_window 30

第一个限制每个发送方地址被回应的查询数,第二个限制所有地址加起来的总数,第三个规定以秒为单位的平均窗口。它们保护 CPU,让它不去白白生成回应。默认值随游戏和构建版本不同,在服务器控制台里用 find sv_max_queries 可以看到您的服务器认识哪些值。

第二个值在 TF2 上是敏感的那个:它给所有地址的回应总量加了盖。设得太低,您的服务器在一次查询洪水攻击期间连列表服务的请求也不再回应,于是从服务器浏览器里消失,也就是从新玩家找到您的唯一途径上消失。请从宽松处开始,等到您能测出合法查询确实通得过之后再往紧调。

在更低一层上,同样的流量可以被干净地分开。Source 引擎所有的无连接数据包都以四个置位的字节开头(0xffffffff),而已经连上的玩家的流量没有这个头部。可以在这上面加一道速率限制,而完全不碰游戏流量:

table inet tf2 {
    chain input {
        type filter hook input priority -10; policy accept;
        udp dport 27015 @th,64,32 0xffffffff \
            meter a2sflood { ip saddr limit rate over 10/second burst 20 packets } drop
    }
}

这个文件用 nft -f 加载。优先级 -10 保证这条规则在 UFW 的过滤链之前生效,而 @th,64,32 读取的是 UDP 头部之后的前四个字节。

4. 拦住在日志里表现为 NET_GetLong 的分片包洪水攻击

这种攻击是 Source 引擎的一个特性,而且对 TF2 打击格外大,因为 TF2 至今仍跑在旧的引擎分支上。除了普通的无连接数据包之外,引擎还认识分片数据包:它们以 FE FF FF FF 而不是 FF FF FF FF 开头,并宣告接下来有一条更大的消息会分成几部分发来。服务器必须把这些部分缓存起来,等着剩下的到齐。

正是这一点可以被滥用。攻击者用伪造的发送方地址大量发出宣告过、却永远不完整的分片包。CPU 负载上升,游戏卡顿,服务器日志里满是带 NET_GetLong 的行。一台机器就够了,几乎不需要带宽。运营者经常把这个报成 DDoS 攻击,尽管线路几乎是空的。

因为一个正规的 TF2 客户端几乎没有理由给服务器发分片数据包,所以在这里设一个很严的限制是站得住脚的:

udp dport 27015 @th,64,32 0xfffffffe \
    meter tf2split { ip saddr limit rate over 5/second burst 10 packets } drop

这一行应该写进第 3 节那条规则所在的同一个链里。客户端上传是分片数据包为数不多的合法理由之一,用 sv_allowupload 0 可以把它也从游戏里去掉(见第 7 节)。

5. 把 RCON 从公网上撤下来

Source 引擎的 RCON 协议通过 TCP 以明文传输密码。谁能在您和服务器之间的路径上监听,事后就拿到了您的 RCON 密码,而拿到 RCON 的人可以换地图、封禁所有玩家并停掉服务器。这不是 DDoS 问题,而是一次接管,但它经常被报成攻击。

rcon_password 绝不要留空,也绝不要用能猜到的值,用 openssl rand -base64 32 生成的一个值就够了。配套的还要有一道对付登录尝试的刹车:

rcon_password "A_RANDOM_VALUE_HERE"
sv_rcon_maxfailures 3
sv_rcon_minfailures 3
sv_rcon_minfailuretime 30
sv_rcon_banpenalty 1440

这样服务器会在 30 秒内出现三次失败之后,把一个地址封禁 24 小时;find sv_rcon 可以看到您的构建版本认识哪些变量。不过更有效的仍然是第 2 节里的防火墙规则,因为它根本不让这个尝试走到应用层。要从变动的接入线路访问,请设置一条本地的 SSH 转发,之后在 127.0.0.1 上和 RCON 对话:

ssh -N -L 27015:127.0.0.1:27015 root@YOUR.SERVER.IP.ADDRESS

6. 给速率设上限,并让休眠保持开启

Team Fortress 2 固定以每秒 66.67 个 tick 运行。由此产生多少流量,决定因素不是 tick,而是单个客户端被允许索取多少。没有上限时,每个玩家都会按他的客户端所要求的量去取,而这是用您的出站带宽来付账的:

sv_minrate 50000
sv_maxrate 100000
sv_mincmdrate 40
sv_maxcmdrate 66
sv_minupdaterate 40
sv_maxupdaterate 66

把这个算一遍:在 sv_maxrate 100000 时,每个玩家每秒可以取 100 千字节,24 个位置就是每秒 2.4 兆字节,也就是出站约 19 Mbit/s。如果设 sv_maxrate 0,就没有上限。联赛服务器是有意这么做的,一台位置很多的公开服务器不应该这样。解锁 tick 率的插件会让每个玩家的数据包速率成倍增加,上面这笔账也跟着成倍。

第二点常常被做错。TF2 在没人连接时会进入休眠,在这个状态下几乎不占 CPU。很多运营者把它关掉,让服务器感觉上是“醒着的”。在一台跑着多个实例的机器上,这意味着 CPU 在空载时就已经满负荷,而一次攻击撞上的是一个本来就已经满了的系统。请保持默认设置:

sv_hibernate_when_empty 1
sv_hibernate_postgame_delay 5
tf_allow_server_hibernation 1

7. 把 FastDL 分开,并关掉上传

社区服务器靠自制地图活着,而第二块攻击面恰恰由此产生。没有 sv_downloadurl 时,每个玩家都通过游戏的网络通道下载内容,也就是通过同一个端口、同一个进程,而这个进程同时还在算比赛。那是每秒几千字节、一个文件接一个文件,遇到 200 兆字节的地图包时,每个玩家都会把您的服务器堵上好几分钟:

sv_allowdownload 1
sv_allowupload 0
net_maxfilesize 64
sv_downloadurl "https://fastdl.example.org/tf/"

net_maxfilesize 默认是 15,最高可以提到 64 兆字节。sv_allowupload 0 阻止客户端把自己的文件(例如喷漆图)发给服务器,从而去掉了第 4 节里分片数据包为数不多的合法理由之一。

关键在于 FastDL 主机放在哪里。如果它和游戏服务器在同一个 IP 地址上,那么一次针对 443/TCP 的 HTTP 洪水攻击就足以填满线路,从而把 27015/UDP 也一起闷死。请把快速下载放到另一台主机上,或者放到一个内容分发网络后面,这样针对文件的攻击就打不到游戏。

8. 限制投票系统、连接洪水攻击和插件

不是每一次故障都是带宽问题。因为 TF2 免费,针对游戏逻辑的攻击除了账号之外什么都不花:占满每个位置的连接洪水攻击、语音和聊天灌水,以及被滥用的投票把正规玩家赶出去。TF2 在这方面的默认设置本来是合理的,但常常被放松:

sv_allow_votes 1
sv_vote_issue_kick_allowed 0
sv_vote_allow_spectators 0
sv_vote_creation_timer 150
sv_vote_failure_timer 300
sv_vote_quorum_ratio 0.6

这些就是标准值:允许投票,不允许踢人投票,观众不参与投票,两次投票之间间隔 150 秒,一次失败之后间隔 300 秒,而一次投票需要 60% 的赞成。谁要设 sv_vote_issue_kick_allowed 1,就该知道自己打开了一个在公开服务器上一定会被滥用的工具。

超出这些的一切,在 TF2 上都来自 SourceMod 和 Metamod:Source。两者都位于 tf/addons/ 下,在控制台里用 meta version 和 sm version 报告自己。与 Counter-Strike 2 不同,这里的底层已经成熟,用于封禁列表、加入校验和聊天限流的插件是常规做法。关于这一点有两条规则:每一个插件都是同一个进程里的代码,一个崩溃的插件会把服务器一起带走。而自带 Web 服务的插件会打开更多端口,有时还正好公布了您想保护的那个地址。sm plugins list 会显示实际在跑的东西。

引擎这一侧该有多当真,2020 年 4 月给出了答案:在 TF2 和 CS:GO 较旧的源代码版本外泄之后,Creators.TF 和 Red Sun 这类大型社区运营者出于被利用的担忧,一度关掉了自己的服务器。请让服务器程序保持最新,并让扩展与引擎版本相匹配。

9. 在出事之前先测量、先记录日志

最重要的一步是几乎没人事先做的那一步:在一切正常的时候先建立基线。没有正常值,事后您就说不清每秒 4 万个数据包是很多,还是就是个普通的周五晚上。事件发生时四条命令就够了:

ip -s link show eth0
nstat -az | grep -i udp
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xffffffff"
tcpdump -ni eth0 -c 200 "udp port 27015 and udp[8:4] = 0xfffffffe"

第一条命令按接口显示数据包、错误和被丢弃的数量;请间隔十秒执行两次,这样得到的就是一个速率而不是一个绝对值。两次抓包把查询洪水攻击和分片包洪水攻击分开,从而回答了第 3 节和第 4 节那两条规则到底哪一条必须生效的问题。请一定要用 -c 限制数量,满载状态下抓包本身也要消耗计算时间。

在服务器内部,控制台命令 stats 会用一行给出 CPU 负载、以千字节每秒计的进出网络负载、服务器 FPS 和玩家数。如果服务器 FPS 明显低于 tick 值,而玩家数正常,那说明服务器正在忙别的事,而不是忙游戏。如何给这些数值定位,见 在服务器上识别 DDoS 攻击。

这些措施到哪里为止:带宽和数据包速率

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

把一台满员 TF2 服务器的正常运行状态和一次真实攻击摆在一起,这个比例就清楚了:

指标 满员 TF2 服务器,24 个位置,每秒 66.67 个 tick 攻击
入站数据包 每秒约 1600 个(24 名玩家乘以 66 条指令) 每秒几百万个
入站带宽 明显低于 2 Mbit/s 针对社区游戏服务器通常为 5 到 50 Gbit/s
出站带宽 在 sv_maxrate 100000 时约 19 Mbit/s 不是问题所在
A2S 查询 每个列表服务每分钟几次 每秒几千次
物理上限 1 Gbit/s 每秒能承载约 149 万个最小数据包 10 Gbit/s 每秒能承载约 1488 万个

一台典型的游戏服务器挂在 1 Gbit/s 上,也就是每秒 125 兆字节,只要有人发得比这更多,线路就满了。第二个量是数据包速率,而它通常比带宽先出事:每一个数据包都要走一遍网络栈,即使之后被丢弃也一样。因此,一次连您线路三分之一都填不满的攻击,照样能让您的服务器瘫痪。运营者的体验是“负载根本不高,可是什么都没了”。

为了有个量级上的参照:在 KernelHost 的服务器上,曾经实时过滤掉的攻击包括一次针对游戏服务器、超过 112.2 Gbit/s、每秒超过 870 万个数据包的 UDP 洪水攻击,以及一次针对语音服务器、超过 473.4 Gbit/s、每秒超过 4150 万个数据包的多向量攻击。473.4 Gbit/s 约为一条 1 Gbit/s 线路的 470 倍。对此没有任何本地设置可用。

那两种常见的紧急刹车都帮不上忙。黑洞路由把被攻击的 IP 地址从网络里撤下来,结束了攻击,但也结束了您的服务器。而一次被动触发的改道,会在切换时间里正好花掉决定比赛胜负的那几分钟。真正有效的只有一种:持续运行在服务器前面网络里的过滤。

KernelHost 用什么应对针对 TF2 服务器的攻击

每个服务器套餐都包含的持续防护

KernelHost 的 DDoS 防护分两级,自服务器开通起持续生效,您不需要订购、开启或配置任何东西:

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

有两点对一台 TF2 服务器是关键的。过滤持续运行,不需要先对攻击做出反应,因此不存在一个切换时间,让您的玩家在其中被踢出去、让您的服务器从服务器浏览器里掉出去。而且不使用黑洞路由:您的 IP 地址留在网络里,被丢弃的只有恶意数据包。哪些游戏和协议在覆盖范围内,见 实时游戏服务器 DDoS 防护。

针对长期被攻击服务器的 Advanced DDoS Protection

有些项目不是偶尔被打,而是被有针对性地连打几周,手法不断变化,而且总是恰好卡在比赛时间。为此有 Advanced DDoS Protection,每月 50.00 欧元起,PrePaid 预付费,没有最低合约期。区别不在于容量更大,而在于控制权:

  • 专用防护 IP,来自法兰克福的核心网络,您的服务器会在我们的网络内切换到它。您这边不需要做任何改造。
  • 按端口和协议自行管理的防护规则,就在客户中心里:您可以分别设置 27015/UDP 上允许什么、27020/UDP 上允许什么、27015/TCP 上允许什么,而不用为此写工单。
  • 改动实时生效,因此您可以在攻击进行时随时调整,而不用等到比赛结束。
  • 与游戏匹配的防护策略,既适用于 Team Fortress 2 和其余 Source 系列作品,也有面向自研应用的自由 TCP 和 UDP 策略。

这项服务面向运行在 KernelHost 的服务器。如果您的 TF2 服务器目前放在别处并且经常被打,那么迁移就是通往这套防护的路。

两级防护对比

对比项 标配的 DDoS 持续防护 Advanced DDoS Protection
价格 包含在每个服务器套餐中,不额外收费 每月 50.00 欧元起,PrePaid 预付费
启用方式 自服务器开通起即生效,无需设置 下单、获得防护 IP,服务器随后被切换过去
过滤能力 17 Tbps 全球清洗,加上法兰克福 3.2 Tbps 的 Arbor 实时过滤 同样的两级过滤
IP 地址 您服务器本身的 IP 地址 额外的专用防护 IP
规则集 自动防护策略,细调通过工单 在客户中心里按端口和协议设置自己的规则
变更 自动跟进 实时生效,攻击进行时也可以
游戏策略 针对常见游戏的优化策略,包括 Team Fortress 2 策略可按端口选择,也适用于经过修改的服务器
黑洞路由 否 否
合约期 与服务器套餐绑定 PrePaid 预付费,没有最低合约期,没有退订通知期,也没有开通费

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

常见错误及解决办法

“服务器在跑,但服务器浏览器里已经没有它了”:请先检查 Game Server Login Token。TF2 服务器要公开列出就需要一个令牌,通过 sv_setsteamaccount 设置,并且要为 App ID 440 生成。Steam 会收回连续 30 天没有使用过的令牌。因此,一台在较长停机之后消失的服务器,往往只是需要一个新令牌,而根本没有被攻击。只有排除了这一点之后,才轮到 sv_max_queries_sec_global 设得太低,或者 27015/UDP 上有一条太粗放的防火墙规则。

“CPU 到了 100%,线路却几乎是空的”:这是查询洪水攻击或分片包洪水攻击的典型画面。请在服务器日志里找带 NET_GetLong 的行,并用第 9 节里那两条 tcpdump 命令测出到达的是哪一种数据包。

“我的 nftables 或 iptables 规则不起作用”:常见原因有三个。规则排在 UFW 的链后面,永远轮不到它(所以才有优先级 -10);规则在上次重启后就没了;或者攻击是流量型的,而规则在一条已经满了的线路上正常工作。用 nft list ruleset 检查计数器是否在增长。如果一直是零,说明规则没有被匹配到。

“我换了 IP 地址,第二天又离线了”:攻击者找到新地址的来源和找到旧地址的来源是同一个。您的服务器一旦重新出现在服务器浏览器里就会自己把它公布出去,而旧的 DNS 记录以及 Discord 状态机器人会把剩下的补齐。换地址只能争取几个小时,不是解决办法。

“服务器会可重现地崩溃,而带宽看不出异常”:这多半不是 DDoS 攻击,而是某个与引擎版本不匹配的插件,或者一个过时的服务器程序。sm plugins list 加上一次版本对照,比任何过滤规则都来得快。

“服务器在空闲之后反应变慢”:那是休眠,不是故障。在没人连接时它把 CPU 负载压到接近零,而这正是您希望手里有余量的那个状态。

“服务器上在执行陌生的管理命令”:这不是 DDoS 攻击,而是 RCON 访问被入侵了。请立刻重设密码,把端口限制到自己的地址上,并且记住密码是以明文经过线路传输的。

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

要点总结

  • 一台 TF2 服务器对外正好需要 27015/UDP。27015/TCP 上的 RCON 应该限制到自己的地址上,27020/UDP 上的 SourceTV 在您不转播时用 -nohltv 关掉。
  • 游戏流量和 A2S 查询共用同一个端口。一刀切地封掉或限速 27015/UDP 的人,会把自己的玩家踢出去。界线必须划在数据包类型之间,可以通过 UDP 头部之后的前四个字节识别。
  • 以 FE FF FF FF 为头部的分片包洪水攻击产生的是 CPU 负载而不是带宽,在日志里表现为 NET_GetLong。在 TF2 上,对这种数据包类型设一个很严的限制是站得住脚的。
  • 自“Meet Your Match”起,新玩家只能通过服务器浏览器找到社区服务器。任何把您挤出这份列表的措施,效果都和攻击本身一样。
  • 一台满员的 24 位服务器每秒处理约 1600 个入站数据包。针对社区游戏服务器的攻击通常在 5 到 50 Gbit/s,并伴随每秒几百万个数据包。
  • 1 Gbit/s 在最小数据包的情况下每秒能承载约 149 万个数据包。超过这个界限,决定一切的就只有服务器前面的网络,而不是服务器上的任何规则。
  • 在 KernelHost,两级持续防护不额外收费地包含在每个服务器套餐中,自服务器开通起即生效,并且不使用黑洞路由。如果您想自己掌控按端口设置的规则,可以每月 50.00 欧元起再加上 Advanced DDoS Protection。

如果您的服务器已经放在 KernelHost,过滤就已经在工作,您什么都不用做。若仍然发现异常,请开一个 支持工单,以便为您的 IP 地址调整过滤规则。攻击正在进行时,您还可以通过 WhatsApp 紧急聊天联系我们:+43 650 8209883。请一并说明四项信息:IP 地址、端口、按您所在时区的时间段,以及您看到的现象。这能省掉一轮追问,而在比赛进行时,那一轮是要紧的。

常见问题

我的 TF2 服务器刚刚离线了。怎么判断是不是 DDoS 攻击?
请看接口的数据包速率,而不是 CPU 负载。用 ip -s link show eth0 间隔十秒执行两次,得到的就是一个速率而不是一个绝对值,用 nstat -az 可以看到 UDP 计数器。如果入站数据包远远高出正常值,而几乎没有人连接,那就是有攻击在跑。如果网络计数器看不出异常,服务器却依然崩溃,那原因多半是某个插件或一个过时的服务器程序,而不是攻击。
一台 Team Fortress 2 服务器需要开放哪些端口?
正好一个:27015/UDP。游戏流量和 A2S 服务器查询共用这个端口,TF2 上没有单独的查询端口。27015/TCP 是 RCON,应该限制到您自己的地址上。27020/UDP 是 SourceTV,如果您不转播,用启动参数 -nohltv 就干脆不会占用它。27005/UDP 是玩家的客户端端口,服务器上不需要放行,26900 起的 Steam 端口只用于出站。
可以直接封掉 27015 端口或者对它限速吗?
不行。因为游戏流量和 A2S 查询共用同一个端口,一条粗放的规则会同时打到两者:您自己的玩家被踢出去,服务器也从服务器浏览器里消失。界线必须划在数据包类型之间。Source 引擎所有的无连接数据包都以四个置位的字节开头(0xffffffff),已经连上的玩家的流量没有这个头部。正是在这上面可以用 nftables 按发送方地址加一道速率限制,而完全不碰游戏流量。
服务器日志里带 NET_GetLong 的行是什么意思?
那是分片包洪水攻击的迹象,一个 Source 引擎特有的现象。分片数据包以 FE FF FF FF 这四个字节开头,宣告接下来有一条更大的消息会分成几部分发来。攻击者用伪造的发送方地址大量发出宣告过、却永远不完整的部分,服务器就一直等着并缓存。这产生的是 CPU 负载而不是带宽:线路几乎是空的,游戏却照样卡顿。在 TF2 上,对这种数据包类型设一个很严的速率限制是站得住脚的。
我的服务器在跑,但服务器浏览器里已经没有它了。我被攻击了吗?
不一定。请先检查 Game Server Login Token,每台公开列出的 TF2 服务器都需要它,它通过 sv_setsteamaccount 设置,并且要为 App ID 440 生成。Steam 会收回连续 30 天没有使用过的令牌。只有排除了这一点之后,才轮到 sv_max_queries_sec_global 设得太低、27015/UDP 上有一条太粗放的防火墙规则,或者真的出现了查询洪水攻击。自 Meet Your Match 更新起,服务器浏览器是新玩家找到社区服务器的唯一途径。
现在赶紧换 IP 地址有用吗?
只在短时间内有用。您的服务器一旦重新登记进服务器浏览器,就会自己把新地址公布出去,因为那正是玩家能找到它的前提。再加上旧的 DNS 记录、Discord 状态机器人和把条目抄下来的列表站点。换地址能争取几个小时到几天,但没有解决问题。长期被打的人需要的是服务器前面网络里的过滤。
攻击到多大规模,我的 TF2 服务器就撑不住了?
一台满员的 24 位服务器每秒处理约 1600 个入站数据包,带宽明显低于 2 Mbit/s。一台典型的游戏服务器挂在 1 Gbit/s 上,相当于每秒 125 兆字节。针对社区游戏服务器的攻击通常在 5 到 50 Gbit/s 之间。同样重要的是数据包速率:在最小数据包的情况下,1 Gbit/s 里能装进每秒约 149 万个数据包,而普通的服务器内核只能处理其中的几十万个。所以一次攻击可以让您瘫痪,哪怕带宽还远没有被用满。
在 KernelHost,我的服务器会在攻击期间离线吗?
不会。我们不使用黑洞路由。您的 IP 地址留在网络里,被丢弃的只有恶意数据包。防护分两级:全球清洗网络中 17 Tbps 的清洗能力,以及法兰克福 3.2 Tbps 的 Arbor 实时过滤。它持续运行,不需要先对攻击做出反应。对一台 TF2 服务器来说这一点是决定性的,因为不存在一个切换时间,让玩家在其中被踢出去、让服务器从服务器浏览器里掉出去。
KernelHost 的 DDoS 防护要额外付费吗?什么时候需要 Advanced DDoS Protection?
两级持续防护不额外收费地包含在每个服务器套餐中,自服务器开通起即生效,您既不用订购也不用开启。当您的服务器被有针对性地连打几周,并且您想自己掌控过滤时,就需要 Advanced DDoS Protection。您会获得一个专用防护 IP,并在客户中心里按端口和协议管理防护规则,也就是把 27015/UDP 和 27020/UDP 分开设置。改动实时生效。价格每月 50.00 欧元起,PrePaid 预付费,没有最低合约期,也没有开通费。

Team Fortress 2 TF2 DDoS 防护 社区服务器 SourceTV SourceMod 27015 端口 游戏服务器防护 Advanced DDoS Protection