保护 Terraria 服务器免受 DDoS 攻击

发布于 阅读时间 29 分钟

为什么 Terraria 只说 TCP,服务器真正需要哪些端口,如何加固 serverconfig.txt、TShock 和 7878 上的 REST API,以及攻击到多大规模就只能靠服务器前面的网络过滤。

想为 Terraria 服务器做好 DDoS 防护,要面对的是一个特例:Terraria 只说 TCP。游戏流量走的正好是一个端口,7777 TCP,而 UDP 端口这个游戏根本不打开。网上流传的游戏服务器防护建议几乎全是为 UDP 游戏写的,放在这里要么落空,要么用错了地方。

本文先讲您不花额外费用就能自己加固的部分,然后讲这些措施在技术上到哪里为止,最后讲服务器前面的网络里必须发生什么。所有内容针对运行在 Debian 12、Debian 13、Ubuntu 22.04 LTS 或 Ubuntu 24.04 LTS 上的 Terraria 独立服务器(vanilla、TShock 或 tModLoader)。命令以 root 身份书写,普通用户请在前面加上 sudo。如果攻击正在进行:现在不要改动任何配置,也不要重启服务器,而是先保存测量数据(见“记录日志”一节),攻击结束后,这些数据就没有了。

为什么偏偏是 Terraria 服务器会遭到 DDoS 攻击

Terraria 服务器是称手的目标,因为它的地址必然是公开的。Vanilla 版 Terraria 没有内置服务器浏览器:玩家通过“Multiplayer”和“Join via IP”连接,也就是通过一个必须先由某人公布出来的地址。想要新玩家的运营者,会把服务器登记到 terraria-servers.com、tserverweb.com 或 topg.org 这类列表站点上,或者通过 Discord 散发地址。这些途径给攻击者的东西,和给玩家的完全一样:明文的 IP 地址和端口。

因此,如果一台 Terraria 服务器不断掉线,而硬件、世界和 Mod 列表都没有变动,那么攻击就是最可能的解释。再加上一个项目的典型局面:固定的游戏时间、互相竞争的服务器、被封禁的玩家,以及社区内部的矛盾。发起一次攻击,既不需要委托人有什么本事,也花不了多少钱,一个 Terraria 服务器 booter 会以每月几欧元的订阅形式出售。DDoS 攻击在技术上是什么、又是怎么组织起来的,请看文章 什么是 DDoS 攻击?。

Terraria 走 TCP,不走 UDP

这是它与几乎所有其他游戏服务器最重要的区别。Terraria 独立服务器用一个 TCP 监听器接受连接(在游戏引擎里是 Terraria.Net.Sockets.TcpSocket 这个类),并且不打开 UDP 套接字。由此产生四个决定您整套防御的后果:

  • 一条完整建立起来的 TCP 连接无法伪造。攻击者必须收到服务器的 SYN-ACK 才能完成握手。因此真正连上来的人,来自一个真实的地址。IP 封禁和连接数上限在 Terraria 上的效果,因此明显好于在 UDP 游戏上。
  • SYN 洪水攻击却完全可以伪造,因为它从不完成握手。对付这一类,IP 封禁没有用,只有 SYN Cookie 和服务器前面的过滤才行。
  • 每一条被接受的、通往 7777 端口的 TCP 连接都会占用游戏进程里的资源,而不只是内核里的。这让槽位耗尽成为用最少带宽就能奏效的攻击。
  • UDP 洪水攻击照样会打到您的服务器。这些数据包不需要被接受,就能填满您的线路。Terraria 不说 UDP 这件事保护不了线路,它只是让游戏进程本身不去处理这些数据包。

有一个例外:如果用 -steam 加 -lobby friends 或 -lobby private 启动独立服务器,连接就会走 Steam 网络,也就是走 27000 到 27100 范围内的 UDP 端口。那是另一种运行模式,不是通过 IP 地址访问的经典服务器。

真正相关的那些端口

一台 Terraria 服务器在公网上正好需要一个端口:7777 TCP。这张表里的其他东西,要么根本不该上互联网,要么只该对您自己的地址开放。

用途 端口 协议 在哪里设置 是否对公网开放
Terraria 游戏流量 7777 TCP serverconfig.txt 中的 port=7777 是,而且是唯一一个
Terraria 走 UDP 没有 没有 游戏不打开 UDP 套接字 否
查询端口、状态端口 没有 没有 Vanilla 版 Terraria 没有自己的查询协议 否
RCON 没有 没有 Terraria 没有 RCON,远程控制只能通过 TShock 否
TShock REST API 7878 TCP tshock/config.json 中的 RestApiPort 否
tModLoader 服务器 7777 TCP 同一个 serverconfig.txt 是,而且是唯一一个
Steam 模式(-steam -lobby) 27000 到 27100 UDP 仅在 Steam 运行模式下 否
Pterodactyl Wings 8080 TCP 面板守护进程 否,仅限自己的地址
Pterodactyl SFTP 2022 TCP 面板的 SFTP 否,仅限自己的地址
SSH 22 TCP /etc/ssh/sshd_config 仅限自己的地址

Terraria 既没有查询端口也没有 RCON,这对加固来说是好消息:在 Counter-Strike、Rust 或 ARK 上经常被用于反射攻击的那两个端点,在这里干脆就不存在。代价是攻击面更加集中在 7777 端口上,而使用 TShock 的人会连带把 7878 端口变成第二块攻击面。

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

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

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

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

ss -lntup

要看的是本地地址那一列。0.0.0.0:7777 表示“整个互联网都能访问”,127.0.0.1:7878 表示“仅本机”,不需要防火墙规则。如果这份列表里出现了属于您 Terraria 进程的 UDP 条目,说明服务器跑在 Steam 模式下。从外面做一次端口扫描,就能看到攻击者眼中的样子:

nmap -Pn -p- --min-rate 1000 YOUR.SERVER.IP.ADDRESS

2. 只留 7777 TCP 开着,其余全部关闭

Terraria 对外只需要一条放行规则。您不需要 UDP 规则,而给 7777 加一条 UDP 规则干脆就是错的:它放行的是一个根本没有东西在监听的端口上的流量。用 UFW 的写法如下,而且顺序必须完全照此执行,以免把自己关在门外:

ufw allow 22/tcp comment 'SSH'
ufw allow 7777/tcp comment 'Terraria'
ufw allow from 203.0.113.10 to any port 7878 proto tcp comment 'TShock REST'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

请把 203.0.113.10 换成您自己的地址。包含自救办法的完整说明见 设置 UFW 防火墙而不把自己关在门外。运行面板的人,也要把 8080 和 2022 限制到自己的地址上。

3. serverconfig.txt:正确设置密码、maxplayers 和 secure

Terraria 服务器的核心配置文件叫 serverconfig.txt,启动时用 -config serverconfig.txt 传入。有四条指令对加固起决定作用:

port=7777
maxplayers=16
password=ALongRandomPassword
secure=1
upnp=0
banlist=banlist.txt

password= 是对付走正规途径的连接洪水攻击最有效的免费措施。原因在协议里:客户端先发出带有版本标识的消息 1(例如 Terraria279),设置了密码时服务器用消息 37 回应,客户端必须用消息 38 正确作答,只有在这之后服务器才会用消息 3 发出许可以及玩家槽位。因此没有正确密码的攻击者,永远走不到世界数据传输那一步,而那才是一次加入过程中昂贵的部分。

maxplayers 接受 1 到 255 的值,默认是 16(在 1.4.0.1 版之前是 8)。255 这个上限不是随便定的数字:Terraria 用单个字节来寻址玩家。请不要把 maxplayers 设得比实际需要更高,因为每一个槽位都是攻击者可以占用的资源。secure=1 打开内置的作弊检查(命令行上是 -secure),upnp=0 阻止服务器自作主张在路由器上打开端口。

4. 加固 TShock:7878 上的 REST API 和登录洪水攻击

TShock 是 Terraria 上最常用的服务器扩展,它带来的 REST API 是第二块完整的攻击面。它默认位于 7878 TCP 端口,配置写在 tshock/config.json 里,而不是 serverconfig.txt 里。出厂状态下它是关闭的("RestApiEnabled": false),而且只要您用不到它,就该一直保持这样。

如果您确实需要它,这几个值就很关键:

"RestApiEnabled": true,
"RestApiPort": 7878,
"EnableTokenEndpointAuthentication": true,
"LogRest": true,
"RESTMaximumRequestsPerInterval": 5,
"RESTRequestBucketDecreaseIntervalMinutes": 1

这里有两点很重要。第一,只要 EnableTokenEndpointAuthentication 还是 false,/status 这个端点就会在没有令牌的情况下给出服务器名称、端口、玩家数和玩家名单。这对状态页面和 Discord 机器人很方便,同时也是给每一个想知道什么时候值得下手的攻击者做的免费侦察。第二,/v2/token/create 这个端点会用用户名和密码生成一个访问令牌,而只要 7878 端口开着,它就能从外面访问到:这是一次针对您管理员账号的密码猜测攻击,还顺带消耗计算时间。由 RESTMaximumRequestsPerInterval 和 RESTRequestBucketDecreaseIntervalMinutes 组成的计数桶能把这个速度压下来,但替代不了一条防火墙规则。

游戏侧的访问还受另外几个 TShock 值管控。MaximumLoginAttempts 的值是 3,三次失败之后就把玩家踢出去。RequireLogin(默认 false)要求每个玩家都有账号。EnableIPBans(默认 true)和 KickProxyUsers(默认 true)在一个 TCP 游戏上格外有效,因为一条已经建立起来的连接,其源地址恰恰无法伪造。对付常被报成攻击的破坏行为(griefing),起作用的是几个阈值:TileKillThreshold(60)、TilePlaceThreshold(20)、TileLiquidThreshold(15)和 ProjectileThreshold(50),单位都是每秒动作数。

因为 Terraria 跑在 TCP 上,所以最有效的本地规则是给每个源地址的并发连接数设一个上限。一个真实玩家正好需要一条:

iptables -I INPUT -p tcp --dport 7777 --syn -m connlimit --connlimit-above 3 --connlimit-mask 32 -j DROP
iptables -I INPUT -p tcp --dport 7777 --syn -m hashlimit --hashlimit-name terraria_syn --hashlimit-mode srcip --hashlimit-above 10/min --hashlimit-burst 20 -j DROP

第一条规则在一个地址同时开着超过三条连接时丢弃新连接。第二条把同一来源的连接尝试速率限制到每分钟十次,外加 20 的余量。这两个数字都是起始值,不是真理:处在共用接入线路后面的情况(合租住处、学校网络、移动网络运营商)会让多个合法玩家出现在同一个地址下。请先在正常运行状态下测一周。

纯 iptables 规则在重启后就没了,在 Debian 和 Ubuntu 下这样保存:

apt-get install -y iptables-persistent
netfilter-persistent save

在 UFW 下,这类规则应写进 /etc/ufw/before.rules,否则下一次 ufw reload 时就会消失。对付从不完成握手的伪造 SYN 数据包,上面这些规则都帮不上,能帮上的是内核本身。请检查这三个值:

sysctl net.ipv4.tcp_syncookies net.ipv4.tcp_max_syn_backlog net.core.somaxconn

net.ipv4.tcp_syncookies 必须是 1,在 Debian 和 Ubuntu 上通常已经如此。SYN Cookie 不再维护半开连接的队列,而是从客户端的回应中重建状态,只要线路没被打满,SYN 洪水攻击就会落空。net.core.somaxconn 从 Linux 5.4 起是 4096,之前是 128:这个值偏小时,内核会在游戏进程还来不及接受之前,就把已经建立好的连接丢弃。

6. 防止槽位耗尽:为什么一次端口扫描会把您的服务器塞满

槽位耗尽是针对 Terraria 服务器最便宜又有效的攻击:攻击者向 7777 端口开出与服务器玩家槽位数一样多的 TCP 连接,并把它们一直挂着。这几乎不花他什么带宽,却把服务器占满了。真实玩家看到“Server is full”就进不来,而您的线路上什么异常都没发生。正是因为这样,Terraria 的运营者常常察觉不到自己正在被攻击。

原因在于计数方式:一条连接在客户端还没发出版本标识之前就已经被接受了。历史上,这类幽灵连接会一直占着位置,直到 TCP 会话超时。1.4.5 系列缓解了这一点,在那里,对立刻又断开的客户端不再预留槽位。不过在 1.4.5.7 和 1.4.5.8 的初版里,只要打开一条 TCP 连接而不完成握手,独立服务器就会因为一个未处理的 ObjectDisposedException 而崩溃。一次 nc -z,或者一次监控系统的可达性检查,就足以触发。这个错误在几周内被静默修复了,但在较旧的容器镜像里有时还在。因此请让您的服务器版本保持最新,这在这里不是套话,而是一个具体的可用性问题。

另有两项设置能帮上忙。使用 TShock 的人,把 MaxSlots 设成想要的玩家数,并把 serverconfig.txt 里的 maxplayers 设得高出两个位置:这样 TShock 会用一条干净的提示拒绝多余的连接,而不是让游戏进程把它们塞进最后一个空位。而上一节里的连接数上限,正是那条阻止单个地址一次性占光所有槽位的规则。

7. 关掉 UPnP,不要自己公布地址

Terraria 服务器默认会尝试通过 UPnP 在路由器上打开自己的端口。在一台租来的服务器上这不起作用,在家庭网络里它会打开一些您后来自己都不记得的端口。请用 serverconfig.txt 里的 upnp=0 或命令行上的 -noupnp 把它关掉。

这里还值得实话实说,而不是想当然:您的 IP 地址保不了密。每一个连过一次的玩家都知道它,而在列表站点上登记一条,本来就等于公布了它。真正有效的是两个习惯。永远不要自己在任何地方公布裸的 IP 地址,而是让玩家通过一个主机名连接:Terraria 客户端会解析主机名,所以万一出事,您可以更换地址而不让所有引用失效。另外请清理旧的 DNS 记录,因为一条指向前一个地址、被遗忘的 A 记录会让任何更换都失去意义。

8. 把状态查询缓存下来,而不是直接转发

因为 Terraria 没有查询协议,状态页面、Discord 机器人和列表站点只能用两种办法之一来了解您服务器的状态:它们要么向 7777 建立一条真实的 TCP 连接、把自己伪装成客户端,要么去查询 TShock 的 REST API。两种都要让您的服务器干活,而且两种都随着查询方的数量一起增长。

对策一分钱不花:绝不要从访客那一侧发起查询。让一个单独的服务按固定间隔去取状态(30 秒或 60 秒就够了),把结果缓存起来,然后把缓存的状态发给所有访客。这样一个访问量很大的状态页面每个间隔只产生一次查询,而不是每个访客一次。用 REST API 做这件事的人,要把 7878 端口限制到这一个服务的地址上。

9. 记录日志,让您在关键时刻手上有数据

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

sar -n DEV 1 10
ss -s
ss -tn state syn-recv | wc -l
ip -s link show eth0
tcpdump -ni eth0 tcp port 7777 -c 200 -q

第三条命令是 Terraria 专属的:它统计半开连接的数量。两位数是正常的,四位数或五位数就是 SYN 洪水攻击。ss -s 另外会显示 TCP 连接的总数,如果这个数字大致等于您的 maxplayers,而游戏里一个人都没有,那您看到的就是槽位耗尽。用 tcpdump 时有一条铁律:一定要用 -c 限制数量,满载状态下抓包会让本来已经过载的服务器更吃力。如何解读这些数值,见 识别 DDoS 攻击。

这些措施到哪里为止

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

算一下就清楚了。一台典型的游戏服务器挂在 1 Gbit/s 上,也就是每秒 125 兆字节,只要有人发得比这更多,线路就满了。针对这个规模的游戏服务器项目的攻击,通常在 5 到 50 Gbit/s 之间,也就是您线路的五到五十倍。到那时,您那条 connlimit 规则写得多好都不再重要,因为您玩家的数据包在更早的地方就已经过不来了。Terraria 服务器的延迟尖峰正是这样产生的,而此时 CPU 负载看起来还很正常。

第二个量是数据包速率,而它往往比带宽先出事。在 64 字节的小包情况下,1 Gbit/s 的线路里能装进每秒约 149 万个数据包。普通的服务器内核视 CPU 和网卡而定,处理其中几十万个之后就会开始丢弃。遇到 SYN 洪水攻击时,这个界限还要更低,因为每一个 SYN 数据包都会触发一次状态判定:每秒几万个 SYN 数据包,就足以让一台标准 Linux 的连接接受过程瘫痪,而此时线路远没有被打满。运营者的体验是“负载根本不高,可是什么都没了”。

第三点是在 Terraria 上最常被忽略的:攻击者不会照着您的协议来。他会往您的地址发 UDP 洪水攻击和反射攻击流量,尽管没有任何 UDP 端口在监听。您的服务器会正确地丢弃这些数据包,但它们已经占掉了您的线路,于是您的 Terraria 服务器离线了,而一个数据包都没有到达游戏进程。为了有个量级上的参照:在 KernelHost 的服务器上,曾经过滤掉的攻击包括一次超过 473.4 Gbit/s、每秒超过 4150 万个数据包的攻击,以及一次针对游戏服务器、超过 112.2 Gbit/s 的 UDP 洪水攻击。对此没有任何本地设置可用。流量型攻击必须在服务器前面的网络里就被终结。

KernelHost 用什么来应对

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

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

  • 第 1 级:全球清洗网络中 17 Tbps 的清洗能力。流量型攻击在靠近来源的地方就被清洗掉,不会到达数据中心。
  • 第 2 级:法兰克福的 Arbor 实时过滤,容量 3.2 Tbps。就在服务器前面,逐个数据包地识别并丢弃与协议相关的攻击特征。对 Terraria 来说具体就是:针对 7777 TCP 的 SYN 洪水攻击和连接洪水攻击在这里终结,而不是终结在您的网卡上。

有两点是关键。防护持续运行,不需要先对攻击做出反应,所以开头不会有服务器失联的那几分钟。而且不使用黑洞路由:您的 IP 地址留在网络里,被丢弃的只有恶意数据包。把 IP 地址从网络里撤下来的做法,对您而言和攻击者达到的结果一样。地点是法兰克福。哪些游戏和协议在覆盖范围内,见 实时游戏服务器 DDoS 防护。

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

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

  • 专用防护 IP,来自法兰克福的核心网络,您的服务器会在我们自己的网络内切换到它。您这边不需要做任何改造。
  • 按端口和协议自行管理的防护规则,就在客户中心里:您可以设置 7777 TCP 上允许什么,并把其余全部关掉,而不用为此写工单。
  • 改动实时生效,因此您可以在攻击进行时随时调整,例如把每个源地址允许的连接速率收得更紧。
  • 与应用匹配的防护策略。针对 Terraria 这样的 TCP 游戏,以及运行在任意 TCP 或 UDP 端口上的自研或经过修改的应用,都有对应的策略。

两级防护对比

对比项 标配的 DDoS 持续防护 Advanced DDoS Protection
价格 包含在每个服务器套餐中,不额外收费 每月 50.00 欧元起,PrePaid 预付费
过滤能力 17 Tbps 全球清洗,加上法兰克福 3.2 Tbps 的 Arbor 实时过滤 同样的两级过滤
IP 地址 您服务器本身的 IP 地址 额外的专用防护 IP
规则集 自动防护策略,无需配置 在客户中心里按端口和协议设置自己的规则
变更 自动跟进 实时生效,攻击进行时也可以
针对 Terraria 的策略 面向 TCP 游戏服务器的自动策略 针对 7777 TCP 的自有规则集,也适用于 tModLoader 和 TShock
黑洞路由 否 否
合约期 与服务器套餐绑定 PrePaid 预付费,没有最低合约期,没有退订通知期,也没有开通费

对大多数 Terraria 项目来说,标配的持续防护配上干净的服务器配置就够了。Advanced DDoS Protection 针对的是有人把这件事当成私人恩怨的情况。目前把服务器放在别处的人,无法把这套防护加装上去,只能通过迁移到 KernelHost 获得:过滤是网络的一部分,不是服务器上的一个附加件。

常见错误及解决办法

“服务器满了,可是里面一个人都没有”:这是槽位耗尽。请用 ss -tn dst :7777 | wc -l 查一下实际开着多少条连接,再和玩家名单对比(服务器控制台里的 playing)。两个数字对不上,说明外来连接占了槽位。对策是按源地址的连接数上限、一个服务器密码,以及一个最新的服务器版本。

“我放行了 7777 UDP,可是什么都没变”:没错,因为 7777 UDP 上没有东西在监听。Terraria 只用 TCP。这条 UDP 放行规则不会直接造成损害,但它是一个不必要的开口,而且是一份复制了别的游戏教程的确凿证据。

“我的 iptables 规则不起作用”:常见原因有三个。规则排在 UFW 的链后面,永远轮不到它;规则在上次重启后就没了(这时用 netfilter-persistent save,或者写进 /etc/ufw/before.rules);或者攻击是流量型的,而规则在一条已经满了的线路上正常工作。用 iptables -L INPUT -n -v 检查命中计数器是否在增长。如果一直是零,说明规则没有被匹配到。

“没有攻击,玩家却被踢出去”:如果把 connlimit 的上限收得太紧,处在共用接入线路后面的玩家就会中招。在 TCP 上这比在 UDP 游戏上更容易发生,因为一次中断后的重连会立刻产生一条新连接,而旧的那条还挂在 TIME_WAIT 里。请一步一步提高这个值,并观察命中计数器。

“服务器卡顿,线路却很安静”:这更常见的原因是某个 Mod 或某个插件,而不是攻击。在 tModLoader 下,每多一个 Mod 都要在同一个进程里消耗计算时间,而一个实体很多的世界会把一个核心完全占满,哪怕多一个数据包都没有到。如果 sar -n DEV 1 10 看不出异常,那就不是 DDoS 攻击。

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

“我在 tcpdump 里看不到任何异常”:如果流量已经在前面的网络里被过滤掉了,服务器上当然就什么都收不到。这在过滤正常工作时是常态。反过来说:线路一旦被打满,您甚至可能连用来测量的那条 SSH 会话都进不来。这时请使用客户中心里的 VNC 控制台,它独立于虚拟机自身的网络运行。

要点总结

  • 一台 Terraria 服务器正好需要一个开放端口:7777 TCP。游戏不打开 UDP 套接字,没有查询协议,也没有 RCON。
  • 7878 TCP 端口上的 TShock REST API 是第二块攻击面。请把 RestApiEnabled 保持在 false,或者把这个端口限制到您自己的地址上。
  • serverconfig.txt 里的服务器密码是最有效的免费措施,因为攻击者若不能正确回应消息 37,就永远走不到世界数据传输那一步。
  • 槽位耗尽是 Terraria 上最便宜的攻击:每一条被接受的、通往 7777 的 TCP 连接都会占掉一个位置,完全不需要什么带宽。对付它靠的是按源地址的连接数上限、一个密码,以及一个最新的服务器版本。
  • 因为 Terraria 用 TCP,一条已经建立起来的连接,其源地址无法伪造:IP 封禁在这里比在 UDP 游戏上更有效。对付伪造的 SYN 洪水攻击,只有 SYN Cookie 和服务器前面的过滤才行。
  • UDP 洪水攻击会让您的 Terraria 服务器瘫痪,尽管它根本不说 UDP,因为它在游戏进程看到任何东西之前就已经填满了线路。
  • 大约从您上行带宽的量级起,唯一起作用的就是服务器前面的网络。在 KernelHost,这套过滤分两级,持续生效,并且不额外收费地包含在每个服务器套餐中。

如果您的项目已经放在 KernelHost,过滤就已经在工作,您什么都不用做。若仍然发现异常,请开一个 支持工单,以便为您的 IP 地址调整过滤规则。攻击正在进行时,您还可以通过 WhatsApp 紧急聊天联系我们:+43 650 8209883。

常见问题

一台 Terraria 服务器需要哪个端口、哪种协议?
一台 Terraria 服务器正好需要一个端口:7777 TCP。这是默认值,写在 serverconfig.txt 的 port=7777 里。游戏不打开 UDP 端口,既没有自己的查询端口,也没有 RCON。使用 TShock 的人另外还有 7878 TCP 端口上的 REST API,它在出厂状态下是关闭的。为 7777 放行 UDP 是多余的,而且是一份复制了别的游戏教程的确凿证据。tModLoader 使用的端口与 vanilla 服务器相同。
Terraria 用 TCP 而不用 UDP,为什么这很重要?
因为它把有效的对策倒了过来。一条完整建立起来的 TCP 连接无法伪造,因为攻击者必须收到服务器的 SYN-ACK。因此 IP 封禁和按源地址的连接数上限在 Terraria 上的效果,明显好于在 UDP 游戏上。而 SYN 洪水攻击却完全可以伪造,因为它从不完成握手:对付它只有内核里的 SYN Cookie 和服务器前面网络里的过滤才行。
我的 Terraria 服务器报 Server is full,可是没人在玩。这是什么?
这是槽位耗尽,针对 Terraria 服务器最便宜又有效的攻击。攻击者向 7777 端口开出与服务器玩家槽位数一样多的 TCP 连接,并把它们一直挂着。这几乎不花什么带宽,却把所有位置都占满了。请用 ss -tn dst :7777 | wc -l 查开着的连接数,再和服务器控制台里的 playing 命令对比。对策是按源地址的连接数上限、一个服务器密码,以及一个最新的服务器版本。
服务器密码对攻击有用吗?
对付连接洪水攻击有用,对付流量型攻击没用。原因在协议里:客户端先发出带有版本标识的消息 1,设置了密码时服务器用消息 37 回应,客户端必须用消息 38 正确作答,只有在这之后才会跟着消息 3 发出许可以及玩家槽位。没有正确密码的攻击者永远走不到世界数据传输那一步,而那才是一次加入过程中昂贵的部分。设置方式是 serverconfig.txt 里的 password= 或命令行上的 -password。
怎样加固 7878 端口上的 TShock REST API?
最保险的办法是干脆不打开它:在 tshock/config.json 里,RestApiEnabled 在出厂状态下就是 false。如果您确实需要它,请把 EnableTokenEndpointAuthentication 设为 true,否则 /status 这个端点会在没有令牌的情况下给出服务器名称、端口、玩家数和玩家名单。请打开 LogRest,把 RESTMaximumRequestsPerInterval 保持在 5、间隔保持在一分钟,并在防火墙里把 7878 端口限制到您自己的地址上。
maxplayers 应该填多少玩家?
填您真正需要的数量,因为每一个槽位都是攻击者可以占用的资源。maxplayers 接受 1 到 255 的值,默认是 16,在 1.4.0.1 版之前是 8。255 这个上限来自于 Terraria 用单个字节来寻址玩家。使用 TShock 的人,把 MaxSlots 设成想要的玩家数,并把 serverconfig.txt 里的 maxplayers 设得高出两个位置,这样 TShock 会用一条干净的提示拒绝多余的连接。
用 iptables 或 UFW 能挡住 DDoS 攻击吗?
对付小型攻击和连接洪水攻击可以,对付流量型攻击不行。服务器上的防火墙规则处理的是已经跑过您线路的数据包。线路一旦被打满,您玩家的数据包在更早的地方就已经过不来了,跟您的规则集写得多好完全无关。在 Terraria 上,给 7777 TCP 加一条 connlimit 规则仍然值得,因为它能有效阻止槽位耗尽。流量型攻击必须在服务器前面的网络里就被终结。
攻击到多大规模,我的 Terraria 服务器就撑不住了?
一台典型的游戏服务器挂在 1 Gbit/s 上,相当于每秒 125 兆字节。针对这个规模项目的攻击通常在 5 到 50 Gbit/s 之间。同样重要的是数据包速率:在 64 字节包大小时,1 Gbit/s 里能装进每秒约 149 万个数据包,而普通的服务器内核只能处理其中的几十万个。遇到 SYN 洪水攻击时这个界限还要更低,因为每一个 SYN 数据包都会触发一次状态判定。所以一次攻击可以让您瘫痪,哪怕带宽还远没有被用满。
Terraria 根本不用 UDP,为什么 UDP 攻击还会打到我?
因为攻击者不会照着您的协议来。他会往您的 IP 地址发 UDP 洪水攻击和反射攻击流量,尽管那里没有任何 UDP 服务在监听。您的服务器会正确地丢弃这些数据包,但它们已经占掉了您的线路,于是您的 Terraria 服务器离线了,而一个数据包都没有到达游戏进程。所以 Terraria 不说 UDP 这件事只保护了应用,保护不了线路。对付它只有服务器前面网络里的过滤才行。
在 KernelHost,我的服务器会在攻击期间离线吗?
不会。我们不使用黑洞路由。您的 IP 地址留在网络里,被丢弃的只有恶意数据包。防护分两级:全球清洗网络中 17 Tbps 的清洗能力,以及法兰克福 3.2 Tbps 的 Arbor 实时过滤。它持续运行,不需要先对攻击做出反应,因此开头不会有服务器失联的那几分钟。对 Terraria 来说具体就是:针对 7777 TCP 的 SYN 洪水攻击和连接洪水攻击在那里终结,而不是终结在您的网卡上。
KernelHost 的 DDoS 防护要额外付费吗?
不额外收费。两级持续防护包含在每个服务器套餐中,自服务器开通起即生效。您既不用订购,也不用开启或配置。目前把 Terraria 服务器放在别处的人无法把这套防护加装上去,因为过滤是网络的一部分,不是服务器上的一个附加件。这种情况下的建议是迁移到 KernelHost。
什么时候还需要 Advanced DDoS Protection?
当您的项目不是偶尔被打,而是被有针对性地连打几周,并且您想自己掌控过滤时。您会获得一个专用防护 IP,并在客户中心里自行按端口和协议管理防护规则:您可以设置 7777 TCP 上允许什么,并把其余全部关掉。改动实时生效,因此您可以在攻击进行时随时调整。价格每月 50.00 欧元起,PrePaid 预付费,没有最低合约期,也没有开通费。

Terraria Terraria DDoS 防护 TShock tModLoader 游戏服务器防护 7777 端口 7878 端口 Advanced DDoS Protection