使用 AWS 保护您的家庭 Minecraft 服务器免受 DDOS 攻击

想要在不暴露自己真实 IP 地址的情况下在家中搭建 Minecraft 服务器吗?这是完全可行的!只需利用亚马逊网络服务(Amazon Web Services)创建一个免费的代理服务器,就能有效地保护你的服务器免受拒绝服务(DDoS)攻击。接下来,我们将详细讲解具体的操作步骤。

本指南不仅适用于 Minecraft 服务器,也同样适用于其他任何类型的游戏服务器。其核心原理在于代理特定端口的流量。你需要做的只是将 Minecraft 的默认端口 25565 替换为你所使用的游戏服务器运行的端口号。

工作原理剖析

假设你希望搭建一个 Minecraft 服务器并将其对外开放。搭建服务器本身并不复杂。它们安装简便,通常只占用一个处理线程,即使是经过大量模组改造的服务器,在少数玩家在线的情况下,也仅需 2 到 3 GB 的内存。你完全可以在闲置的笔记本电脑或台式机后台运行服务器,无需额外花费托管费用。

然而,为了让其他玩家能够连接到你的服务器,你必须公开你的 IP 地址。这带来了一些潜在的安全风险。特别是在你的路由器仍然使用默认管理员密码的情况下,这将是一个严重的安全隐患。此外,这还会使你容易遭受分布式拒绝服务(DDoS)攻击,一旦遭受攻击,不仅你的 Minecraft 服务器会停止运行,甚至整个家庭网络也会瘫痪。

你不必直接让玩家连接到你的路由器。更明智的做法是从亚马逊网络服务、谷歌云平台或微软 Azure 租用一台小型 Linux 虚拟机。它们都提供了免费套餐。这台服务器不需要拥有运行 Minecraft 服务器所需的强大性能,它的主要作用是为你转发连接。这样一来,你就可以提供代理服务器的 IP 地址,而不是你自己的真实 IP。

当有玩家尝试连接你的服务器时,他们会将你的 AWS 代理服务器的 IP 地址输入到 Minecraft 客户端中。客户端会向代理服务器的 25565 端口(Minecraft 的默认端口)发送一个数据包。代理服务器被配置为将所有来自 25565 端口的流量转发到你的家庭路由器。这个过程在后台进行,连接的玩家甚至不会察觉。

之后,你的家庭路由器需要进行端口转发,将接收到的连接进一步转发到你运行服务器的电脑。你的电脑运行服务器并响应客户端的数据包,然后将响应数据包发回给代理服务器。代理服务器会重写这些数据包,使其看起来好像是代理服务器本身在响应客户端。整个过程对客户端而言是透明的,它只会认为代理服务器在运行服务器。

这就像在你的服务器前面增加了一台路由器,正如你的家庭路由器保护你的电脑一样。只是这台新的路由器运行在亚马逊网络服务上,并享有 AWS 服务免费提供的完整的传输层 DDoS 防护(称为 AWS Shield)。如果检测到攻击,它会自动缓解,不会影响你的服务器运行。如果出于某些原因,防护没有生效,你可以随时关闭实例,断开与你家的连接。

为了管理代理服务器,我们需要使用一个名为 sslh 的实用工具。它主要用于协议多路复用。例如,如果你想在同一个端口上运行 SSH(通常是 22 端口)和 HTTPS(443 端口),就会遇到冲突。sslh 可以解决这个问题,它会拦截端口流量并将其重定向到相应的应用程序。但它是工作在传输层级别的,就像路由器一样。这意味着我们可以拦截 Minecraft 的流量,并将其转发到你的家庭服务器。默认情况下,sslh 是不透明的,它会重写数据包以隐藏你的家庭 IP 地址。这样一来,任何人都无法使用像 Wireshark 这样的工具来嗅探到你的真实 IP 地址。

创建并连接到新的 VPS

首先,你需要设置你的代理服务器。如果你有一定的 Linux 使用经验,这会更加容易,但这不是必需的。

前往 亚马逊网络服务 并创建一个帐户。你需要提供你的借记卡或信用卡信息,但这只是为了防止有人注册多个帐户;创建的实例本身不会产生费用。免费套餐有效期为一年,请务必在用完后关闭实例。谷歌云平台 也提供免费的 f1-micro 实例,你可以选择使用。谷歌还提供一年的 300 美元信用额度,实际上,你可以用这笔额度运行一个功能更强大的云服务器。

AWS 会对带宽收费。你有 1GB 的免费空间,超出部分每 GB 收费 0.09 美元。通常情况下,你可能不会超出限制,但如果你的账单上出现了 20 美分的额外费用,请留意一下。

创建帐户后,搜索 “EC2″。这是 AWS 的虚拟服务器平台。你可能需要等待片刻,AWS 才能为你的新账户启用 EC2。

在 “Instances”(实例)选项卡中,选择 “Launch Instance”(启动实例)以打开启动向导。

你可以选择默认的 “Amazon Linux 2 AMI” 或 “Ubuntu Server 18.04 LTS” 作为操作系统。点击下一步,系统会要求你选择实例类型。选择 t2.micro,它是免费层实例。你可以在 AWS 的免费套餐下 24/7 运行此实例。

选择 “Review and Launch”(查看并启动)。在下一页上,选择 “Launch”(启动),你将看到下面的对话框。点击 “Create a new key pair”(创建新密钥对),然后点击 “Download Key Pair”(下载密钥对)。这是你访问该实例的密钥,请务必妥善保管,可以将其放在你的文档文件夹中。下载完成后,点击 “Launch Instances”(启动实例)。

你将返回到实例页面。找到你的实例的 IPv4 公共 IP 地址,这是服务器的地址。如果你愿意,你可以设置一个 AWS 弹性 IP(重启后不会改变),甚至可以注册一个免费域名 dot.tk,这样你就不必每次都返回此页面查找地址。

保存此地址以备后用。接下来,你需要编辑实例的防火墙以打开 25565 端口。在 “Security groups”(安全组)选项卡中,选择你的实例正在使用的安全组(可能是 launch-wizard-1),然后点击 “Edit”(编辑)。

添加新的自定义 TCP 规则,并将端口范围设置为 25565。”Source”(源)应设置为 “Anywhere”(任意位置)或 0.0.0.0/0。

保存更改,防火墙将更新。

现在我们需要通过 SSH 连接到服务器以设置代理。如果你使用的是 macOS/Linux 系统,可以直接打开终端。如果你使用的是 Windows 系统,则需要使用 SSH 客户端,例如 PuTTY,或者安装适用于 Linux 的 Windows 子系统。我们推荐后者,因为它更方便一致。

首先,你需要使用 cd 命令切换到密钥文件所在的文档文件夹:

cd ~/Documents/

如果你使用的是适用于 Linux 的 Windows 子系统,则你的 C 盘位于 /mnt/c/,你需要使用以下命令切换到你的文档文件夹:

cd /mnt/c/Users/username/Documents/

使用 -i 参数告诉 SSH 你要使用密钥文件进行连接。密钥文件通常带有 .pem 扩展名,因此你需要将扩展名也包含在内:

ssh -i keyfile.pem [email protected]

将 “0.0.0.0” 替换为你的服务器的 IP 地址。如果你创建的是 Ubuntu 服务器而不是 AWS Linux,则需要使用 “ubuntu” 用户名连接。

成功连接后,你应该看到命令提示符变为服务器的提示符。

配置 SSLH

你需要从软件包管理器安装 sslh。对于 AWS Linux,可以使用 yum,对于 Ubuntu,可以使用 apt-get。在 AWS Linux 上,你可能需要先添加 EPEL 存储库:

sudo yum install epel-release
sudo yum install sslh

安装完成后,使用 nano 打开配置文件:

nano /etc/default/sslh

将 RUN= 参数修改为 “yes”:

在最后的 DAEMON 行下方,输入以下内容:

DAEMON_OPTS="--user sslh --listen 0.0.0.0:25565 --anyprot your_ip_address:25565 --pidfile /var/run/sslh/sslh.pid

将 “your_ip_address” 替换为你的家庭 IP 地址。如果你不知道你的 IP 地址,请在谷歌上搜索 “我的 IP 地址是什么?” 即可。

此配置使 sslh 代理在 25565 端口上侦听所有网络设备的连接。如果你的 Minecraft 客户端使用不同的端口,或者你想玩其他游戏,你需要将其替换为不同的端口号。通常情况下,你可以使用 sslh 来匹配不同的协议,并将它们路由到不同的位置。但在此案例中,我们只需要匹配所有可能的流量,并将其转发到你的_ip_address:25565。

按下 Control+X,然后按下 Y 保存文件。输入以下命令以启用 sslh:

sudo systemctl enable sslh
sudo systemctl start sslh

如果 systemctl 在你的系统上不可用,你可能需要改用 service 命令。

现在 sslh 应该已经在运行了。请确保你的家庭路由器正在进行端口转发,并将 25565 端口的流量转发到你的电脑。你可能需要为你的电脑分配一个静态 IP 地址,以避免 IP 地址发生变化。

要查看其他人是否可以访问你的服务器,请将代理服务器的 IP 地址输入到 在线状态检查器 中。你也可以在 Minecraft 客户端中输入你代理服务器的 IP 地址,尝试加入服务器。如果无法连接,请检查你的实例的安全组是否已打开相应的端口。