The basic use of NAT accomplishes much the same thing that Linux's IP Masquerading
function does, and it does it with one simple rule:
map tun0 192.168.1.0/24 -> 18.104.22.168/32
Very simple. Whenever a packet goes out the tun0 interface with a source address matching the CIDR network mask of 192.168.1.0/24 [[dagger]][[dagger]] this packet will be rewritten within the IP stack such that its source address is 22.214.171.124, and it will be sent on to its original destination. The system also keeps a list of what translated connections are in progress so that it can perform the reverse and remap the response (which will be directed to 126.96.36.199) to the internal host that really generated the packet. [[footnote: [[dagger]][[dagger]] This is a typical internal address space, since it's non-routable on the Real Internet it is often used for internal networks. You should still block these packets coming in from the outside world as discussed earlier. ]]
There is a drawback to the rule we have just written, though. In a large number of
cases, we do not happen to know what the IP address of our outside link is (if we're using
tun0 or ppp0 and a typical ISP) so it makes setting up our NAT tables a
chore. Luckily, NAT is smart enough to accept an address of 0/32 as a signal that it needs
to go look at what the address of that interface really is and we can rewrite our rule as
map tun0 192.168.1.0/24 -> 0/32
Now we can load our ipnat rules with impunity and connect to the outside world without having to edit anything. You do have to run ipf -y to refresh the address if you get disconnected and redial or if your DHCP lease changes, though.
Some of you may be wondering what happens to the source port when the mapping happens.
With our current rule, the packet's source port is unchanged from the original source
port. There can be instances where we do not desire this behavior; maybe we have another
firewall further upstream we have to pass through, or perhaps many hosts are trying to use
the same source port, causing a collision where the rule doesn't match and the packet is
passed untranslated. ipnat helps us here with the portmap keyword:
map tun0 192.168.1.0/24 -> 0/32 portmap tcp/udp 20000:30000
Our rule now shoehorns all the translated connections (which can be tcp, udp, or tcp/udp) into the port range of 20000 to 30000.