Port Forwarding

This is my first attempt at documenting the code I wrote to expand on the
functionality of the IP Masquerading code included in Linux 2.0.* kernels.

Short comment: There used to be an ad here asking for people to offer me a
job. Thank you to the several people that did and an especially big thank to
the IP Masquerading maintainer, Nigel Metheringham, who's now my boss!

New

Thanks to Ray Bagley for producing new patches for 2.0.33. They are now
available
atftp://ftp.ox.compsoc.org.uk/pub/users/steve/ipsubs/subs-patch-1.34.gz

Port Forwarding - Why?

Before I describe what port forwarding is, let me describe the situation
that persuaded me to write this code. A local computer group had 3 computers
and 1 IP address. They had implemented an IP masquerading solution to allow
people to use all 3 computers with the configuration:

                          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:

   * Some services such as rlogin in to the cluster didn't work properly
   * Logs on internal machines were difficult to interpret as all
     connections originated at the gateway host.
   * Making internal services which use UDP visible externally was
     difficult.
   * Redirecting inward connections was much slower than masquerading
     outward ones.
   * It confused the users.

Port Forwarding - What is it?

The easiest way to imagine Port Forwarding is a combination of routing by
port combined with packet rewriting. A convention router examines the packet
header and dispatches the packet on one of its other interfaces, depending
on the packet's destination address. Port Forwarding examines the packet
header and forwards it on to another host (after a little header rewriting)
depending on the destination port.

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/80

This would be forwarded on to the internal host as:

Source: 163.158.1.2/7890  Dest: 10.0.0.2/80

Replies would be labelled:

Source: 10.0.0.2/80       Dest: 163.158.1.2/7890

and would be rewritten by the gateway to:

Source 194.160.1.1        Dest: 163.158.1.2/7890

This has a number of advantages over using tools like nc and plug-gw to do
the forwarding:

   * As there is less copying of packets in memory, its much faster.
   * Internal hosts see the original connection source so so logs are
     meaningful.
   * It's easy to load split between the internal hosts. The choice of host
     can also depend on live feedback such as which machine has the lower
     load average. This decision making is done entirely in userspace so is
     easy to implement.
   * As redirection is done at a packet level, you don't need different
     gatewaying tools for different services.
   * It's very stable. Our gateway machine has been crashed many times (it's
     not difficult to crash a machine with only 4Mb of memory) but it's
     carried on forwarding/masquerading although someone notices that they
     can't log in and reboots it.

Port Forwarding - How does it work?

[This section is optional reading and is not necessary to use Port
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.

Port Forwarding - How do I use it?

The code was original written for Linux 2.0.27-29 and worked with many other
2.0.* kernel. Changes were made to the kerne's masquerading code in 2.0.30
and this provoked me to improve and upgrade my patches while converting them
for 2.0.30. The new patches use 17k less memory when in use and are smaller,
neater and better integrated into the kernel distribution and with a
Makefile option.

Using the Linux 2.0.27-29 patches.
Using the Linux 2.0.30-33 patches.

Port Forwarding - Anything else?

When I wrote this code, I didn't imagine anyone else ever using this code
other than the computer group I mentioned. I would appreciate all comments
on the idea of port forwarding and its implementation, whether it's "didn't
you know there's a much easier way of doing it" or "I liked the idea but I
extended it by doing ...". If there are any mistakes or areas that aren't
clear in the above documentation, please also let me know. My email address
is: steven@monmouth.demon.co.uk

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...

Short comment: There used to be an ad here asking for people to offer me a
job. Thank you to the several people that did and an especially big thank to
the IP Masquerading maintainer, Nigel Metheringham, who's now my boss!

----------------------------------------------------------------------------
Last updated on 25th November, 1997
SC
