Machine protection with iptables firewall

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 [1] 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 [2]

rule specification


-p protocol

Specify protocol for the rule to match e.g. icmp, tcp, udp

-s address/mask!port

Specifies a certain address or network to match

-j target

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 [2]

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 -nvL
Chain 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 [3] 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 [4], block reserved private networks coming from the Internet

#iptables -I INPUT -i eth0 -s -j DROP #iptables -I INPUT -i eth0 -s -j DROP #iptables -I INPUT -i eth0 -s -j DROP #iptables -I INPUT -i eth0 -s -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 [5] 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 DROP
iptables -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 (^)__(^)


[1] T. Howlett, Open Source Security Tools: Practical Applications for Security. Prentice Hall Professional Technical Reference, 2005

[2] P. Russell et al. Iptables manuals and documentations. (January 2008  )

[3] H. Bidgoli. The Internet Encyclopedia. John Wiley and Sons, 2004

[4] M. Freire and M. Pereira. Encyclopedia of Internet Technologies and Applications. Information Science Reference, 2008

[5] Internet Assigned Numbers Authority. ICMP type numbers RFC list. (January 2008  )

Tags: , , , , , , , , , , ,

7 Responses to “Machine protection with iptables firewall”

  1. | The social sites' most interesting urls Says:

    Protect your machine with iptables firewall! |

    A clear, quick, concise, and academic (partly due to my thesis) setup of t

  2. junbert Says:



  3. f241vc15 Says:

    No problem. Glad to share what I know in Linux.

  4. nitinr0cks Says:

    Thanks !

  5. nitinr0cks Says:

    i bookmarked it

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: