I am running a simple expirement for validating some NAT concepts with IPtables.
I have a Firewall with two interfaces connecting two networks:
Network A - 192.168.0.0/24 - connected to eth0 - Firewall's IP: 192.168.0.1
Network B - 192.168.1.0/24 - connected to eth1 - Firewall's IP: 192.168.1.1
I've applied the following DNAT rule to the FW:
iptables -t nat -A PREROUTING -d 192.168.1.1/32 -j DNAT --to-destination 192.168.0.2
Traffic gets redirected properly to the host 192.168.0.2, this is a sample captured from the .0.2 host:
16:17:40.005055 IP 192.168.1.2 > 192.168.0.2: ICMP echo request, id 15106, seq 1285, length 64 16:17:40.005133 IP 192.168.0.2 > 192.168.1.2: ICMP echo reply, id 15106, seq 1285, length 64
However I see something very interesting when I capture this same traffic from the FW HOST.
When I capture it from eth0 I see the traffic as expected, echo replys are coming with the IP: 192.168.0.2
But when I do the same thing for eth1, this is what I see:
16:21:44.348196 IP 192.168.1.2 > 192.168.1.1: ICMP echo request, id 15106, seq 1527, length 64 16:21:44.360376 IP 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 15106, seq 1527, length 64
If you pay attention to the echo reply, the source IP is 192.168.1.1. How that is possible if we just saw the original packages from 192.168.0.2 when we looked at eth0?
As one can see, there is no SNAT or Masquerade rule configured on the FW:
FIREWALL:~# iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT all -- anywhere 192.168.1.1 to:192.168.0.2 Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
There is only the original DNAT rule.
So why is the kernel masquerading my packages? I know that is is advisable to do SNAT in conjunction to DNAT, but that is no my point. I want to understand why that is happening if I did not tell the IPtables to do so. Is it possible that the kernel does that without consulting iptables/netfilter rules?