6.7. Port Forwarding with IPTABLES or external tools like IPPORTFW, IPMASQADM, IPAUTOFW, REDIR, UDPRED, and other Port Forwarding tools

IPTABLES as well as IPPORTFW, IPAUTOFW, REDIR, UDPRED, and other programs offer generic TCP and/or UDP port forwarding for Linux IP Masquerade. These tools are typically used with or as a replacement for specific IP MASQ modules to get a specific network traffic through the MASQ server.

With port forwarders, you can redirect data connections from the Internet to an internal, privately addressed machine behind your IP MASQ server. This forwarding ability includes network protocols such as TELNET, WWW, and SMTP. Protocols such as FTP, legacy ICQ, and others require special handling via kernel modules (see below).

NOTE: If you are just looking to do simple port forwarding but you don't need Masquerading support, you don't have any choice. You will STILL NEED to enable IP Masquerading support in the kernel AND either run a IPTABLES, IPCHAINS, or IPFWADM ruleset to be able to use Linux's port forwarding tools.

So why all the different choices? IPTABLES, IPPORTFW, MARK (MFW), IPMASQADM (PORTFW or AUTOFW), IPAUTOFW, REDIR, and UDPRED (all URLs are in Section 3.2.3) are the various tools available to IP MASQ users to allow this type of functionality depending on their kernel version. Later, as the Linux IP Masquerade feature matured, many of these tools were eventually replaced by the IPTABLES or PORTFW and MARK systems which are far more intelligent solutions.

For the later 2.2.x kernels, the IPMASQADM tool combined the legacy IPAUTOFW and IPPORTFW 2.0.x kernel tools into one binary. Both the IPMASQADM tool for 2.2.x kernels as well as IPTABLES for the 2.6.x and 2.4.x kernels also supports a new mechanism called "MARK" or MFW for PORTFW functionality. The MARK system works where a specific IPTABLES or IPCHAINS ruleset would match a given packet sequence. Once matched, the tool would "mark" these packets. Later, the IPMASQADM tool or a specific IPTABLE "table" could be instructed to change these packets as needed and forward them off to their desired internal destination. Currently, this HOWTO doesn't cover the MARK solution but it will in the future.

Anyway, because of the availablity of the newer tools, it is *HIGHLY DISCOURAGED* to use the old tools such as IPAUTOFW (even AUTOFW in IPMASQADM) and REDIR because they don't properly notify the Linux kernel of their presence and can ultimately CRASH your Linux server with extreme use.

NOTE #2: With enabling PORTFW functionality in ANY 2.2/2.0 Linux kernel (2.6.x. and 2.4.x users won't use these specific tools anyway), internal machines typically CANNOT use the same "external" PORTFWed IP address to access a given internal" machine. To put it another way, PORTFW was only intended to be used with "external" computers on the Internet. If this is an issue for you, you can also use the REDIR tool for older 2.2.x and 2.0.x kernels to let internal machines get redirected to the internal servers too. 2.6.x and 2.4.x kernels users running IPTABLES solves this issue once and for all and is fully covered in a FAQ entry in Section 7.19 below. If you would like a technical explination on why this internal/external forwarding doesn't work, please page down towards the bottom of the 2.2.x PORTFW section for a note from Juan Jose Ciarlante.

NOTE #3: The forwarding of non-NAT friendly traffic such as FTP server traffic to an internal MASQed FTP server, known as PORTFW FTP, is now fully supported in the 2.6.x and 2.4.x kernels as well as in the 2.2.x kernels via a BETA version FTP kernel module (does NOT come with the stock Linus kernels). It should also be noted that you can also PORTFW FTP traffic using an external FTP proxy program (not covered in this HOWTO). It should be noted that the Beta 2.2.x FTP kernel module code is still experimental and some people get better results simply using ACTIVE FTP sessions compared to PASSIVE connections. Interestingly enough, other people have seen the exact opposite behavior. Please let us know what your results are like. More about this is covered below in both the 2.2.x and 2.0.x sections as the solutions require the use of different patches.

WARNING! Before jumping right into installing ANY of these tools, it needs to be mentioned that network security can be an issue with ANY PORT FORWARD tool. The reason for this is because these tools basically create a hole in strong packet firewalls for the required TCP/UDP ports. Though this doesn't pose any threat to your Linux machine, it might be an issue to the PORTFW'ed internal machine(s). No worries though, this is what Steven Clarke (the author of IPPORTFW) had to say about that:

   "Port Forwarding is only called within masquerading functions so it 
   fits inside the same IPFWADM/IPCHAINS rules. Masquerading is an extension to 
   IP forwarding. Therefore, ipportfw only sees a packet if it fits 
   both the input and masquerading ipfwadm rule sets."

What that means in English is that if you have a strong packet firewall running, PORTFW doesn't directly bypass any of that security. You will still be able to allow or deny specific IPs and/or domains to this new PORTFW'ed resource if you so wish.

With this said, it's important to have a strong firewall ruleset. Please see Section 6.4.1, Section 6.4.2, and Section 6.4.3 for more details on getting strong rulesets.

6.7.1. IPTABLES-based PORTFWD'ing: Using IPTABLES's PREROUTING option for 2.6.x and 2.4.x kernels

As mentioned before, a port forward or "PORTFW" allows a single or range of TCP/IP ports from the external side of the network to be forwarded into the inside network.

Unlike ALL previous Linux kernels, the 2.6.x and 2.4.x series kernels now allows for full PORTFW, PORTFW FTP, and PORTFW REDIR functionality within the "iptables" tool itself.

NOTE: Once you enable a port forwarder on say port 80 (forward WWW traffic through the MASQ server to an internal WWW server), that port will no longer be used by the Linux IP Masquerade server itself. To be more specific, if you have a WWW server already running on the MASQ server, enabling PORTFW will now give all Internet users acces to the WWW pages from the -INTERNAL- WWW server and not the pages on your IP MASQ server.

To enable port forwarding on an IPTABLES (2.6.x or 2.4.x kernel):

/etc/rc.d/rc.firewall-*

#echo "Enabling PORTFW Redirection on the external LAN.."
#
#   This will forward ALL port 80 traffic from the external IP address
#   to port 80 on the 192.168.0.10 machine
#
#   Be SURE that when you add these new rules to your rc.firewall-*, you
#   add them before a direct or implict DROP or REJECT.
#
PORTFWIP="192.168.0.10"


# NOTE:  If you are using the basic rc.firewall-iptables ruleset, you
#        will need to enable the following EXTIP option.  Users of the
#        rc.firewall-iptables-stronger ruleset already have this defined.
#
#  *PLEASE* look over the rc.firewall-iptables-stronger ruleset for more 
#            specific issues regarding dynamic vs. static IP addresses
#
#
# Determine the external IP automatically:
# ----------------------------------------
#
#  The following line will determine your external IP address.  This
#  line is somewhat complex and confusing but it will also work for
#  all NON-English Linux distributions:
#
# DISABLED by default -- to enable, REMOVE both the "#" characters below
#
#EXTIP="`$IFCONFIG $EXTIF | $AWK \
#/$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"


# Allow forwarding of new and existing port 80 connections from the external
# interface.  This rule is required as our default FORWARD policy is DENY.
#
$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 80 -m state \
 --state NEW,ESTABLISHED,RELATED -j ACCEPT


#Enable PORTFW of this port 80 traffic from the external interface
#
$IPTABLES -A PREROUTING -t nat -p tcp -d $EXTIP --dport 80 -m state \ 
 --state NEW,ESTABLISHED,RELATED -j DNAT --to $PORTFWIP:80 

That's it! Just re-run your /etc/rc.d/rc.firewall-iptables ruleset and test it out! If you would like to learn more about this, please see the Section 7.19

--------------------------------------------------------------------------

Running the rc.firewall-iptables-stronger ruleset? Good for you! To get PORTFW running with this ruleset, it's very easy. The following example is for HTTP (WWW) traffic to be PORTFWed to the IP address indicated by the $PORTFWIP variable:

PORTFW FTP: If you have the "ip_conntrack_ftp" and "ip_nat_ftp" kernel modules loaded into kernel space (as already done in the rc.firewall-iptables script), the simple PREROUTING command like the one shown above changed for port "21" should do the trick. This is much easier than the configuration for the older IPCHAINS / IPFWADM tools for the 2.2.x / 2.0.x kernels!

Please note, if you setup PORTFW to redirect traffic to an internal FTP server that is running on a NON-standard FTP port, say port 8021 instead of the usual port 21, you MUST tell the "ip_conntrack_ftp" module to be aware of the new FTP port. The reason for this configuration change is that FTP is not a NAT-friendly protocol. By telling the FTP NAT module about this non-standard FTP port, the NAT module and do it's job again. To enable this, edit your rc.firewall-* file and change the loading of the FTP module to look something like this:

/sbin/insmod ip_conntrack_ftp ports=21,8021

PORTFW Redirection of Internal requests:

In the past, if users PORTFWed port 80 on their EXTERNAL IP address to some internal machine, only the machines out on the Internet would be able to properly reach this internal WWW server. If you tried to contact this internal WWW server via the MASQ server's EXTERNAL address, it would fail. Fortunately, there are workarounds for all Linux kernels. IPTABLES for the 2.6.x and 2.4.x kernels supports this functionality natively. IPCHAINS support for the 2.2.x kernels and IPFWADM support for the 2.0.x kernels need to use the external REDIR tool (not currently covered in the HOWTO). For those of you who understand IPTABLES fairly well, the rule of thumb is a PREROUTING/DNAT rule is for enabling PORTFW from *external* machines and a POSTROUTING/SNAT rule is for enabling PORTFW from *internal* machines.

To support redirection like this from an internal host, add a rule like the one shown below ABOVE the "Catch all" FORWARDing rule in the rc.firewall-* file. The following example will REDIRECT all external as well as internal WWW traffic to the internal machine noted as PORTFWIP (192.168.0.10). This traffic will have the source IP address of the IP Masq server's internal IP address. Please change the IP address of the PORTFWIP variable to reflect your specific configuration:

#The following rule should be configured in *addition* to the above rule
# for enabling external to internal PORTFWing

$IPTABLES -t nat -A POSTROUTING -d $PORTFWIP -s $INTLAN -p tcp \
--dport 80 -m state --state NEW,ESTABLISHED,RELATED -j SNAT \
--to $INTIP

6.7.2. IPMASQADM-based PORTFWD'ing: Using IPMASQADM with 2.2.x kernels

First, make sure you have the newest 2.2.x kernel uncompressed into /usr/src/kernel/linux. If you haven't already done this, please see Section 3.2.2 section for full details. Next, download the "ipmasqadm.c" program from Section 2.7 into the /usr/src/kernel directory.

Next, you'll need to compile the 2.2.x kernel as shown in Section 3.2.2 section. Be sure to say "YES" to the IPPORTFW option when you configure the kernel. Once the kernel compile is complete and you have rebooted, return to this section.

Now, compile and install the IPMASQADM tool:

        cd /usr/src
        tar xzvf ipmasqadm-x.tgz
        cd ipmasqadm-x
        make
        make install 

Now, for this example, we are going to allow ALL WWW Internet traffic (port 80) hitting your Internet TCP/IP address to be forwarded to the internal Masqueraded machine at IP address 192.168.0.10.

PORTFW FTP: As mentioned above, there are two solutions for forwarding FTP server traffic to an internal MASQed PC. The first solution *IS* a BETA level IP_MASQ_FTP module for 2.2.x kernels to PORT Forward FTP connections to an internal MASQed FTP server. The other method is using a FTP proxy program (the URL is in Section 2.7. It should also be noted that the FTP kernel module also supports the adding of additional PORTFW FTP ports on the fly without the requirement of unloading and reloading the IP_MASQ_FTP module and thus breaking any existing FTP transfers. You can find more about this new code at the IPMASQ WWW site at http://ipmasq.webhop.net;. There are also examples and some additional information about PORTFWed FTP connection below in the 2.0.x. kernel section.

NOTE: Once you enable a port forwarder on port 80, that port can no longer be used by the Linux IP Masquerade server. To be more specific, if you have a WWW server already running on the MASQ server, a port forward will now give all Internet users the WWW pages from the -INTERNAL- WWW server and not the pages on your IP MASQ server.

Anyway, to enable port forwarding for HTTPd:

NOTE #2: If you get a dynamically assigned TCP/IP address from your ISP (PPP, DSL, Cablemodems, etc.), you CANNOT load this strong ruleset upon booting. You will either need to reload this firewall ruleset EVERY TIME you get a new IP address or make your /etc/rc.d/rc.firewall-ipchains-stronger ruleset more intelligent. To do this for various types of connections such as PPP or DHCP users, please see the Section 7.8 FAQ entry for all the details.

/etc/rc.d/rc.firewall-*

#echo "Enabling IPPORTFW Redirection on the external LAN.."
#
#   This will forward ALL port 80 traffic from the external IP address
#   to port 80 on the 192.168.0.10 machine
#
PORTFWIP="192.168.0.10"

/usr/sbin/ipmasqadm portfw -f
/usr/sbin/ipmasqadm portfw -a -P tcp -L $EXTIP 80 -R $PORTFWIP 80

That's it! Just re-run your /etc/rc.d/rc.firewall-* ruleset and test it out!

If you get the error message "ipchains: setsockopt failed: Protocol not available", you AREN'T running your new IPPORTFW enabled kernel. Make sure that you moved the new kernel over, re-run LILO, and then reboot again. If you are sure you are running your new kernel, run the command "ls /proc/net/ip_masq" and make sure the "portfw" file exists. If it doesn't, you must have made an error when configuring your kernel. Try again.

PORTFW Redirection of Internal requests:

It should be mention that this IPMASQ HOWTO currently does *NOT* provide any explination or examples on how to use the REDIR tool. If you need help setting it up for 2.2.x kernels, send me an email. For those who want to understand why PORTFW cannot redirect traffic for both external and internal interfaces (what the REDIR tool fixes), here is an email from Juanjo that better explains it.

From Juanjo Ciarlante
--

>If I use:
>
> ipmasqadm portfw -a -P tcp  -L 1.2.3.4 80 -R 192.168.2.3 80
>
>Everything works great from the outside but internal requests for the same
>1.2.3.4 address fail. Are there chains that will allow a machine on localnet 
>192.168.2.0 to accesss www.periapt.com without using a proxy? 

Actually not.

I usually setup a ipmasqadm rule for outside, *AND* a port
redirector for inside. This works because ipmasqadm hooks before
redir will get the eventual outside connection, _but_ leaves things
ok if not (stated by APPROPIATE rules).

The actual "conceptual" problem comes from the TRUE client (peer) IP
goal (thanks to masq) being in the same net as target server.

The failing scenario for "local masq" is :
   client: 192.168.2.100
   masq:   192.168.2.1
   serv:   192.168.2.10

1)client->server packet
 a) client:  192.168.2.100:1025  -> 192.168.2.1:80   [SYN]
 b) (masq):  192.168.2.100:1025  -> 192.168.2.10:80  [SYN]
            (and keep  192.168.2.1:61000 192.168.2.100:1025 related)
 c) serv:    gets masqed packet (1b)

2)server->client packet
 a) serv:    192.168.2.10:80     -> 192.168.2.100:1025  [SYN,ACK]
 b) client:  192.168.2.100:1025  -> 192.168.2.10:80     [RST]

Now take a moment to compare (1a) with (2a).
You see, the server replied DIRECTLY to client bypassing masq (not
letting masq to UNDO the packet hacking) because it is in SAME net, so
the client resets the connection.

hope I helped.

Warm regards
Juanjo

6.7.3. IPPORTFW-based PORTFWD'ing: Using IPPORTFW on 2.0.x kernels

First, make sure you have the newest 2.0.x kernel uncompressed into /usr/src/kernel. If you haven't already done this, please see Section 3.2.3 for full details. Next, download the "ipportfw.c" program and the "subs-patch-x.gz" kernel patch from Section 3.2.3 into the /usr/src/ directory.

NOTE: Please replace the "x" in the "subs-patch-x.gz" file name with the most current version available on the site.

Next, if you plan on port forwarding FTP traffic to an internal server, you will have to apply an additional NEW IP_MASQ_FTP module patch found in Section 3.2.3. More details regarding this are later in this section. Please note that this is NOT the same patch as for the 2.2.x kernels so some functionality such as the dynamic FTP PORT functionality is not present.

Now, copy the IPPORTFW patch (subs-patch-x.gz) into the Linux directory

        cp /usr/src/subs-patch-1.37.gz /usr/src/linux

Next, apply the kernel patch to create the IPPORTFW kernel option:

        cd /usr/src/linux
        zcat subs-patch-1.3x.gz | patch -p1

Ok, time to compile the kernel as shown in Section 3.2.3. Be sure to say YES to the IPPORTFW option now available when you configure the kernel. Once the compile is complete and you have rebooted, return to this section.

Now with a newly compiled kernel, please compile and install the actual "IPPORTFW" program

        cd /usr/src
        gcc ipportfw.c -o ipportfw
        mv ipportfw /usr/local/sbin

Now, for this example, we are going to allow ALL WWW Internet traffic (port 80) hitting your Internet TCP/IP address to then be forwarded to the internal Masqueraded machine at IP address 192.168.0.10.

NOTE: Once you enable a port forwarder on port 80, that port can no longer be used by the Linux IP Masquerade server. To be more specific, if you have a WWW server already running on the MASQ server and then you port forward port 80 to an internal MASQed computer, ALL internet users will see the WWW pages, pages from the -INTERNAL- WWW server and not the pages on your IP MASQ server. This only performs a port forward to some other port, say 8080, to your internal MASQ machine. Though this will work, all Internet users will have to append :8080 to the URL to then contact the internal MASQed WWW server.

Anyway, to enable port forwarding, edit the /etc/rc.d/rc.firewall-* ruleset. Add the follow lines but be sure to replace the word "$extip" with your Internet IP address.

NOTE #2: If you get a dynamically assigned TCP/IP address from your ISP (PPP, DSL, Cablemodems, etc.), you CANNOT load this strong ruleset upon booting. You will either need to reload this firewall ruleset EVERY TIME you get a new IP address or make your /etc/rc.d/rc.firewall-ipchains-stronger ruleset more intelligent. To do this for various types of connections such as PPP or DHCP users, please see the Section 7.8 FAQ entry for all the details.

/etc/rc.d/rc.firewall-*

#echo "Enabling IPPORTFW Redirection on the external LAN.."
#
#   This will forward ALL port 80 traffic from the external IP address
#   to port 80 on the 192.168.0.10 machine
#
/usr/local/sbin/ipportfw -C
/usr/local/sbin/ipportfw -A -t$extip/80 -R 192.168.0.10/80

That's it! Just re-run your /etc/rc.d/rc.firewall-* ruleset and test it out!

If you get the error message "ipfwadm: setsockopt failed: Protocol not available", you AREN'T running your new kernel. Make sure that you moved the new kernel over, re-run LILO, and then reboot again.

Port Forwarding FTP servers:

If you plan on port forwarding FTP to an internal machine, things get more complicated. The reason for this is because the standard IP_MASQ_FTP kernel module wasn't written for this though some users report that it works without any problems. Personally, without the patch, I've heard that extended file transfers in excess of 30 minutes will fail without the patch while other users swear that it works flawlessly. Anyway, I recommend that you try the following PORTFW instruction with the STOCK ip_masq_ftp module and see if it works for you. If it doesn't, try using the modified ip_masq_ftp module.

For those who need the module, Fred Viles wrote a modified IP_MASQ_FTP module to make things work. If you are curious what EXACTLY are the issues, download the following archive since Fred documents it quite well. Also understand that this patch is somewhat experimental and should be treated as such. It should be noted that this patch is ONLY available for the 2.0.x kernels though there is a different patch available for 2.2.x kernels.

So, to get the 2.0.x patch working, you need to:

Once this is complete, edit the /etc/rc.d/rc.firewall-* ruleset and add the following lines, but be sure to replace the word "$extip" with your Internet IP address.

This example, like the one above, will allow ALL FTP Internet traffic (port 21) hitting your Internet TCP/IP address to then be forwarded to the internal Masqueraded machine at IP address 192.168.0.10.

NOTE: Once you enable a port forwarder on port 21, that port can no longer be used by the Linux IP Masquerade server. To be more specific, if you have an FTP server already running on the MASQ server, a port forward will now give all Internet users the FTP files from the -INTERNAL- FTP server and not the files on your IP MASQ server.

/etc/rc.d/rc.firewall-*

#echo "Enabling IPPORTFW Redirection on the external LAN.."
#
/usr/local/sbin/ipportfw -C
/usr/local/sbin/ipportfw -A -t$extip/21 -R 192.168.0.10/21

#NOTE: If you are using multiple local port numbers to PORTFW
#      to multuple internal FTP servers (say, 21, 2121, 2112,
#      etc, you need to configure the ip_masq_ftp nodule to
#      listen to these ports.  To do this, edit the 
#      /etc/rc.d/rc.firewall-* script as shown in this HOWTO
#      to look like:
#
# /sbin/modprobe ip_masq_ftp ports=21,2121,2112
#
# Re-run the /etc/rc.d/rc.firewall-* script for these changes to
# take effect.


#Please note that PORTFWing port 20 is probably NOT required 
#  for ACTIVE connections as the internal FTP server will 
#  initiate this port 20 connection and it will be properly 
#  handled by the classic MASQ mechanisms.

That's it! Just re-run your /etc/rc.d/rc.firewall-* ruleset and test it out!

PORTFW Redirection of Internal requests:

It's not clear if the REDIR tool will compile or work against legacy 2.0.x kernels. It should also be mentioned that this IPMASQ HOWTO currently does *NOT* provide any explination or examples on how to use the REDIR tool. If you need help setting it up, send me an email. If you would like to learn more about REDIR, please see the above section for the 2.2.x kernels.