0

Network diagram: Laptop (10.8.0.2) -> (wireguard) -> server A (10.8.0.1, 10.10.0.10) -> server B (10.10.0.20)

sequence diagram

I've connected my laptop (10.8.0.2) to a server A (10.8.0.1) via Wireguard. I can ping/curl to the server A (10.10.0.10), but not another server B (10.10.0.20).

When ping 10.10.0.20 server B from my laptop, I find the following on server A:

  • tcpdump -nn -i wg0 shows request, but no response:
  • tcpdump -nn -i enp7s0 shows request and response

So the problem seems to be that the response is not forwarded from enp7s0 to wg0.

But why not?

This is my iptables configuration:

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o enp7s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o enp7s0 -j MASQUERADE

Laptop wireguard:

[Interface]
PrivateKey = ...
Address = 10.8.0.2/24

[Peer]
PublicKey = ...
AllowedIPs = 10.8.0.0/24,10.10.0.0/24
Endpoint = ...

Server A wireguard:

[Interface]
PrivateKey = 
Address = 10.8.0.1/24
ListenPort = 51820
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o cilium_host -j MASQUERADE
PostUp = iptables -t nat -A POSTROUTING -o enp7s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o cilium_host -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o enp7s0 -j MASQUERADE

[Peer]
PublicKey = 
AllowedIPs = 10.8.0.2/32

Server B and server A are connected via a virtual private network.

Update: wireguard service reload

Restarting the service also seemed to help.

systemctl reload wg-quick@wg0.service
systemctl restart wg-quick@wg0.service

You can also try adding these rules, but I removed them and it still worked:

PostUp = iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -o wg0 -j ACCEPT

Update: Other related problems (FYI):

When I analyzed my routing table (ip route):

default via 172.31.1.1 dev eth0 
10.0.0.0/24 via 10.0.1.50 dev cilium_host proto kernel src 10.0.1.50 mtu 1400 
10.0.0.0/8 via 10.0.0.1 dev enp7s0 
10.0.0.1 dev enp7s0 scope link 
10.0.1.0/24 via 10.0.1.50 dev cilium_host proto kernel src 10.0.1.50 
10.0.1.50 dev cilium_host proto kernel scope link 
10.0.2.0/24 via 10.0.1.50 dev cilium_host proto kernel src 10.0.1.50 mtu 1400 
10.0.3.0/24 via 10.0.1.50 dev cilium_host proto kernel src 10.0.1.50 mtu 1400 
10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.1 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
172.31.1.1 dev eth0 scope link 

I realized that 10.0.0.0/8 via 10.0.0.1 dev enp7s0 was conflicting with the other routes, due to the 10.10.0.0/24 subnet belonging to a larger 10.0.0.0/8 range. So I moved my Kubernetes/Cilium network (to avoid 10.0.0.0/8 that could conflict with common networks at coffee shops etc.), and narrowed the VPC network as well.

xaa29221
  • 3
  • 2
  • You should post your wireguard confs on the three hosts. iptables is not responsible for where the traffics go. – Tom Yan Aug 28 '23 at 14:14
  • Thanks. I've added the details. My estimate is that the problem is with iptables, not wireguard, but maybe I'm wrong. – xaa29221 Aug 28 '23 at 14:36
  • Well, if your `FORWARD` table is actually filtering, you will also need to allow replying traffics to be forwarded back out of `wg0` (either statefully or by matching with `-o wg0`). Server B also needs to have correct route for `10.8.0.2/32` (or `10.8.0.0/24`) unless `cilium_host` or `enp7s0` is really the vpn tunnel interface. Also make sure IP forwarding is enabled sysctl-wise. – Tom Yan Aug 28 '23 at 15:07
  • Btw, although not really related to the issue here, it doesn't seem like you should have `AllowedIPs = 0.0.0.0/0` under the `[Peer]` section for `Laptop` (but `AllowedIPs = 10.8.0.2/32`). (Unless Laptop is supposed to be serving as an Internet gateway for other VPN clients.) – Tom Yan Aug 28 '23 at 15:09
  • Thanks for pointing out that `AllowedIPs` was incorrectly configured. – xaa29221 Aug 28 '23 at 16:03
  • Yes, but I suspect your `FORWARD` table isn't actually filtering anyway (i.e., no fallback DROP/REJECT rule and chain policy is ACCEPT), so probably you don't need any `-A FORWARD` anyway. (`iptables-save` will give us the full picture) – Tom Yan Aug 28 '23 at 16:07
  • That was the problem. AllowedIPs was set incorrectly. Do you want to create an answer so I can select it? Thanks a lot! – xaa29221 Aug 28 '23 at 16:13
  • For the record, the keys you once pasted are still in the edit history. If you really want to be safe, use a new key pair. – Tom Yan Aug 28 '23 at 17:43
  • @TomYan Thanks for your careful attention :). Btw, I found out that my VPC was using 10.10.0.0/24 subnet but in a 10.0.0.0/8 network, so my routing tables were conflicting with the Kubernetes/Cilium routing table (also 10.0.0.0/8). – xaa29221 Aug 28 '23 at 20:18

1 Answers1

0

After a second thought, the reason that it didn't work was probably AllowedIPs = 0.0.0.0/0 causes the VPN-encapsulated traffics from Server A to B to be routed into the wireguard tunnel.

And the solution is hence replacing it with AllowedIPs = 10.8.0.2/32.

Tom Yan
  • 747
  • 3
  • 9