IPPORTFW, IPAUTOFW, REDIR, UDPRED, and other programs are generic TCP and/or UDP port forwarding tools for Linux IP Masquerade (for < 2.4 kernels). 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, SMTP, FTP (with a special patch - see below), ICQ, and many others.
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? MARK (MFW), IPMASQADM (PORTFW or AUTOFW), IPPORTFW, IPAUTOFW, REDIR, and UDPRED (all URLs are in Section 3.2.3) were the various tools available to IP MASQ users to allow this type of functionality. Later, as the Linux IP Masquerade feature matured, many of these tools were eventually replaced by the PORTFW and MARK systems which are more intelligent solutions.
In recent 2.2.x kernels, the IPMASQADM tool combined the IPAUTOFW and IPPORTFW 2.0.x kernel tools into one binary. Both the IPMASQADM tool and IPTABLES also supports a new mechanism called "MARK" or MFW. 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 destination. Currently, this HOWTO doesn't cover the MARK solution but it will in the near 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 (not 2.4.x), 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 implement the REDIR tool for 2.2.x and 2.0.x kernels to let internal machines get redirected to the internal servers too. The 2.4.x kernels running IPTABLES solves this issue once and for all and is covered in a FAQ entry in Section 7.19. 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 FTP server traffic to an internal MASQed FTP server, known as PORTFW FTP, is now fully supported in the 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.
2.4.x kernels users should be ready to go for PORTFW functionality. 2.2.x and 2.0.x kernel kernel users will need to re-compile the Linux kernel to support PORTFW. It should be noted that some Linux distribution kernels might have this already done for you.
Modern 2.2.x kernel users will already have the PORTFW kernel option available to them via the normal kernel "make" procedures.
2.0.x users will need to apply a simple kernel option patch to have access to then enable this via the normal kernel "make" procedures.
Unlike ALL previous Linux kernels, the 2.4.x series 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 a 2.4.x kernel:
Edit the /etc/rc.d/rc.firewall-2.4 ruleset and place the lines shown below just ABOVE the "FWD: Allow all connections OUT and only existing and related ones IN" line (in the "Optional FORWARD section"). Please be sure to replace the word "$EXTIP" with your specific Internet IP address.
NOTE: Unlike the 2.2.x and 2.0.x kernels, PORTFWed traffic does *not* traverse the INPUT or OUTPUT rules. It only traverses the FORWARD rule.
NOTE: If you use get a DYNAMIC TCP/IP address from your ISP (PPP, ADSL, Cablemodems, etc.), you will NEED to make your /etc/rc.d/rc.firewall ruleset more intelligent. To do this, please see Section 6.4.2 from above or TrinityOS - Section 10 for more details on strong rulesets and Dynamic IP addresses. I'll give you a hint though: /etc/ppp/ip-up for PPP users.
/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-2.4 ruleset, you # will need to enable the following EXTIP option. Users of the # rc.firewall-2.4-stronger ruleset already have this defined. # # *PLEASE* look over the rc.firewall-2.4-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 # $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 # $IPTABLES -A PREROUTING -t nat -p tcp -d $EXTIP --dport 80 \ -j DNAT --to $PORTFWIP:80 |
That's it! Just re-run your /etc/rc.d/rc.firewall-2.4 ruleset and test it out!
--------------------------------------------------------------------------
Running the rc.firewall-2.4-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:
Take the ruleset lines shown above (for the generic rc.firewall ruleset) and place them just after the "#FORWARD Enable Forwarding and thus IPMASQ" comment lines. It should also be noted that you DO NOT have to enable the "HTTPD" rules under the "Optional 'INPUT' section" for 2.4-based kernels. With 2.4 kernels, those lines are ONLY used if you want to allow HTTP traffic to terminate on the MASQ server's httpd process (Apache).
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-2.4 script), the simple PREROUTING command like the one shown above changed for for port "21" should do the trick. This is much easier than the configuration for the old 2.2.x / 2.0.x kernels!
Please note, if you setup PORTFW to an internal FTP server that is running on a NON-standard FTP port, say port 8021, you MUST tell the "ip_conntrack_ftp" module about the new FTP port. The reason for this is that FTP is not a NAT-friendly protocol. By telling the NAT module about this new non-standard FTP port, the NAT module and do it's job again. To do 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 machines out on the Internet would 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 is a workaround for 2.2.x and 2.0.x kernels using the REDIR tool. Even better, the use of the REDIR tool is NOT required for the 2.4.x kernels. 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 internal WWW traffic to the 192.168.0.2 internal machine (please change the IP address to reflect your configuration):
$IPTABLES -t nat -A PREROUTING -d $EXTIP -p tcp --dport 80 \ -m state --state NEW,ESTABLISHED,RELATED -j DNAT --to 192.168.0.2 |
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:
Edit the /etc/rc.d/rc.firewall ruleset and ENABLE the "Optional" "HTTP" sections in both the INPUT and OUTPUT subsections.
Add the following lines shown below JUST BELOW the "ipchains -P forward DENY" rule (in the "Optional FORWARD section"). Be sure to replace the "$EXTIP" variable's contents with your EXTERNAL Internet IP address on the IPMASQ server.
NOTE: If you use get a DYNAMIC TCP/IP address from your ISP (PPP, ADSL, Cablemodems, etc.), you will NEED to make your /etc/rc.d/rc.firewall ruleset more intelligent. To do this, please see Section 6.4.2 from above or TrinityOS - Section 10 for more details on strong rulesets and Dynamic IP addresses. I'll give you a hint though: /etc/ppp/ip-up for PPP users.
/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.
For those who want to understand why PORTFW cannot redirect traffic for both external and internal interfaces (the REDIR situation), 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 |
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: If you use get a DYNAMIC TCP/IP address from your ISP (PPP, ADSL, Cablemodems, etc.), you will NEED to make your /etc/rc.d/rc.firewall ruleset more intelligent. To do this, please see Section 6.4.2from above or TrinityOS - Section 10 for more details on strong rulesets and Dynamic IP addresses. I'll give you a hint though: /etc/ppp/ip-up for PPP users.
/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:
FIRST, apply the IPPORTFW kernel patch as shown earlier in this section.
Download the "msqsrv-patch-36" from Fred Viles's FTP server in Section 3.2.3and put it into /usr/src/linux.
Patch the kernel with this new code by running "cat msqsrv-patch-36 | patch -p1"
Next, replace the original "ip_masq_ftp.c" kernel module with the new one
mv /usr/src/linux/net/ipv4/ip_masq_ftp.c /usr/src/linux/net/ipv4/ip_masq_ftp.c.orig
mv /usr/src/linux/ip_masq_ftp.c /usr/src/linux/net/ipv4/ip_masq_ftp.c
Lastly, build and install the kernel with this new code in place.
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!