用例:我想通过移动设备上的 vpn 随时随地访问在家中托管的服务(并且我不想逐个地通过隧道访问它们)。
我已经根据这个要点设置了 wireguard:https://gist.github.com/insdavm/b1034635ab23b8839bf957aa406b5e39
只是我想在我的“固定客户端”(Gist 中的主机 A)上使用分割隧道。VPS 在 Ubuntu 22.04 LTS 上,“固定客户端”在 18.04 LTS 上,两者都使用 iptables。
wg 隧道内的主机可以通过隧道相互 ping 通。但是,我无法192.168.0.0/24
从“移动客户端” ping 子网中的任何主机。Ping
确实到达了目标主机,该主机也做出了响应,但“固定客户端”不会通过 wg 隧道发回响应:
$ sudo tcpdump -i wg0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
22:25:50.229878 IP 10.66.76.2 > 192.168.0.67: ICMP echo request, id 4271, seq 1, length 64
22:25:54.276140 IP 10.66.76.2 > 192.168.0.67: ICMP echo request, id 4272, seq 1, length 64
22:25:58.402260 IP 10.66.76.2 > 192.168.0.67: ICMP echo request, id 4273, seq 1, length 64
$ sudo tcpdump -i enp2s0 -n host 192.168.0.67
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp2s0, link-type EN10MB (Ethernet), capture size 262144 bytes
22:25:26.677816 IP 192.168.0.15 > 192.168.0.67: ICMP echo request, id 4268, seq 1, length 64
22:25:26.678704 IP 192.168.0.67 > 192.168.0.15: ICMP echo reply, id 4268, seq 1, length 64
22:25:30.721416 IP 192.168.0.15 > 192.168.0.67: ICMP echo request, id 4269, seq 1, length 64
22:25:30.722195 IP 192.168.0.67 > 192.168.0.15: ICMP echo reply, id 4269, seq 1, length 64
22:25:34.742213 IP 192.168.0.15 > 192.168.0.67: ICMP echo request, id 4270, seq 1, length 64
22:25:34.742946 IP 192.168.0.67 > 192.168.0.15: ICMP echo reply, id 4270, seq 1, length 64
为什么回复应该通过 NAT 发送,却没有通过隧道发送回来?
似乎固定客户端只使用一种方式的 NAT,而不是反向的?!
我希望来自的 ping 回复192.168.0.67
能够被转发到,10.66.76.2
因为那是应用 NAT 之前的原始来源。
相同的 PostUp iptables 规则在 VPS 上工作正常:通过 VPS 的公共 IP 隧道传输所有流量的客户端可以访问互联网。所以我不明白为什么我的“固定客户端”无法将流量通过 NAT 传输到本地网络。
我的 wg confs 如下:
VPS 服务器:
[Interface]
Address = 10.66.76.1/24,fd42:42:52::1/64
ListenPort = 12345
PrivateKey = ...
# Not needed for this scenario, but some clients tunnel all traffic
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens6 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens6 -j MASQUERADE
# Mobile client
[Peer]
PublicKey = ...
AllowedIPs = 10.66.76.2/32, fd42:42:52::2/128
# Fixed client in home network
[Peer]
PublicKey = ...
AllowedIPs = 10.66.76.4/32, fd42:42:52::4/128, 192.168.0.0/24
移动客户端:
[Interface]
PrivateKey = ...
Address = 10.66.76.2/24, fd42:42:52::2/64
MTU = 1420
[Peer]
PublicKey = ...
Endpoint = my-vps.net:12345
AllowedIPs = 10.66.76.0/24, fd42:42:52::1/128, 192.168.0.0/24
固定客户端:
[Interface]
PrivateKey = ...
Address = 10.66.76.4/24, fd42:42:52::4/64
MTU = 1420
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE
[Peer]
PublicKey = ...
Endpoint = my-vps.net:12345
AllowedIPs = 10.66.76.0/24, fd42:42:52::0/64
答案1
我终于解决了这个问题。
原来是我缺少用于转发到隧道的反向 iptables 规则:
iptables -A FORWARD -o wg0 -j ACCEPT
。
因此,“固定客户端”的正确配置如下:
[Interface]
PrivateKey = ...
Address = 10.66.76.4/24, fd42:42:52::4/64
MTU = 1420
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE
[Peer]
PublicKey = ...
Endpoint = my-vps.net:12345
AllowedIPs = 10.66.76.0/24, fd42:42:52::0/64, 172.20.0.0/24