Configuring a Linux Firewall using Iptables
Overview
This page will describe how I set up the IPTable Firewall Scripts for Linux 2.4 or later. This is not a How-To, it will not attempt to teach you anything about IPTables, these are just scripts you can use that I know to work, and work well. These scripts are what I usually use when setting up firewall computers.
The Scripts
I use 3 different scripts to initiate/deactivate the firewall services for Linux.
A pre.iptable script that will deny everything that comes in on the Internet. I initiate this before any network interfaces come up so when the network comes up it is protected in case, for any reason, the main firewall script fails to initialize.
A rc.firewall script as the main script to initiate all the firewall and masquerading services needed to run on the network. Basically what this script will do is allow anyone on the internal network to access all the services of the internet, but anyone from the outside cannot access the internal network, unless someone on the internal network initiates the communication.
Finally a script to flush all the IPTables at shutdown, or whenever you make changes to the main script.
In order for IPTables to work properly you must either compile the appropriate items into the kernel, or compile them as a module. I won't go over how to compile a Kernel here, as there are many guides already available, but the following is a list of what you will need in order for these scripts to work. Most modern Linux Distributions already compile support for iptables into the default Kernel, so these scripts should just work.
Under Linux Kernel ver 2.4.9 the first 2 are under Networking Options, the rest are under IP:Netfilter Configuration within Networking Options.
- Packet Socket (CONFIG_PACKET)
- Network Packet Filtering (CONFIG_NETFILTER)
- Connection Tracking (CONFIG_IP_NF_CONNTRACK)
- FTP Protocol Support (CONFIG_IP_NF_FTP)
- IP Tables Support (CONFIG_IP_NF_IPTABLES)
- Limit Match Support (CONFIG_IP_NF_MATCH_LIMIT)
- Connection State Match Support (CONFIG_IP_NF_MATCH_STATE)
- Packet Filtering (CONFIG_IP_NF_FILTER)
- Full NAT (CONFIG_IP_NF_NAT)
- Masquerade Target Support (CONFIG_IP_NF_TARGET_MAQUERADE)
- Log Target Support (CONFIG_IP_NF_TARGET_LOG)
The pre.iptables Script
################################################################################ #!/bin/sh ######### Script to start firewall support before ethernet card initialize echo "Starting Pre-Firewalling..." iptables -F iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP ################################################################################
You can download my pre.iptables script here.
As you can see, there really isn't much to this script. All it basically does is Drops all traffic going in or coming out of the Linux box. Some people would consider this extremely paranoid behavior, but this will secure the network in case the rc.firewall script does not initialize.
To use this script, what I do is to copy it to the /etc/rc.d/init.d directory, make it executable (chmod +x pre.iptables) then link it to whatever runlevel you want to run it under. The following command explains the symbolic link.
ln -s /etc/rc.d/init.d/pre.iptables /etc/rc.d/rc3.d/S01preiptables
The flsh.iptables Script
################################################################################ #!/bin/sh ######### Script to flush the firewall tables echo "Flushing Firewall and Deleting Chains" iptables -F icmp_packets iptables -F tcp_packets iptables -F udpincoming_packets iptables -F allowed iptables -F iptables -X icmp_packets iptables -X tcp_packets iptables -X udpincoming_packets iptables -X allowed iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP ################################################################################
You can download our flsh.iptables script here.
All this script does is to get rid of all the custom tables you create with my rc.firewall script, as well as making the default action to Drop all traffic on the Linux box. You should use this script when you shut down the computer. You should also use this script whenever you make any changes to the rc.firewall script so that you start with a clean slate. The following is a command to allow this script to run every time you shutdown your computer. You should also make a symbolic link to /usr/bin or anywhere else in your path to allow for easy flushing of the firewall.
ln -s /etc/rc.d/init.d/flsh.iptables /etc/rc.d/rc0.d/S01flshiptables ln -s /etc/rc.d/init.d/flsh.iptables /usr/bin/flsh.iptables
The rc.firewall Script
#!/bin/sh ################################### # # IP Firewall script for # PCC-Services # Author: Mike Petersen # ################################### # Configuration Options EXTERNAL_INTERFACE="eth0" LOOPBACK_INTERFACE="lo" LAN_INTERFACE_1="eth1" # Get the IP Addresses for the network cards IPADDR=`/sbin/ifconfig $EXTERNAL_INTERFACE | grep -i "addr:" | cut -f2 -d: | cut -f1 -d " "` LAN_IPADDR=`/sbin/ifconfig $LAN_INTERFACE_1 | grep -i "addr:" | cut -f2 -d: | cut -f1 -d " "` LOCALHOST_IP="127.0.0.1/32" LAN_BCAST_ADDRESS="10.0.0.255" # Adjust LAN_BCAST_ADDRESS to suit your network ########## echo "Starting Firewalling... " echo "1" > /proc/sys/net/ipv4/ip_forward iptables -F ########## Enable Masquerading iptables -t nat -A POSTROUTING -o $EXTERNAL_INTERFACE -j MASQUERADE iptables -A FORWARD -i $LAN_INTERFACE_1 -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT ########## Log errors when masquerading iptables -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT FORWARD packet died: " ########## Set default policies iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP iptables -A INPUT -i $LOOPBACK_INTERFACE -j ACCEPT iptables -A OUTPUT -o $LOOPBACK_INTERFACE -j ACCEPT ########## Create Seperate Chains for ICMP, TCP and UDP to traverse iptables -N icmp_packets iptables -N tcp_packets iptables -N udpincoming_packets ########## The Allowed Chain for TCP connections iptables -N allowed iptables -A allowed -p TCP --syn -j ACCEPT iptables -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A allowed -p TCP -j DROP ########## ICMP rules (Internet Control Message Protocol) iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type 0 -j ACCEPT iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type 3 -j ACCEPT iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type 5 -j ACCEPT iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT ########## TCP rules (Transmission Control Protocol) ### FTP port iptables -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed ### SSH port iptables -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed ### SMTP Mail Server port iptables -A tcp_packets -p TCP -s 0/0 --dport 25 -j allowed ### HTTP port iptables -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed ### POP3 port iptables -A tcp_packets -p TCP -s 0/0 --dport 110 -j allowed ### IRC port iptables -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed ### IMAP port iptables -A tcp_packets -p TCP -s 0/0 --dport 143 -j allowed ### No-ip DNS services port iptables -A tcp_packets -p TCP -s 0/0 --dport 8245 -j allowed ### Example of Port Forwarding using Bittorrent Ports iptables -t nat -A PREROUTING -d $IPADDR -p tcp -m tcp --dport 6881 -j DNAT --to-destination 10.0.0.76 ########## UDP ports (User Datagram Protocol) iptables -A udpincoming_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT iptables -A udpincoming_packets -p UDP -s 0/0 --source-port 123 -j ACCEPT iptables -A udpincoming_packets -p UDP -s 0/0 --source-port 2074 -j ACCEPT iptables -A udpincoming_packets -p UDP -s 0/0 --source-port 4000 -j ACCEPT iptables -A udpincoming_packets -p UDP -s 0/0 --source-port 143 -j ACCEPT ########## Prerouting chain - Check for obviously spoofed IP's iptables -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 192.168.0.0/16 -j DROP iptables -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 10.0.0.0/8 -j DROP iptables -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 172.16.0.0/12 -j DROP ########## INPUT chain # Establish the basic Input chain ########## and filter the packets onto the correct chains. iptables -A INPUT -p ICMP -i $EXTERNAL_INTERFACE -j icmp_packets iptables -A INPUT -p TCP -i $EXTERNAL_INTERFACE -j tcp_packets iptables -A INPUT -p UDP -i $EXTERNAL_INTERFACE -j udpincoming_packets iptables -A INPUT -p ALL -i $LAN_INTERFACE_1 -d $LAN_BCAST_ADDRESS -j ACCEPT iptables -A INPUT -p ALL -d $LOCALHOST_IP -j ACCEPT iptables -A INPUT -p ALL -d $LAN_IPADDR -j ACCEPT iptables -A INPUT -p ALL -d $IPADDR -m state --state ESTABLISHED,RELATED -j ACCEPT ########## ENABLE TO LOG ERRORS iptables -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT INPUT packet died: " ########## OUTPUT chain # Establish the basic Output chain ########## and filter them onto the correct chain iptables -A OUTPUT -p ALL -s $LOCALHOST_IP -j ACCEPT iptables -A OUTPUT -p ALL -s $LAN_IPADDR -j ACCEPT iptables -A OUTPUT -p ALL -s $IPADDR -j ACCEPT ########## ENABLE TO LOG ERRORS iptables -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
You can download our rc.iptables script here.
In order for this script to work properly, you must have a permanent Internet Address assigned to you. It should be relatively simple to implement a DHCP address, which we may add to this page at a later date.
To make this automatically run at startup you could make a symbolic link from /etc/rc.d/init.d/rc.iptables to /etc/rc.d/rc3.d/S15iptables.
As you can see in the script, I have allowed certain services to access to the firewall computer, like the http or ssh servers. You can add your own services that you want to allow access to, just experiment.
Below is a command to allow Quake 3 to work, which we received from oberon@umich.edu. I haven't got a chance to use the commands for quake 3, so use at your own peril. (substitute your workstation IP address where <LAN address> is. The rc.iptables scipt above already has a section that shows you how to forward bittorrent ports.
iptables -t nat -A PREROUTING -d $IPADDR -p tcp -m tcp --dport 27960 -j DNAT --to-destination <LAN address> iptables -t nat -A PREROUTING -d $IPADDR -p udp -m udp --dport 27960 -j DNAT --to-destination <LAN address>

