文章摘要
加载中...|
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结

背景与痛点

相信很多 Minecraft 服主都遇到过这样的经典困境:

  • 高性能主机在内网:我有一台配置不错的内网机器(简称 机器 A),它是跑 Minecraft 服务端的最佳选择。但是,它位于大内网(CGNAT),没有公网 IPv4 地址。
  • 公网服务器配置太低:同时,我手头还有一台腾讯云的轻量应用服务器(简称 机器 B),它有公网 IP,但它的配置只有 4核4G,无法流畅运行 MC 服务端。

目标非常明确:我想利用 机器 B 的公网 IP 作为入口,把流量转发给 机器 A 处理。

通常大家的第一反应是使用 FRP (Fast Reverse Proxy) 做内网穿透,不过我前面文章已经介绍过了。所以这次我打算介绍一种小众变态思路,采用 Tailscale 虚拟局域网 + rinetd 端口转发 的方案。

方案拓扑

我的思路是这样的:

  1. 铺路 (Tailscale):利用 Tailscale 将位于内网的机器 A 和位于公网的机器 B 连成一个虚拟局域网。
  2. 指路 (rinetd):在公网机器 B 上运行 rinetd,监听公网端口,把收到的流量“推”给机器 A 的 Tailscale 内网 IP。

第一步:铺设高速路 (Tailscale + 自建 DERP)

首先,需要在两台机器上安装 Tailscale。

bash
curl -fsSL https://tailscale.com/install.sh | sh

为了保证转发的低延迟和高稳定性,建议将公网服务器(机器 B)同时作为 DERP 中继节点。我们不使用官方的海外节点,而是使用 Docker 快速部署自建节点。

这里推荐使用 yangchuansheng 封装好的镜像。

1.1 部署 DERP 服务

创建存放目录:

bash
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:

bash
nano docker-compose.yml

复制以下配置:

yaml
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

启动服务:

bash
docker compose up -d

注意:请务必在云服务器防火墙放行 TCP 8443UDP 3478 端口。

1.2 配置 Tailscale ACL

进入 Tailscale 控制台 Access Controls,添加 derpMap 配置以启用我们的自建节点:

json
{
  // ... 其他 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)上执行:

bash
tailscale netcheck

如果输出中包含你的 DERP 节点 IP 且延迟正常,说明“高速路”铺设完毕。此时记下机器 A 的 Tailscale IP(通常以 100. 开头),我们下一步要用。

方案二

在内网机器(机器 A)上执行:

bash
tailscale ping 机器 A Tailscale IP

如果在输出中看到类似via DERP(cn-derp1)的信息,说明流量正在通过我们自建的DERP节点中继,证明配置成功。


第二步:配置指路人 (rinetd)

这是本方案的核心。我们需要在 公网机器 B 上安装并配置 rinetd,将外部玩家的流量转发进 Tailscale 隧道。

2.1 安装 rinetd

对于 Ubuntu/Debian 系统:

bash
sudo apt update
sudo apt install rinetd -y

2.2 编辑配置文件

rinetd 的配置文件非常简单直白。

bash
sudo nano /etc/rinetd.conf

在文件末尾添加转发规则。格式为:[绑定地址] [绑定端口] [目标地址] [目标端口]

假设:

  • 机器 A(内网 MC 服务器)的 Tailscale IP 是 100.64.0.10
  • Minecraft 监听端口是 25565

则添加如下内容:

conf
# 允许所有来源访问本机的 25565 端口,并转发给内网机器
0.0.0.0 25565 100.64.0.10 25565

2.3 重启并验证

保存文件后,重启 rinetd 服务:

bash
sudo systemctl restart rinetd

检查 rinetd 是否正常监听:

bash
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 转发)。

希望这个方案能给各位带来新的灵感!

评论 隐私政策