May 15

IP Tables (explanation in efficiency)



IP Tables are a set of rules that you define to allow or reject network traffic from entering into your system. The ones that I am referring to are for a UNIX (Linux) type system.  As a default, the IP Tables specify what’s called an ‘implicit deny’ which means that it will deny any network traffic, thereby dropping any packets that come through. By specifying the type of traffic you would like to allow into your system, you are effectively creating a single virtual door that can only be opened if the conditions are correct.

IP Tables exist but are not necessarily implemented in the most efficient fashion by novice users. Upon initial configuration of my new Fedora server, I made the server accept traffic for all of the types that I was familiar with.  I did this because I didn’t quite understand how IP Tables work.  Now that time has gone by and I’ve gained a better understanding (and respect) for  these important rules, I’ve drastically changed the way that I implement IP Tables, and that theory of efficient implementation is what I’ll talk about in this writing.


Each program or application that is installed on your UNIX box will most likely need to talk to someone or something else in order to be effective. If that application is simply talking to the local machine, it is assumed that you installed that application and therefore trust the work that it is doing. If that application has to reach outside of the boundaries of your local machine to get information, that’s when you’ll have to decide which traffic you’d like to let into your system in order to make your application effective.

Based on the programs that we have running on the machine, we know the type of traffic that will be expected at the front door. Needless to say, if information comes to the machine that shouldn’t be there, we want to get rid of it before it can do us any harm. That’s where the IP Tables come into play. The IP Tables service allows us to put conditions in place before the door can be opened.

NOTE: Don’t think of these conditions as keys that will open doors. That is inaccurate and can lead you down the wrong path.


Conditional statements are a set of rules put in place that must be met before something else happens. In the case of our IP Tables, the rules will be looking for the type of network traffic, the source that it’s coming from, the destination that it’s going to, and finally what we intend to do with it.  As a baseline, there is something to keep in mind when writing your rules.  The right implementation for IP Tables is to allow only the essentials; the wrong implementation is to allow everything.

There are plenty of ways that these rules can be written, but as a novice, you’re only looking for one… whichever way makes it work.  When I did this for the first time, I searched online, I posted in forums, and I also used chat rooms to try to figure out what to type into the command prompt to make this work.  In the end, the simplest way to get my IP Tables up and running was to keep it simple.  The resultant command yielded the least amount of conditions with the most amount of acceptable traffic being allowed through the door.  Here was the first IP Tables command that I ever wrote:

$ sudo iptables -I INPUT -m tcp -p tcp –dport http -j ACCEPT

This entry in the command prompt yields the following rule in the IP Table:

ACCEPT    tcp    —    anywhere    anywhere    tcp    dpt:http

The following explanation of the tags used in the command are taken directly from the IP Tables Manual page.  This page is found by typing ‘man iptables’ into your ssh window or terminal.

-I–insert chain [rulenumrule-specificationInsert one or more rules in the selected chain as the given rule number. So, if the rule number is 1, the rule or rules are inserted at the head of the chain. This is also the default if no rule number is specified.

-m or –match options, followed by the matching module name… iptables can use extended packet matching modules.

-p–protocol protocolThe protocol of the rule or of the packet to check. The specified protocol can be one of tcpudpudpliteicmpespahsctp or all, or it can be a numeric value, representing one of these protocols or a different one. A protocol name from /etc/protocols is also allowed. A “!” argument before the protocol inverts the test. The number zero is equivalent to all. Protocol all will match with all protocols and is taken as default when this option is omitted.

–destination-ports,–dport port[,port|,port:port]…Match if the destination port is one of the given ports. The flag –dports is a convenient alias for this option.

-j–jump targetThis specifies the target of the rule; i.e., what to do if the packet matches it. The target can be a user-defined chain (other than the one this rule is in), one of the special builtin targets which decide the fate of the packet immediately, or an extension (see EXTENSIONS below). If this option is omitted in a rule (and -g is not used), then matching the rule will have no effect on the packet’s fate, but the counters on the rule will be incremented.


When you type in the command that you just saw, it will insert that rule (based on the default for -I) as the new first rule that is reviewed when traffic tries to enter your system.  If you were to write another rule by entering the command again, that one would then be the first rule that is examined.  Therefore, you need to make a game plan for entering these commands.

To make your game plan, ask yourself a few questions:

  • What am I using this server for?
  • Is this server accessible by a Graphic User Interface (GUI) or only SSH?
  • Do I need to contact another server for information?

The answers to these questions will begin to give you a picture of the types of network traffic you can expect at your front door.  If you’re creating a web server, you’ll want to allow http and https (port 80 and 443) traffic through.  Other types of servers may require other types of traffic and those can be added into the rules as well.  In addition, if you’re using a GUI, you may be running third party programs requiring other traffic.  I personally prefer to do everything through SSH to make things much more simple.  Finally, you could be running a configuration of servers that all talk to each other.  If you must request information from an SQL database on another server, you would need to allow SQL traffic through the door.  So make sure you look at what will be required based on what you have installed.

Once you know which traffic you can expect at the door, you want to enter your rules based on the order in which you deem them most important.  IP Tables work by comparing the network traffic to the conditions in the first rule.  If those conditions are not met, the traffic will move on to the second rule to compare in the same way until it sees the final rule.  If it doesn’t follow the conditions of any of the rules, the traffic will be dropped.  If any one of the rule conditions were met, the traffic would have been allowed through.

With this understanding of how IP Tables work, you can see that the first rule the traffic is compared to should be reserved for the most frequent type of traffic that you’d like to allow in.  If it’s a web server, the http traffic should be first, followed by https, and so on.

In addition, you want to apply the principle of hardening to your IP Tables.  The bottom line is if you don’t need a particular type of traffic, don’t allow it (implicit deny).  In the case of my first implementation of IP Tables shown below, you can see that I chose to let mysql traffic through the door.  With the mysql server being hosted on the local machine, I do not need to use network traffic to get information.  Therefore, I’m not expecting mysql traffic at the front door.  If it shows up and I have a rule letting it in, that traffic could be malicious and should not be allowed in.  The easiest way to ensure this is to not create a rule to accept mysql traffic.


As you can see on the example below, my first implimentation was rather poor.  I opened up every type of traffic that I was familiar with and I executed the commands in the order that I thought of them.  Having thought of http and https first, it was the first in the pecking order of the commands inputted into the system.  In reality, if I would have had a game plan for IP Table implimentation, I would have executed the http command last because it will draw the most traffic.

In addition, I didn’t even need to execute a command allowing mysql traffic because the server resides on the local machine.  Therefore, I should have left that one out completely.

So overall, have a gameplan for the way that you want to impliment your IP Tables.  It will save you some effort in the future when you finally realize how to harden your tables and re-write rules.  In addition, become familiar with the iptables command.  You can use the manual page (‘$man iptables’) to see what each of the tags do, and can also use that manual to re-order your rules.  If you’re just trying to get your server up and running, this article will serve you well.  In the future, however, I recommend becoming very familiar with all of the functionality of IP Tables as it will be your first line of defense when it comes to malicious traffic showing up at your door!

…And always remember… WHAT IF AND WHY NOT?!?


$ sudo iptables -I INPUT -m tcp -p tcp –dport http -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport https -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport ssh -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport ftp -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport ftp-data -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport mysql -j ACCEPT


Chain INPUT (policy ACCEPT)

target prot opt source destination
ACCEPT tcp — anywhere anywhere tcp dpt:mysql
ACCEPT tcp — anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp — anywhere anywhere tcp dpt:ftp
ACCEPT tcp — anywhere anywhere tcp dpt:ssh
ACCEPT tcp — anywhere anywhere tcp dpt:https
ACCEPT tcp — anywhere anywhere tcp dpt:http
ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp — anywhere anywhere
ACCEPT all — anywhere anywhere
ACCEPT tcp — anywhere anywhere state NEW tcp dpt:ssh
REJECT all — anywhere anywhere reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)

target prot opt source destination
REJECT all — anywhere anywhere reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)

target prot opt source destination