I am trying to provide L3 connectivity between two remote LAN networks (10.0.0.0/24, 10.0.1.0/24) using OpenVPN with the following setup:
+----------------+ +---------------------+ +---------------------+
|VM A | |VM B (OpenVPN Server)| |VM C (OpenVPN Client)|
|eth0:10.0.0.5/24|--|eth0:10.0.0.4/24 | |eth0:10.0.1.4/24 |
+----------------+ |tun0:10.8.0.1/32 |==|tun0:10.8.0.2/32 |
+---------------------+ +---------------------+
Providing following IP table rule:
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 10.0.0.4
Pinging VMC->VMA(10.0.0.5) ICMP echo request's IP is SNATed correctly on VM B:
VM-B# tcpdump -i eth0 icmp
09:27:36.170555 IP 10.0.0.4 > 10.0.0.5: ICMP echo request, id 4049, seq 2, length 64
09:27:36.171201 IP 10.0.0.5 > 10.0.0.4: ICMP echo reply, id 4049, seq 2, length 64
But pinging VMA->VMC(10.0.1.4) echo reply's IP is NOT SNATed on VM B:
VM-B# tcpdump -i eth0 icmp
09:33:31.791095 IP 10.0.0.5 > 10.0.1.4: ICMP echo request, id 6590, seq 2, length 64
09:33:31.795299 IP 10.0.1.4 > 10.0.0.5: ICMP echo reply, id 6590, seq 2, length 64
which in my case results in dropping the packet by other underlying (VM's host machine) anti-spoofing iptables rules to prevent IP spoofing.
I don't understand why is the ICMP echo reply packet not being SNATed properly and how to make it happen. Thank you.
Best Answer
The ICMP echo-reply is the return half of a connection, and they're handled differently, for a reason.
Firstly, if you did manage to do what you want, you'd break PING: VMA would send an ICMP echo-request to
10.0.1.4
, but get an ICMP echo-reply (PONG) from10.0.0.4
. It would not associate that PONG with the PING previously sent, so you'd see 100% packet loss (plus gratuitous PONGs).The way to handle SNAT on returns is to do DNAT on outbounds, and let the NAT tidy-up logic handle with de-NATting the return half traffic. But you can't do that here, because if you DNAT everything coming into VMB's eth0 to
10.0.0.4
, you won't be able to talk to VMB any longer.So the right thing to do is to fix the underlying problem, and make your host's martian-detection logic fit with your actual IP addressing scheme.