HOWTOs :: Firewall rules for a dual-homed gateway server
Last modified on Wednesday May 25 2005 @ 20:59:15
This HOWTO shows how to get computers on your LAN to access the Internet through a
dual-homed gateway server. It is divided into the following sub-sections:
The scenario is as follows: You have one static IP address issued by your ISP, but you have
several computers that you want to have online. One way of solving this issue, is by installing
a dual-homed gateway server as shown in the figure below.
Part 1: Getting your private hosts online (IP Masquerading)
You need to have IPTables installed and IP forwarding enabled in your kernel in order to get
this to work. Check if your kernel has this enabled by typing the following command:
cat /proc/sys/net/ipv4/ip_forward
If it has a value of 0, IP forwarding is not enabled in your kernel. Go into your kernel
sources (/usr/src/linux) and do a 'make menuconfig' and configure as follows:
In Networking Options
<*> Packet socket
...
[*] Network packet filtering (replaces ipchains)
...
<*> Unix domain sockets
[*] TCP/IP networking
...
<M> IP: tunneling
Then, under Networking Options --> IP: Netfilter Configuration
<M> Connection tracking (required for masq/NAT)
...
<M> IP tables support (required for filtering/masq/NAT)
...
<M> MAC address match support
<M> Packet type match support
...
<M> Connection state match support
<M> Connection tracking match support
...
<M> Packet filtering
<M> REJECT target support
...
<M> Full NAT
<M> MASQUERADE target support
Now, compile the kernel. Refer to the Kernel HOWTO for further
information on this topic. Install your new kernel and reboot with it.
You now need to install the IP Tables tools. Install this on your Gentoo
distribution by executing the following command:
emerge net-firewall/iptables
If you don't run Gentoo, you can download the source at www.iptables.org.
Refer to the installation documents in the package for how to compile and install IPTables.
After IPTables is installed, make sure they start next time you boot your gateway server by
typing:
rc-update add iptables default
Now, we need to customize the firewall, so you need to create a script that enables and
disables your firewall rules. Open up your favourite editor and create a new file, e.g.
/root/firewall.sh that looks like this:
#!/bin/bash
################################################################################
# script to open the appropriate ports in the firewall
################################################################################
IPTABLES="/sbin/iptables"
IPTABLES_SAVE="/sbin/iptables-save"
IPTABLES_SAVEFILE="/var/lib/iptables/rules-save"
### open: ssh, http, https, X forward (range) ###
SERVICES="22 80 443"
SERVICES_RANGE_START="6010"
SERVICES_RANGE_END="6011"
EXT_NIC="eth0"
INT_NIC="eth1"
INT_IP="192.168.50.0/255.255.255.0"
if [ "$1" = "start" ]
then
echo "Starting firewall..."
### set default rules (DENY, ACCEPT) ###
${IPTABLES} -P INPUT DROP
${IPTABLES} -P FORWARD ACCEPT
${IPTABLES} -P OUTPUT ACCEPT
### allow all incoming packets from internal net ###
${IPTABLES} -A INPUT -i ! ${EXT_NIC} -j ACCEPT
### allow incoming realated packets on external NIC ###
${IPTABLES} -A INPUT -i ${EXT_NIC} -m state --state ESTABLISHED,RELATED -j ACCEPT
### allow certain services ###
echo -n "* opening ports: "
for x in ${SERVICES}
do
echo -n "$x "
${IPTABLES} -A INPUT -i ${EXT_NIC} -p tcp --dport $x -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
${IPTABLES} -A INPUT -i ${EXT_NIC} -p udp --dport $x -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
done
echo ""
### allow certain services : range ###
echo "* opening port range: ${SERVICES_RANGE_START} - ${SERVICES_RANGE_END}"
for port in $(seq $SERVICES_RANGE_START $SERVICES_RANGE_END); do
${IPTABLES} -A INPUT -i ${EXT_NIC} -p tcp --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
${IPTABLES} -A INPUT -i ${EXT_NIC} -p udp --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
done
### enables masquerading of internal hosts ###
echo "* enabling ip forwarding in kernel"
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "* enabling masquerading of internal hosts"
${IPTABLES} -t nat -P PREROUTING ACCEPT
${IPTABLES} -t nat -P POSTROUTING ACCEPT
${IPTABLES} -t nat -P OUTPUT ACCEPT
${IPTABLES} -t nat -A POSTROUTING -o ${EXT_NIC} -j MASQUERADE
#### opening ports for ICMP ###
${IPTABLES} -A INPUT -p icmp -j ACCEPT
################################################################################
### enable SSH forwarding to internal IP address ###
################################################################################
#
# begin configuration
#
# port to listen to on the outside
LISTEN_ON_PORT=7000
# internal IP address to the inside desktop
FORWARD_TO_IP="xxx.xxx.xxx.xxx"
# forward SSH to port 22
FORWARD_TO_PORT=22
#
# end configuration
#
echo "* forwarding incoming requests on port $LISTEN_ON_PORT to $FORWARD_TO_IP:$FORWARD_TO_PORT"
#
# handle port forwarding for SSH2 to schweetie
#
${IPTABLES} -t nat -I PREROUTING -i ${EXT_NIC} -p tcp --dport ${LISTEN_ON_PORT} -j DNAT --to ${FORWARD_TO_IP}:${FORWARD_TO_PORT}
#
# Enable forwarding rules to allow the above port forwarding connections to progress through
#
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p tcp -d ${FORWARD_TO_IP}/32 --dport ${FORWARD_TO_PORT} -j ACCEPT
### end forwarding ssh rules
################################################################################
################################################################################
#### enable emule forwarding on router ###
################################################################################
### from xmule.org forum ###
#
# This script assumes that there is a single machine behind an iptables
# enabled gateway which is running an emule or lmule client. If you are
# running a client on the same machine for which the firewall is also
# enabled, the rules will be based in the INPUT and OUTPUT tables instead of
# the nat and FORWARD tables.
#
#
# begin configuration
#
# Default server port
SERVERPORT=4661
# The port used by our client
CLIENTPORT=4666
#CLIENTPORT=4662
# The port used by our client for the extended emule protocol
EXCHANGEPORT=4672
# The port used by our client for the web server
WEBPORT=4771
# The network address of our machine behind this gateway
EMULE_CLIENTIP="xxx.xxx.xxx.xxx"
#
# end configuration
#
echo "* forwarding incoming eMule/lMule packets (ports $SERVERPORT, $CLIENTPORT, $EXCHANGEPORT, $WEBPORT) to $EMULE_CLIENTIP"
#
# Handle port forwarding for our client behind this gateway
#
${IPTABLES} -t nat -I PREROUTING -i ${EXT_NIC} -p tcp --dport ${CLIENTPORT} -j DNAT --to ${EMULE_CLIENTIP}:${CLIENTPORT}
${IPTABLES} -t nat -I PREROUTING -i ${EXT_NIC} -p udp --dport ${CLIENTPORT} -j DNAT --to ${EMULE_CLIENTIP}:${CLIENTPORT}
${IPTABLES} -t nat -I PREROUTING -i ${EXT_NIC} -p udp --dport ${EXCHANGEPORT} -j DNAT --to ${EMULE_CLIENTIP}:${EXCHANGEPORT}
${IPTABLES} -t nat -I PREROUTING -i ${EXT_NIC} -p tcp --dport ${EXCHANGEPORT} -j DNAT --to ${EMULE_CLIENTIP}:${EXCHANGEPORT}
${IPTABLES} -t nat -I PREROUTING -i ${EXT_NIC} -p tcp --dport ${WEBPORT} -j DNAT --to ${EMULE_CLIENTIP}:${WEBPORT}
#
# Enable forwarding rules to allow the above port forwarding connections to progress through
#
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p tcp -d ${EMULE_CLIENTIP}/32 --dport ${CLIENTPORT} -j ACCEPT
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p udp -d ${EMULE_CLIENTIP}/32 --dport ${EXCHANGEPORT} -j ACCEPT
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p tcp -d ${EMULE_CLIENTIP}/32 --dport ${WEBPORT} -j ACCEPT
#
# Enable forwarding rules to allow our internal client to get to allowed ports
#
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p tcp -s ${EMULE_CLIENTIP}/32 --dport ${SERVERPORT} -j ACCEPT
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p tcp -s ${EMULE_CLIENTIP}/32 --dport ${CLIENTPORT} -j ACCEPT
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p udp -s ${EMULE_CLIENTIP}/32 --dport ${EXCHANGEPORT} -j ACCEPT
${IPTABLES} -A FORWARD -i ${EXT_NIC} -p tcp -s ${EMULE_CLIENTIP}/32 --dport ${WEBPORT} -j ACCEPT
### end emule rules
################################################################################
#
# Finally, allow any established or related connections on to the external interface be forwarded on
#
$IPTABLES -A FORWARD -i ${EXT_NIC} -m state --state ESTABLISHED,RELATED -j ACCEPT
# end start
elif [ "$1" = "stop" ]
then
echo "Stopping firewall..."
${IPTABLES} -F INPUT
${IPTABLES} -F FORWARD
${IPTABLES} -P INPUT ACCEPT
# turn off NAT/masquerading, if any
${IPTABLES} -F -t nat
# ${IPTABLES} -L -v
# ${IPTABLES} -L -v -t nat
elif [ "$1" = "save" ]
then
echo "Saving IP Table rules to ${IPTABLES_SAVEFILE}"
${IPTABLES_SAVE} > ${IPTABLES_SAVEFILE}
else
echo "invalid parameter"
echo "Usage: firewall.sh "
fi
##############################################################################o
#EOF
|
Save your file, and exit the editor. Now, make sure you have the executable flags on the
firewall.sh script:
chmod 700 /root/firewall.sh
Great! Start your firewall by typing:
/root/firewall.sh start
TODO: explain how to set up internal routing (DHCP/static) here...
You should now be able to get online with the internal hosts. If everything works as
expected, you want to save your firewall rules so that they start up automatically next time you
boot your server. Do this by typing:
/root/firewall.sh save
WARNING: The save command is customized for the Gentoo
distribution, and is not guaranteed to work with other distros. Figure out where IP Tables saves
its rules in your distro, and change the IPTABLES_SAVEFILE variable in the
script above.
Your rules are now saved and everything will start automatically next time you boot your
gateway server. :D
Part 2: Opening for selected services on your gateway server
The following lines in the script above determine the services
that are open to the world on the gateway server:
### open: ssh, http, https, X forward (range) ###
SERVICES="22 80 443"
SERVICES_RANGE_START="6010"
SERVICES_RANGE_END="6020"
|
Change them to fit your system, and restart your firewall by typing:
/root/firewall.sh stop; /root/firewall.sh start
Now, test the firewall by opening a connection to either of the opened services. If everything works ok, save the firewall rules:
/root/firewall.sh save
Part 3: SSH-forwarding to an internal host through your gateway server
The scenario is as follows: You want to access a service (e.g. SSH) on one of the internal hosts
from the outside world as depicted in the figure below.
The trick is to have the firewall (IPTables) to forward any connection attempt to a given
port (e.g. 7000 as in the image) on the gateway server to an internal IP address. In order to
enable forwarding to an internal host on your private network, edit the following configuration
and customize it to your environment:
################################################################################
### enable SSH forwarding to internal IP address ###
################################################################################
#
# begin configuration
#
# port to listen to on the outside
LISTEN_ON_PORT=7000
# internal IP address to the inside desktop
FORWARD_TO_IP="192.168.0.12"
# forward SSH to port 22
FORWARD_TO_PORT=22
#
# end configuration
#
|
Now, restart your firewall by typing:
/root/firewall.sh stop; /root/firewall.sh start
Now, test the new config by SSH-ing in from an external host:
ssh -o "Port 7000" 218.121.12.10
Verify that you got forwarded to the internal host. If everything works ok, remember to save the firewall rules:
/root/firewall.sh save
Part 4: Get eMule/lMule/xMule to run inside your private network
The goal of this part is to get eMule/lMule/xMule to run on one of your internal hosts
without getting the LowID that eMule/lMule/xMule gives you if no external connections are
allowed. The scenario is as the figure shows:
The section of the firewall script above that needs to be
customized to enable emule on the inside of our gateway is as follows:
### from xmule.org forum ###
#
# This script assumes that there is a single machine behind an iptables
# enabled gateway which is running an emule or lmule client. If you are
# running a client on the same machine for which the firewall is also
# enabled, the rules will be based in the INPUT and OUTPUT tables instead of
# the nat and FORWARD tables.
#
#
# begin configuration
#
# Default server port
SERVERPORT=4661
# The port used by our client
CLIENTPORT=4662
# The port used by our client for the extended emule protocol
EXCHANGEPORT=4672
# The port used by our client for the web server
WEBPORT=4771
# The network address of our machine behind this gateway
EMULE_CLIENTIP="192.168.0.11"
#
# end configuration
#
|
Now, restart your firewall by typing:
/root/firewall.sh stop; /root/firewall.sh start
The next step is to configure your eMule/lMule/xMule client to match the configuration set
here. Go into the preferences and set the ports as specified in the firewall rules.
Verify that you don't get LowID after restarting your eMule/lMule/xMule client. If everything
works ok, remember to save the firewall rules:
/root/firewall.sh save
|