🚀 运行: ...
IP: ...
ISP: 检测中...

给 NAT VPS 借一个能入站的公网 IPv6(WireGuard + NDP 代理)

起因

手里一台便宜的 IPv4 NAT 小鸡,只有共享 IPv4 + 端口映射,没有原生 IPv6,想让它也能被 IPv6 网络直接访问(入站)。

第一个念头是 HE TunnelBroker 的 6in4 隧道,但这条路在 NAT 机上走不通:6in4 走的是 IP 协议 41,不是 TCP/UDP 端口,端口映射型 NAT 的宿主机不会给你转发这个协议(除非商家愿意单独配合,基本别想)。

思路

向另一台有原生 IPv6 的 VPS 借一个地址:

  1. 目标机(NAT 小鸡)主动向中转机建立一条 WireGuard 隧道——WG 只需要 UDP 出站,NAT 天然支持
  2. 中转机从自己的 /64 里分出一个地址,经隧道”寄”给目标机使用
  3. 中转机开启 NDP 代理,在公网网卡上替这个借出的地址应答邻居发现——这是整个方案最关键的一步,普通 WG 组网教程里不会出现
  4. 外部访问该 IPv6:中转机先收下,再按路由转进隧道,目标机上的服务接客——真正的入站,不是 NAT66 那种端口转发

路径长这样:

外部(IPv6) → 借出的地址 2001:db8:1::505:51
  → 中转机公网网卡(NDP 代理"冒认"这个地址)
  → WireGuard 隧道(底层走 IPv4)
  → 目标机 wg0(绑着 2001:db8:1::505:51)
  → 目标机上监听 :: 的服务(hy2 / sing-box 等)

前提

  • 中转机:一台有原生 IPv6 /64 的 VPS,root 可用。本文示例地址 2001:db8:1::a/64,IPv4 为 203.0.113.10(均为占位示例,请替换成你自己的)
  • 目标机:一台 IPv4 NAT VPS,root 可用,systemd 正常
  • 借出的地址:2001:db8:1::505:51,从中转机的 /64 里任意挑一个没被占用的

第 0 步:确认目标机跑得了 WireGuard

容器型小鸡先测,有的 LXC 模板不给 tun、不给内核模块:

ls -l /dev/net/tun
ip link add wgtest type wireguard && ip link del wgtest && echo OK

打印 OK 才继续。报 Operation not permitted / Unknown device type 说明容器权限不够,先联系商家开 TUN,否则后面都是白干。

第 1 步:确认借的地址没人占(中转机执行)

ping6 -c2 2001:db8:1::505:51

无应答才能用;有人回就换个后缀再测。

第 2 步:两台都安装 WireGuard 并生成密钥

两台各执行一遍:

apt install -y wireguard
umask 077
wg genkey > /etc/wireguard/privatekey
wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey
cat /etc/wireguard/publickey    # 公钥要填到对端配置里
cat /etc/wireguard/privatekey  # 私钥只填自己这台的配置,绝不要外发

记牢一句话:私钥永远只出现在自己机器的配置里,交换的只有公钥。

第 3 步:中转机配置 /etc/wireguard/wg0.conf

[Interface]
PrivateKey = <中转机自己的私钥>
# 隧道内侧的测试地址,随意设定,仅用于验证隧道本身
Address = fd99::1/128
ListenPort = 51820
# 全篇关键一步:在公网网卡(按你实际网卡名改,如 eth0/ens3)上替借出的地址应答 NDP,
# 否则上游网关不知道这个地址“住在哪”,包根本送不进来
PostUp = ip -6 neigh replace proxy 2001:db8:1::505:51 dev ens3
PreDown = ip -6 neigh del proxy 2001:db8:1::505:51 dev ens3

[Peer]
PublicKey = <目标机的公钥>
# 只接受源地址是这两个的隧道包;同时它也定义“去这两个地址走隧道”的路由
AllowedIPs = 2001:db8:1::505:51/128, fd99::2/128

网卡名用 ip -br link 查你实际的,别照抄 ens3。

第 4 步:中转机开启转发并持久化

cat > /etc/sysctl.d/99-wg6.conf <<'EOF'
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.proxy_ndp=1
EOF
sysctl --system
sysctl net.ipv6.conf.all.forwarding net.ipv6.conf.all.proxy_ndp   # 两个都要是 1
  • forwarding=1:中转机当一回路由器,把公网网卡收到的包转进隧道
  • proxy_ndp=1:第 3 步那条”冒认地址”的代理条目靠它才生效

第 5 步:目标机配置 /etc/wireguard/wg0.conf

[Interface]
PrivateKey = <目标机自己的私钥>
# 这台机对外从此就是 2001:db8:1::505:51;fd99::2 是隧道内侧测试地址
Address = 2001:db8:1::505:51/128, fd99::2/128

[Peer]
PublicKey = <中转机的公钥>
# 隧道另一端:中转机的 IPv4 + 第 3 步定的监听端口
Endpoint = 203.0.113.10:51820
# IPv6 出站全走隧道(这台机本来就没有 v6;IPv4 原有流量完全不受影响)
AllowedIPs = ::/0
# NAT 机在运营商映射后面,每 25 秒一个保活包,映射才不会被回收
PersistentKeepalive = 25

第 6 步:启动(先中转机,后目标机)

systemctl enable --now wg-quick@wg0
wg show

报错就看 journalctl -u wg-quick@wg0 -n 20 --no-pager,最常见的原因是两边的公钥填反了。

三级验证(从里到外,哪级断了查哪级)

第 1 级 · 隧道握手

wg show

任意一端出现 latest handshake: 几秒前 就对了。一直为空,多半是公私钥串位,或者中转机的 UDP 51820 没放行(检查中转机 iptables -L INPUT -n 的策略)。

第 2 级 · 隧道内层

# 在目标机上
ping6 -c3 fd99::1

通了说明隧道数据通道没问题。握手有、ping 不通,检查两边 wg0 上的地址有没有抄错:ip -6 addr show wg0。

第 3 级 · 公网入站(定论)

从任意一个外部的 IPv6 网络(另一台带 v6 的主机、手机关 WiFi 用流量)执行:

ping6 2001:db8:1::505:51

能收到回复就全线贯通了。若第 1、2 级都正常唯独这级不通,问题几乎一定在 NDP 代理那一环:到中转机执行 ip -6 neigh show proxy,应能看到 2001:db8:1::505:51 dev ens3 这一行;没有就 systemctl restart wg-quick@wg0 让 PostUp 再跑一遍。

用起来

目标机上的服务只要监听 ::,就能用新地址访问,客户端地址填 [2001:db8:1::505:51]:端口。

如果想让 IPv6 入口也支持 Hysteria2 的端口跳跃(50552–50559 跳回 50551),在目标机补一条 v6 版的跳转规则并持久化:

ip6tables -t nat -A PREROUTING -p udp --dport 50552:50559 -j REDIRECT --to-ports 50551
apt install -y iptables-persistent && netfilter-persistent save

重启机器也不怕丢:wg-quick 已经 enable,sysctl 写在 /etc/sysctl.d/ 里,NDP 代理条目由 PostUp 每次启动时自动重建。

常见坑清单

  • 地址写成 ::50551:IPv6 每个段最多 4 个十六进制字符,五位直接被 wg 拒绝(日志是 Unable to parse IP address),挑地址时别把十进制端口号整段塞进去
  • 握手有、数据不通:AllowedIPs 抄错,或中转机的 forwarding 没生效,去第 4 步回看一下
  • 自己哪哪都通、唯独外部 ping 不进来:NDP 代理条目没生效,先查 ip -6 neigh show proxy
  • 抓包查入站 UDP 时什么都看不到:iptables REDIRECT 是在抓包点之后改的端口,抓包要按”重定向前”的端口段过滤(比如跳跃段要抓 portrange 50551-50559),别只盯主端口

小结

整套方案只多出一条 WireGuard 隧道和一条 NDP 代理:NAT 小鸡自此拥有一个真正公网可达的 IPv6 入站地址,代价是这台机的 IPv6 流量都要经过中转机绕一圈——线路好坏直接决定这个 v6 入口的速度上限,借之前先想清楚中转机选谁。