Why does SNAT happen in POSTROUTING chain and DNAT in PREROUTING chain?

I'm pretty sure anything coming from the local machine never goes through the PREROUTING table, as seen in this awesome ASCII figure.


Usually the main criterion for SNAT is "traffic that's going out a given interface" (i.e. -o eth0). What interface a packet will go out is determined by routing, so to apply that criterion you need to run it in a POSTROUTING context.

DNAT rewrites the destination address of a packet, meaning it can affect where a packet goes to — for example, a packet that looks like it's destined for the gateway could end up being rewritten to go to a machine on the network instead. Since you want the routing to be able to take that rewritten destination into account when it makes its decision, so that the packet actually goes where it needs to, DNAT should run in a PREROUTING context.


As the chain names suggest, PREROUTING is done at first when a packet is received and is thus routed based on where it is going (destination). After all other routing rules have been applied, the POSTROUTING chain will determine where it goes based on where it came from (source).

For example, on my server, incoming ports that are to be forwarded (NATed) are all defined in the PREROUTING chain as DNAT, and all packets that come from the NATed interfaces, go through the POSTROUTING chain as SNAT, and consequently (in this case), go through the filter FORWARD chain.