INTERNET
| (194.160.1.1)
linux box 1
| (10.0.0.1)
+--------------------------+ internal ethernet
| (10.0.0.2) | (10.0.0.3)
linux box 2 linux box 3
The first linux box was a 386SX20 with only 4Mb and couldn't have coped
with any real users. We then redirected telnet, mail, web, etc. to one of
the two internal machines with plug-gw or nc (netcat) from inetd.This had a number of problems:
In more detail: Port forwarding forwards all packets intended for one forwarding port on the gateway from the external networks to routed on a specified port on one of the internal machines (after a little rewriting of headers). This is (in some ways) a reverse of masquerading and uses many of the maquerading functions - particularly the packet header rewriting code.
Confused? Here's an example:
On the gateway, we setup the rule that all connections to port 80/tcp
should be redirected to port 80 on 10.0.0.2 (an internal machine).
The incoming web connection would be labelled:
Source: 163.158.1.2/7890 Dest: 194.160.1.1/80This would be forwarded on to the internal host as:
Source: 163.158.1.2/7890 Dest: 10.0.0.2/80Replies would be labelled:
Source: 10.0.0.2/80 Dest: 163.158.1.2/7890and would be rewritten by the gateway to:
Source 194.160.1.1 Dest: 163.158.1.2/7890This has a number of advantages over using tools like nc and plug-gw to do the forwarding:
Port forwarding uses the existing masquerading scheme to do all the rewriting of packets. The masquerading table (what you see when you type netstat -M or ipfwadm -M -l) is setup as if the connection started internally. When the existing masquerading code receives a packet from the external interface, it checks whether the destination port is in the range 61000-64999 and, if so, checks for any current entries in the masquerading table. If there is a matching entry, it rewrites the packet header and forwards it onto its new desintation. Port forwarding performs an additional check on the destination port if it isn't in the masquerading range to see whether it's a forwarding port. If it is, we let the existing code check for an entry in the masquerading table. If a corresponding entry exists in the masquerading table, the existing masquerading code rewrites the header and sends the packet out. If the destination port is a forwarding port but doesn't have an entry in the masquerading table, we create a suitable entry in the table before rewriting the packet and sending it out.
Using the Linux 2.0.27-29 patches.
Using the Linux 2.0.30-38 patches.
Using Port Forwarding with Linux 2.2.
First FAQ: I now know what port forwarding is but what's IP Substitution or IPSubs?
Answer: IP Substitution was the original name I gave to the code I wrote. I subsequently decided I didn't like the name and changed it to Port Forwarding instead.
Lastly...