This mini tutorial aims to setup a firewall on a machine that will connect to the Internet, and perhaps serve some web pages on its web server. This mini tutorial was actually inspired by one of the Appendices I’m writing for my thesis, particularly the details of how I setup my firewall in the machine I’ll be using. To setup a firewall as a NAT gateway, you can consult this site, but this tutorial will still benefit you since almost all the things/commands we’ll be doing here can be applied to NAT firewall setup. For protection from malicious attackers breaking into the system and/or causing havoc, a firewall is definitely a must. To implement a firewall system, the iptables  utility created by Paul Russell was used. Paul Russell founded the Netfilter Core Team which provides an extensive manual and documentation for iptables. The iptables utility is usually the standard built in firewall utility in Linux distributions with kernel versions of 2.4 or higher. The network interface for the machine is given the name eth0.
In executing the commands (unless otherwise stated, which would mean it’s a configuration file and a ‘#’ means a comment) below preceded by a ‘#’ means either you need to be root or you’re using sudo to enter the commands.
A bit of warning though: if you’re setting up the following rules on a remote machine (and this is your first time using iptables) on which you don’t have any physical reach/contact (e.g. manually rebooting the machine), it’s best if you add this command on your crontab :
*/15 * * * * /sbin/iptables -F
Which ‘flushes’ or removes all iptables rules you’ve made every 15 minutes in case you get locked out of your remote machine when you’re experimenting and you make a mistake. That way, even if you get disconnected from your machine because of a mistaken rule you made, you can login again after the crontab job flushes all your rules. Of course this won’t be of much use if the machine your configuring iptables for is the local machine (or you have physical contact with the machine).
Appends one or more rules to the end of the statement.
-I chain rulenum
Inserts chain at the location rulenum. Useful when one wants a rule
to supercede those before it.
Lists all the rules in the current chain.
Flush all the rules in the current chain, basically deleting the firewall
Table 1 – basic iptables commands 
Specify protocol for the rule to match e.g. icmp, tcp, udp
Specifies a certain address or network to match
This tells what to do with the packet if it matches the specifications.
The valid options for target are
DROP – Drop packet/s without any further action.
REJECT – Drop packet/s and send an error packet in return.
ACCEPT – Allow packets to enter the network interface
Table 2 – iptables basic rules specifications 
Initially, iptables rules are empty. Rules are the the firewall’s configuration/s, denying and/or accepting certain packets, for example. Checking the rules before any has been added:
# iptables -nvLChain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0K packets, 0 bytes) pkts bytes target prot opt in out source destination
Which basically says no rules have been applied yet. If in case there were previous rules and one wishes to start with a clean slate, the command
# iptables -F
Flushes the rules out. Careful notice has to be given to the uppercase and lowercase commands since iptables is [sic] case-sensitive.
The following setup is for a single non-gateway non-NAT (Network Address Translation) machine. All packets received by the network interface eth0 with destination address being the machine’s IP address pass through the INPUT chain/rule. Only wanted packets must be accepted to avoid attackers or DOS (Denial of Serivce) attacks et al.
First, create custom chains/rules which will become clearer as more chains/rules are given:
# iptables -N open # iptables -N interfaces
Accept ICMP messages such as pings:
# iptables -A INPUT -p icmp -j ACCEPT
Next is the rule that will make sure no traffic that belongs to already established connections will be dropped. This rule can be done by matching a given state of a connection. A connection can have one of the four states: ESTABLISHED, RELATED, NEW and INVALID. All packets/connections that are in state ESTABLISHED or RELATED should be accepted, turning the firewall into a “stateful firewall”:
# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
Since not all incoming connections will be denied, more custom chains are put into place for the open and interfaces that have been created earlier:
# iptables -A INPUT -j interfaces # iptables -A INPUT -j open
Based on the last two rules, drop all traffic that hasn’t been explicitly accepted by the previous rules. TCP packet connections are denied with a tcp-reset. UDP packets are answered with an ICMP message. This method of replying to connections imitates Linux’s default behaviour:
# iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset # iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
All protocols other than TCP, UDP and ICMP are dropped (unless they manage to match the state match from previous chains). This rule is done by setting the policy for the INPUT chain to DROP
# iptables -P INPUT DROP
Since the machine won’t function as a router/forwarding device, we set the policy of the FORWARD chain to DROP:
# iptables -P FORWARD DROP
There is no need to filter any outgoing traffic. Set the OUTPUT policy to ACCEPT.
# iptables -P OUTPUT ACCEPT
Use the interfaces chain to accept any traffic from trusted interfaces. The following rule is absolutely necessary:
# iptables -A interfaces -i lo -j ACCEPT
The previous rule accepts every traffic from the loopback interface, lo, which is necessary for many applications to work properly. Incoming connections on other interfaces will be denied, unless they hit another exception in the open chain.
The open chain contains rules for accepting incoming connections on specific ports/protocols. To accept ssh (default port is 22) connections on every interface
# iptables -A open -p tcp --dport 22 -j ACCEPT
Limited machines can be allowed to connect to port 22 by modifying the /etc/hosts.allow file. The local machine uses the port 8094 (arbitrarily chosen) to make ssh connections instead of the default port (default ssh port is 22):
# iptables -A open -i eth0 -p tcp --dport 80 -j ACCEPT
Next, force SYN packet checking. Make sure NEW incoming tcp connections are SYN packets (synchronization); otherwise drop them:
# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
Now, force fragmented packets to be checked. Packets with incoming fragments are dropped.
#iptables -A INPUT -f -j DROP
Incoming malformed Christmas tree packets  are dropped:
#iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
As well as incoming malformed NULL packets:
#iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
To prevent spoofed traffic , block reserved private networks coming from the Internet
#iptables -I INPUT -i eth0 -s 10.0.0.0/8 -j DROP #iptables -I INPUT -i eth0 -s 172.16.0.0/12 -j DROP #iptables -I INPUT -i eth0 -s 192.168.0.0/16 -j DROP #iptables -I INPUT -i eth0 -s 127.0.0.0/8 -j DROP
The following line is added to the /etc/sysctl.conf configuration file to enable source address verification which is built into the Linux kernel itself.
net.ipv4.conf.all.rp_filter = 1
In order to further lessen the network traffic that will be experienced by the machine’s network interface (eth0), specific types of unwanted ICMP packets  will be dropped
iptables -I INPUT -p icmp --icmp-type redirect -j DROP#iptables -I INPUT -p icmp --icmp-type router-advertisement -j DROP#iptables -I INPUT -p icmp --icmp-type router-solicitation -j DROPiptables -I INPUT -p icmp --icmp-type address-mask-request -j DROP#iptables -I INPUT -p icmp --icmp-type address-mask-reply -j DROP
Now, the rules should be saved. Different Linux distributions have different ways of saving iptables rules. The following comes from an Arch Linux setup. The configuration file /etc/conf.d/iptables is edited first for further security:
# Configuration for iptables rules IPTABLES=/usr/sbin/iptables IPTABLES_CONF=/etc/iptables/iptables.rules IPTABLES_FORWARD=0 # disable IP forwarding!!!
And then arbitrarily specify a filename such as iptables.rules where the rules will be saved according to the previous configuration file.
Now, save the rules with the command
# /etc/rc.d/iptables save
and to make sure the rules are loaded when the machine is rebooted, edit the /etc/rc.conf file, iptables should be added preferably before ‘network’.
DAEMONS=(... iptables network ...)
For other Linux distros (Debian, Ubuntu, Fedora etc), issuing the command
iptables-save > /etc/firewall.conf
saves all your iptables rules on the arbitrary file firewall.conf. Then after a reboot, you can do a
iptables-restore < /etc/firewall.conf
To restore your iptables rules. Or you can just create a simple shell script like so
echo "#!/bin/sh" > /etc/network/if-up.d/iptables echo "iptables-restore < /etc/firewall.conf" >> /etc/network/if-up.d/iptables chmod +x /etc/network/if-up.d/iptables
To let ifup load your rules automatically for you. Run the previous shell script during boot-up of course.
Now you might want to log the packets that are dropped. A quick and simple way to log those packets on the file /var/log/syslog is this:
#iptables -I INPUT 5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
which is pretty self-explanatory.
Comments/suggestions/questions/reactions are welcome as long as they come in a calm and ruly way (^)__(^)
 T. Howlett, Open Source Security Tools: Practical Applications for Security. Prentice Hall Professional Technical Reference, 2005
 P. Russell et al. Iptables manuals and documentations. http://www.netfilter.org/documentation/index.html (January 2008 )
 H. Bidgoli. The Internet Encyclopedia. John Wiley and Sons, 2004
 M. Freire and M. Pereira. Encyclopedia of Internet Technologies and Applications. Information Science Reference, 2008
 Internet Assigned Numbers Authority. ICMP type numbers RFC list. http://www.iana.org/assignments/icmp-parameters (January 2008 )