UDP→TCP 伪装,从 RouterOS 穿越公网至 VPS
mihomo 作为 WG 客户端,通过 Phantun 容器做 UDP→TCP 伪装穿越公网:
家里局域网 (192.168.88.0/24)
│
↓ mihomo 容器(内置 WG 客户端 + DNS/IP 分流)
RouterOS ──→ Phantun 容器 (veth-phantun, 192.168.88.x)
│
↓ UDP→TCP 伪装,穿越公网
VPS → Phantun 服务端 → WG 服务端 → 互联网
mihomo 内置 WG 客户端 + 规则分流引擎,不需要在 RouterOS 上配置原生 WG 接口和 IP 分流规则。
| 文件 | 说明 |
|---|---|
install_vps_server.sh |
第一步:VPS 服务端一键安装(WG + Phantun Server) |
install_proxy_client.sh |
备选:Debian 代理机安装 Phantun Client(不用容器时) |
在 VPS 上运行 install_vps_server.sh,自动完成 WireGuard + Phantun Server 的安装。
chmod +x install_vps_server.sh ./install_vps_server.sh
脚本交互提示:
| 提示 | 填写 | 说明 |
|---|---|---|
| WG 监听端口 | 回车默认 1234 |
|
| Phantun TCP 端口 | 回车默认 3656 |
|
| WG 隧道网段 | 回车默认 10.20.30.0/24 |
脚本完成后会输出以下关键信息(后续配置需要用到):
请保存好这些信息,第二步设环境变量和第三步配置 mihomo 时会用到。
如果您的网关设备支持容器(比如 RouterOS v7 并已开启 Container 功能),推荐使用方案 A;如果是通过旁路由或者其他 Linux 机器做代理,请选用方案 B。
按以下步骤将准备好的 phantun-client-arm64.tar 镜像文件上传到 RouterOS 并安装容器。
使用 WinBox 文件管理器或任意 SFTP 工具(如 FileZilla)连接 RouterOS:
phantun 文件夹和 phantun/root 子文件夹(容器文件系统解压位置)phantun-client-arm64.tar 等镜像文件上传到 /phantun/ 目录下phantun/root 必须提前创建好,否则容器启动会失败。如果命令行创建不成功,请在 WinBox 文件管理器或 SFTP 工具中手动创建。
前提:RouterOS 已安装 container 包并开启容器功能。
# ── 创建 veth 并接入 LAN 网桥 ──
# ★ bridge= 填你实际的 LAN 网桥名(/interface/bridge/print 可查看,通常是 bridge1)
# ★ address= 填一个局域网内未使用的 IP(本例用 192.168.88.200)
# ★ gateway= 填路由器 LAN 接口 IP(通常是 192.168.88.1)
/interface/veth/add name=veth-phantun address=192.168.88.200/24 gateway=192.168.88.1
/interface/bridge/port/add bridge=bridge1 interface=veth-phantun
# ── 设置环境变量(★ 填你的 VPS IP) ──
/container/envs/add list=phantun-env key=VPS_IP value=<你的VPS公网IP>
/container/envs/add list=phantun-env key=VPS_PORT value=3656
/container/envs/add list=phantun-env key=LOCAL_PORT value=1234
/container/envs/add list=phantun-env key=RUST_LOG value=info
# 验证参数
/container/envs/print where list=phantun-env
# ── 创建并启动容器 ──
# envlists ← 注意带 s,不是 envs
# logging ← 开启后可在 /log print 看到容器输出
/container/add \
file=phantun/phantun-client-arm64.tar \
root-dir=phantun/root \
interface=veth-phantun \
envlists=phantun-env \
logging=yes \
name="Phantun"
/container/print # 等 status=stopped(解压约 10~30 秒)
/container/start 0
/container/print # 确认 status=running
如果您不使用 RouterOS 的容器功能,而是有一台单独的 Linux (Debian/Ubuntu) 做代理机,可运行此文件夹下的 install_proxy_client.sh 一键安装。
chmod +x install_proxy_client.sh sudo ./install_proxy_client.sh
脚本运行时的交互提示:
脚本会自动下载安装最新版 Phantun 客户端,添加相应的 NAT 转发规则并挂载为开机自启的系统服务 (phantun-client.service)。
安装完成后,继续执行下方[第三步]时,其中的 server 字段配置就需要填写这台 Debian 代理机的内网 IP,且端口填写刚设置的本地监听端口(1234)。
在 mihomo 的 config.yaml 中添加 WG 代理节点,endpoint 指向 Phantun 容器:
proxies:
- name: "wg-vps"
type: wireguard
server: 192.168.88.200 # ★ Phantun 容器 IP
port: 1234 # ★ Phantun 监听端口(LOCAL_PORT)
ip: 10.20.30.2 # ★ VPS 分配的 WG 隧道 IP
private-key: "替换为WG客户端私钥" # ★ 第一步脚本输出的客户端私钥
public-key: "替换为VPS端WG公钥" # ★ 第一步脚本输出的服务端公钥
allowed-ips: ['0.0.0.0/0']
mtu: 1420
udp: true
将 wg-vps 加入代理组即可。mihomo 自带 DNS 防污染 + GeoIP/GeoSite 分流,国内直连、国外走 WG。
# 1. 在使用 mihomo 的客户端上测试出口 IP curl ip.sb # 应返回 VPS 的公网 IP # 2. 测试国内直连 curl myip.ipip.net # 应返回国内运营商 IP # 3. 检查 mihomo 代理日志或面板,确认 wg-vps 节点的延迟(测速)
初次部署时 install_vps_server.sh 会自动生成,如需更换密钥可手动生成:
# 生成一对密钥(私钥 → 公钥) wg genkey | tee privatekey | wg pubkey > publickey cat privatekey # 私钥 cat publickey # 公钥
更换后需同步修改:
/etc/wireguard/wg0.conf 中 PrivateKey(服务端私钥)和 [Peer] 的 PublicKey(客户端公钥),然后 wg-quick down wg0 && wg-quick up wg0config.yaml 中 private-key(客户端私钥)和 public-key(服务端公钥)# 查看 WG 状态(握手时间、流量统计) wg show # 查看 WG 配置详情 cat /etc/wireguard/wg0.conf # 修改 WG 配置后重启 vi /etc/wireguard/wg0.conf wg-quick down wg0 && wg-quick up wg0 # 关闭 WG(会同时停止 Phantun 服务端) wg-quick down wg0 # 开启 WG wg-quick up wg0 # 开机自启 systemctl enable wg-quick@wg0 # 取消开机自启 systemctl disable wg-quick@wg0 # 查看 Phantun 日志 tail -f /var/log/phantun.log # 查看 Phantun 进程 ps aux | grep phantun # 查看 iptables 规则(确认 MASQUERADE 和 DNAT) iptables -t nat -L -n -v # 查看 WG 接口 IP 信息 ip addr show wg0 # 抓包调试(看 Phantun 伪装 TCP 流量) tcpdump -i <公网网卡名> tcp port 3656 -n
# 查看容器状态 /container/print # 停止 / 启动 /container/stop 0 /container/start 0 # 查看容器日志(entrypoint 输出) /log/print where topics~"container" # 进入容器 shell(排查问题用) /container/shell 0 # ------- 容器内可用命令 ------- # 查看 iptables NAT 规则(确认 SNAT 生效) iptables -t nat -L -n -v # 查看网卡和 IP ip addr # 查看 Phantun 进程 ps -a | grep phantun_client # 查看 Phantun 日志 cat /var/log/phantun.log # 退出容器 shell exit # -------------------------------- # 修改 VPS 地址或端口(无需重建镜像) /container/envs/set [find list=phantun-env key=VPS_IP] value=<新VPS_IP> /container/stop 0 /container/start 0 # 更新镜像(上传新 tar 后执行) /container/stop 0 /container/remove 0 # 先去 Files 删掉旧目录和 tar 包,解压新 tar 后重新执行 /container/add ...
如果您使用的是物理机或虚拟机安装的代理客户端(install_proxy_client.sh),可以使用以下命令进行问题排查:
# 查看代理机上总共起了几个 Phantun 客户端服务,以及它们占用的端口号和远端连接 IP ps -ef | grep phantun_client | grep -v grep # 结合 ss 查看 Phantun 客户端实际监听的 UDP 端口情况 sudo ss -ulnp | grep phantun_client # 查看守护进程运行状态与日志 systemctl list-units --type=service | grep phantun-client systemctl status phantun-client journalctl -fu phantun-client
# 抓 WG UDP 包(RouterOS) /tool/sniffer/quick port=1234 interface=bridge1 # 【Linux 代理机】实时验证流量是否有来有回 (假设本地端口 1234,VPS TCP 端口 3656) # 1. 确认 WG 客户端有请求过来,且代理机有返回给客户端(UDP 流量) sudo tcpdump -i any udp port 1234 -nn # 正常现象:能看到 客户端IP -> 代理机IP,以及 代理机IP -> 客户端IP 的连续包 # 2. 确认伪装流量有发给 VPS,且 VPS 有返回(TCP 流量) sudo tcpdump -i any tcp port 3656 -nn # 正常现象:能看到 代理机IP -> VPS_IP,以及 VPS_IP -> 代理机IP 的包 # 3. 统计 TUN 虚拟网卡是否有真实数据上下行 (需注意 TX 发送方向) ip -s link show | grep -A 6 -E "tun" # 正常现象:RX (接收) 和 TX (发送) 的 packets/bytes 计数都在不断增加。如果 TX 始终为 0,说明数据有去无回,可能被 VPS 阻断或目标无法路由。 # 抓包保存到文件(Linux) tcpdump -i <接口> -w /tmp/capture.pcap # 测试出口 IP curl ip.sb
如果部署后发现连不通 VPS(即使 VPS 操作系统内没开防火墙),请按以下 5 点顺序进行排查:
1. 云厂商的安全组(最容易被忽略的“外部防火墙”)
通常说的“没有防火墙”是指 VPS 操作系统内(如 ufw, firewalld)关闭了,但几乎所有的云厂商(阿里云、腾讯云、AWS、Oracle等)在网页控制台都有外部安全组(Security Group)限制。
3656 端口(即 Phantun 通信端口)。2. Mihomo 配置的 Endpoint IP 和 端口填错了
server (IP):不能填 VPS 的公网 IP!必须填代理机 / Phantun 容器的内网 IP(例如 RouterOS 容器的 192.168.88.200 或本地 Debian 代理机的局域网 IP)。port (端口):不能填 3656!必须填本地代理机监听的 UDP 端口(默认是 1234)。3. MTU 封包超载(非常关键)
WireGuard 封装加上 Phantun 的 Fake-TCP 封装,头部体积会变得很大。如果家里的宽带是 PPPoE 拨号(MTU 一般是 1492),原本的 1420 加上各种包头后刚好超出物理网络极限,导致 TCP 数据包被分片。而 Fake-TCP 对碎片包处理差,会导致直接丢弃无法建立连接。
config.yaml 中,把 wg-vps 节点的 mtu: 1420 降低为 1360 甚至 1280 试试。4. 密钥成对关系填反了
private-key 是否确实是客户端的私钥,public-key 是否确实是服务端的公钥。也要注意末尾是否少复制了 = 或多带有空格,会导致密钥解码失败。5. 确认数据断点在哪里
不要靠猜,结合上文中的“网络调试”抓包技巧定位断线位置:
tcpdump -i any udp port 1234 -nn,确认局域网中的 mihomo 流量有没有到达代理机。tcpdump -i any tcp port 3656 -nn,确认代理机有没有将 UDP 包装成 TCP 发给 VPS 公网,以及有没有收到 VPS 返回的 TCP 包。如果没有收到回包,实锤是云端安全组阻断或 VPS 的服务端进程未启动。wg show,如果不显示 latest handshake(握手时间),说明 UDP 数据未能成功还原并被 WireGuard 服务端识别,通常是上述的第3点或第4点问题。# 停止并禁用 WG(会同时停掉 Phantun 服务端) wg-quick down wg0 systemctl disable wg-quick@wg0 # 删除配置和二进制 rm -f /etc/wireguard/wg0.conf rm -f /usr/local/bin/phantun_server rm -f /var/log/phantun.log # 删除 ip_forward 配置(如不再需要转发) rm -f /etc/sysctl.d/99-wg-forward.conf sysctl -w net.ipv4.ip_forward=0 # 卸载 WireGuard 包(可选,其他服务可能也在用) apt-get remove --purge -y wireguard wireguard-tools
# 停止并禁用 Phantun 客户端服务 systemctl disable --now phantun-client.service rm -f /etc/systemd/system/phantun-client.service systemctl daemon-reload # 删除二进制 rm -f /usr/local/bin/phantun_client # 删除 iptables MASQUERADE 规则 MAIN_NIC=$(ip route get 8.8.8.8 | grep -Po '(?<=dev )[^ ]+' | head -n 1) iptables -t nat -D POSTROUTING -o $MAIN_NIC -j MASQUERADE netfilter-persistent save # 还原 ip_forward(如不再需要转发) sed -i '/net.ipv4.ip_forward/d' /etc/sysctl.conf sysctl -w net.ipv4.ip_forward=0
# 停止并删除容器 /container/stop 0 /container/remove 0 # 删除环境变量 /container/envs/remove [find list=phantun-env] # 删除 veth 和网桥端口 /interface/bridge/port/remove [find interface=veth-phantun] /interface/veth/remove [find name=veth-phantun] # 删除镜像和文件系统(在 Files 中操作或命令行) /file/remove phantun