Score:0

Wireguard/iptables: ICMP response not forwarded to wg0

mv flag

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 [email protected]
systemctl restart [email protected]

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.

Tom Yan avatar
in flag
You should post your wireguard confs on the three hosts. iptables is not responsible for where the traffics go.
xaa29221 avatar
mv flag
Thanks. I've added the details. My estimate is that the problem is with iptables, not wireguard, but maybe I'm wrong.
Tom Yan avatar
in flag
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 avatar
in flag
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.)
xaa29221 avatar
mv flag
Thanks for pointing out that `AllowedIPs` was incorrectly configured.
Tom Yan avatar
in flag
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)
xaa29221 avatar
mv flag
That was the problem. AllowedIPs was set incorrectly. Do you want to create an answer so I can select it? Thanks a lot!
Tom Yan avatar
in flag
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.
xaa29221 avatar
mv flag
@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).
Score:0
in flag

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.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.