背景与痛点
相信很多 Minecraft 服主都遇到过这样的经典困境:
- 高性能主机在内网:我有一台配置不错的内网机器(简称 机器 A),它是跑 Minecraft 服务端的最佳选择。但是,它位于大内网(CGNAT),没有公网 IPv4 地址。
- 公网服务器配置太低:同时,我手头还有一台腾讯云的轻量应用服务器(简称 机器 B),它有公网 IP,但它的配置只有 4核4G,无法流畅运行 MC 服务端。
目标非常明确:我想利用 机器 B 的公网 IP 作为入口,把流量转发给 机器 A 处理。
通常大家的第一反应是使用 FRP (Fast Reverse Proxy) 做内网穿透,不过我前面文章已经介绍过了。所以这次我打算介绍一种小众变态思路,采用 Tailscale 虚拟局域网 + rinetd 端口转发 的方案。
方案拓扑
我的思路是这样的:
- 铺路 (Tailscale):利用 Tailscale 将位于内网的机器 A 和位于公网的机器 B 连成一个虚拟局域网。
- 指路 (rinetd):在公网机器 B 上运行 rinetd,监听公网端口,把收到的流量“推”给机器 A 的 Tailscale 内网 IP。
第一步:铺设高速路 (Tailscale + 自建 DERP)
首先,需要在两台机器上安装 Tailscale。
curl -fsSL https://tailscale.com/install.sh | sh为了保证转发的低延迟和高稳定性,建议将公网服务器(机器 B)同时作为 DERP 中继节点。我们不使用官方的海外节点,而是使用 Docker 快速部署自建节点。
这里推荐使用 yangchuansheng 封装好的镜像。
1.1 部署 DERP 服务
创建存放目录:
mkdir -p /opt/derp && cd /opt/derp准备证书: 由于我们要使用 IP 证书,推荐使用 ZeroSSL 申请 90 天免费的 IP 证书。
将申请到的服务器证书和中间证书合并重命名为 ip.crt ,私钥重命名为 ip.key(例如 1.2.3.4.crt -> ip.crt),并放入 /opt/derp/certs 目录中。
编写 docker-compose.yml:
nano docker-compose.yml复制以下配置:
services:
derper:
image: ghcr.io/yangchuansheng/ip_derper:latest
container_name: derper
restart: always
ports:
- "8443:8443" # 将8443改为您想使用的端口
- "3478:3478/udp" # STUN端口,建议保持不变
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock # 映射本地 Tailscale 验证连接
- ./certs:/app/certs # 证书目录映射
environment:
- DERP_ADDR=:8443 # 与上面端口保持一致
- DERP_CERTS=/app/certs
- DERP_VERIFY_CLIENTS=true # 防止白嫖的关键参数
# 注意:将下面的 1.2.3.4 替换为你的公网 IP
command: >
/app/derper
-hostname 1.2.3.4
-a :8443
-http-port -1
-certmode manual
-certdir /app/certs
-verify-clients启动服务:
docker compose up -d注意:请务必在云服务器防火墙放行 TCP 8443 和 UDP 3478 端口。
1.2 配置 Tailscale ACL
进入 Tailscale 控制台 Access Controls,添加 derpMap 配置以启用我们的自建节点:
{
// ... 其他 ACL 配置保持不变 ...
"derpMap": {
"OmitDefaultRegions": false, // 设为 true 可仅使用自建节点(生产环境建议 false 以保留备用)
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "chn1",
"RegionName": "China1",
"Nodes": [
{
"Name": "cn-derp1",
"RegionID": 900,
"IPv4": "1.2.3.4", // 替换为您服务器的公网IP
"DERPPort": 8443, // 与 docker-compose 端口一致
"InsecureForTests": false // 使用自签或 IP 证书建议开启
}
]
}
}
}
}注意事项:
- RegionID在900-999之间是预留给自定义DERP节点的,避免与官方节点冲突
- RegionCode和RegionName可以自定义,建议使用有意义的名称
- IPv4必须是服务器的公网IP地址
- DERPPort必须与Docker配置中暴露的端口一致
- 如果使用了自签名证书一定要将InsecureForTests设置为true
保存配置后,稍等片刻即可生效。
1.3 验证连通性
方案一
在内网机器(机器 A)上执行:
tailscale netcheck如果输出中包含你的 DERP 节点 IP 且延迟正常,说明“高速路”铺设完毕。此时记下机器 A 的 Tailscale IP(通常以 100. 开头),我们下一步要用。
方案二
在内网机器(机器 A)上执行:
tailscale ping 机器 A 的 Tailscale IP如果在输出中看到类似via DERP(cn-derp1)的信息,说明流量正在通过我们自建的DERP节点中继,证明配置成功。
第二步:配置指路人 (rinetd)
这是本方案的核心。我们需要在 公网机器 B 上安装并配置 rinetd,将外部玩家的流量转发进 Tailscale 隧道。
2.1 安装 rinetd
对于 Ubuntu/Debian 系统:
sudo apt update
sudo apt install rinetd -y2.2 编辑配置文件
rinetd 的配置文件非常简单直白。
sudo nano /etc/rinetd.conf在文件末尾添加转发规则。格式为:[绑定地址] [绑定端口] [目标地址] [目标端口]。
假设:
- 机器 A(内网 MC 服务器)的 Tailscale IP 是
100.64.0.10 - Minecraft 监听端口是
25565
则添加如下内容:
# 允许所有来源访问本机的 25565 端口,并转发给内网机器
0.0.0.0 25565 100.64.0.10 255652.3 重启并验证
保存文件后,重启 rinetd 服务:
sudo systemctl restart rinetd检查 rinetd 是否正常监听:
sudo netstat -tunlp | grep rinetd
# 输出应包含:tcp 0 0 0.0.0.0:25565 ...别忘了在防火墙控制台放行 TCP 25565 端口。
最终效果
现在,在 Minecraft 多人游戏中输入 公网机器 B 的 IP:25565,流量就会经过以下路径丝滑到达你的内网主机:
方案总结
- 优点:配置极其简单,rinetd 几乎不占用资源;利用 Tailscale 的加密隧道,安全性有保障;双向流量可控。
- 缺点:rinetd 仅支持 TCP 协议(这对 MC Java 版足够了,但基岩版需要 UDP,可能需要 iptables 转发)。
希望这个方案能给各位带来新的灵感!
