This is an excellent post and great reference material. I’ve done this a few times before and the information was scattered all over the place. I appreciate the clear and concise writing here. I even added it to my HN favorites - a rare accolade!
One thing I’d add, is that the best explanation I’ve ever seen for this, is the famous diagram [0] on Wikipedia of the netfilter API — I remember when I saw that, everything clicked into place. I’m not sure how up to date it is now, but it’s really good.
[0] https://commons.wikimedia.org/wiki/File:Netfilter-packet-flo...
The wiki diagram helped me too, thanks!
One thing I did not understand before: why SNAT must happen at POSTROUTING?
Because the exit interface is only known after the routing decision... before that kernel does not know which source IP to write
this visual schematic made it click for me - https://vectree.io/c/linux-netfilter-packet-flow-tables-chai...