1

I am new to iptables and I want to understand how iptables nat is working. I have a linux machine with a lxc container. The machine network configuration is as follows: eth0 interface which connects the machine to the internet (it's IPv4 address is 10.9.63.173) and a veth-1 interface (192.168.2.1) for lxc container. On the lxc container there is a eth0 interface (192.168.2.2) connected to the veth-1.

On the linux machine I have added two iptables rules:

1) iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 10.9.63.173
2) iptables -t nat -A PREROUTING -d 10.9.63.173 -j DNAT --to-destination 192.168.2.2

If I do a ping 8.8.8.8 from the lxc container everything is working (the source IP gets translated to 10.9.63.173 when leaving the linux machine). But the second rule is never matched by the ping echo replies. I have watched the incoming packets on eth0 (10.9.63.173) using tcpdump and the output is as follows:

23:34:33.151565 IP google-public-dns-a.google.com > host.local: ICMP echo reply, id 536, seq 174, length 64

Therefore, packets with destination 10.9.63.173 arrive on eth0 interface.

I have three questions:

1) Why is the nat prerouting rule never matched?

2) How does iptables know how to modify replies such that to forward them to 192.168.2.2?

3) Can the SNAT target modify the source port (without explicitly telling to translate to a specific port(s))?

Thanks!

3 Answers 3

1

Iptables is using a NAT table, and the conntrack machine. This way, if your container initiate the connection, it will match the SNAT rule, write in the NAT table, and fill the conntrack one.

When a reply is coming, conntrack knows (with source and destination ip and port, and TCP sequence if the connection is TCP) that the packet belongs to the connection, and will address it to the right NAT correspondance.

Per connection, only the first packet will match a NAT rule, then every other will just follow the same path (or reverse path).

If a new connection is coming from the outside to your container, it will match the DNAT rule instead.

SNAT can't modify the source port.

2
  • Ok! Thanks! Is there any official documentation to specify the exact behaviour of iptables nat?
    – SebiSebi
    Jan 5, 2017 at 16:48
  • Take a look on this, this, and this. Jan 6, 2017 at 9:10
1

1) Why is the nat prerouting rule never matched?

iptables NAT works on "connections"*, only the first packet of each "connection" goes through the user-controlled nat tables.

2) How does iptables know how to modify replies such that to forward them to 192.168.2.2?

When the first packet of a "connection" passes through the NAT it establishes an entry in an internal connection tracking table. This is used to translate later packets of the connection.

3) Can the SNAT target modify the source port (without explicitly telling to translate to a specific port(s))?

Yes it can, but by default it will only do so if it is nessacery to avoid ambiguity.

* "connection" here refers to a set of criteria that can be used to match requests to their corresponding responses. e.g. the source ip/source port/destination ip/destination port tuple for TCP/UDP or the source ip/type/id/code/destination ip for ICMP queries.

0

Take a read for TCP and connection tracking I guess: http://www.iptables.info/en/connection-state.html

SNAT can only modify source IP address so far I know.

3
  • 1
    Including the pertinent information from a link will greatly improve this answer, and make it still helpful even if the link changes and goes bad. Feb 9, 2017 at 19:06
  • That comment rings very true now the link is dead @music2myear.
    – Cimbali
    Feb 9, 2023 at 16:35
  • @Cimbali this is why it is a rule on this site. Feb 9, 2023 at 19:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .