hackorama logo
HOME |  CONTACT |  ABOUT  
 



 

PORT FORWARDING - with IPTABLES while using BASTILLE firewall

Background on network setup

I have my home network setup as described here. So my linux gateway server is the only one visible to the internet, while all other machines are in an internal subnet with DHCP assigned IP's not visible to the outside internet, but can access the outside net using Iptables based Network Address Translation (NAT).

Why you need portforwarding

So in this setup if I want to run a public service like httpd, not on the gateway server ( where it is visible to outside ) but on an internal machine ( which is not visible outside ) how do I make it availble to the outside internet.

To make the above scenario of exposing and internal machine's service to outside we need to use port forwarding on the gateway server. Which is assigning a port on the gateway to accept all connections and forward it to the internal machines port where the service is listening to.

Let xxx.xxx.xxx.xxx be the IP address of the gateway server connected to the cable modem and 192.168.0.2 , the IP address of the internal machine. And say we want to run a web server ( httpd ) on 192,168.0.2 on port 80 which should be avaialble to the outside internet. We can forward the port 80 on xxx.xxx.xxx.xxx to port 80 of 192.168.0.2

Source: xxx.xxx.xxx.xxx:80 -- forwarded to -> 192.168.0.2:80

You can chhose any port on xxx.xxx.xxx.xxx it need not match the port we are forwarding to.

Source: xxx.xxx.xxx.xxx:8888 -- forwarded to -> 192.168.0.2:80

Port Forwarding using Iptables

Since I have been using 2.4 kernel, I use iptables for firewall and NAT. So these are the Iptable rules required for port forwarding xxx.xxx.xxx.xxx:8888 to 192.168.0.2:80 .

/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 -d xxx.xxx.xxx.xxx
		 --dport 8888 -j DNAT --to 192.168.0.2:80
/sbin/iptables -A FORWARD -p tcp -i eth0 -d 192.168.0.2 --dport 80 -j ACCEPT

How to add custom rules to Bastille firewall

Since I trust Bastille firwall script to generate the correct iptable scripts for my server, I wanted to keep those scripts but add these custom port forwarding rules to supplement/extend it.

But the version of Bastille on my machine ( 1.2.0 ) does not support port forwarding, and does not had a way of adding custom scripts to it. Posting the question to Bastille mailing list generated these prompt responses from Peter Watkins, core developer of Bastille. ( See the complete thread )

Following Peter's advice I upgraded Bastille to the latest version, without any problem. The new version regenerated all the scripts with my old rules intact.

And with the new Bastill in place and working fine doing all the firewall filteringa nd NAT. I made the following changes to add a supplemental script, portforward.sh for my custom port forwarding rules.

Created the directories for supplemetal script. ( as explained in the comments at portforward.sh )

/etc/Bastille/firewall.d/pre-chain-split.d/

Created portforward.sh with working portforwarding rules, following the sample script from Peter.
[ Please note: The ipchains rules in portforward.sh are untested. I have left it there from Peter's sample script for completeness. ]

In portforward.sh all you have to do is specify the portforwarding source and destination IP addresses and ports with the ethernet interface name ( "eth0" if you have only one interface ) and the protocol type ( "tcp" in this case ).

IP_FORWARDS="eth0-xxx.xxx.xxx.xxx-8888-tcp-192.168.0.2-80"

Also you can have multiple port forwaring specified like:

IP_FORWARDS="eth0-xxx.xxx.xxx.xxx-8888-tcp-192.168.0.2-80 
		eth0-xxx.xxx.xxx.xxx-2222-tcp-192.168.0.2-22"

This will be parsed and stored into varibles down the script and used in the following Iptable calls to generate the rules. [ NOTE: The rules need to be on a single continuous line, I have broken it down to two lines for readability ]

${IPTABLES} -t nat -A PREROUTING -p $fw_inproto -i $fw_iface 
   -d $fw_inaddr --dport $fw_inport -j DNAT --to $fw_outaddr:$fw_outport

${IPTABLES} -A FORWARD -p $fw_inproto -i $fw_iface 
   -d $fw_outaddr --dport $fw_outport -j ACCEPT

Which will translate to.

/sbin/iptables -t nat -A PREROUTING -p tcp -i eth0 -d xxx.xxx.xxx.xxx 
	--dport 8888 -j DNAT --to 192.168.0.2:80
/sbin/iptables -A FORWARD -p tcp -i eth0 -d 192.168.0.2 
   	--dport 80 -j ACCEPT

Now we can restart Bastille scripts to make this rules effective.

#/etc/rc.d/init.d/bastille-firewall start

Verify the rules by listing them.

# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  anywhere             xxx.xxx.xxx.xxxtcp dpt:ddi-tcp-1 to:192.168.0.2:80

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  192.168.0.0/16       anywhere
MASQUERADE  all  --  192.168.0.0/16       anywhere
MASQUERADE  all  --  192.168.0.0/16       anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
#
[ where "ddi-tcp-1", I assume corresponds to port 8888 ]

Verify the port forwaring works by connecting to the port from a machine outside the network.

Notes on this setup

The above rules work fine when you access from outside, but if you try to access the same port xxx.xxx.xxx.xxx:8888 from an internal machine, it will not work. But from the internal network you dont need the forwarding, since you can directly access the machine 192.168.0.2:80.



 
 
kishan@hackorama.com 04/05/02 12:06:15