In this tutorial we will discuss the very basics of iptables, which is the default firewall for most modern linux systems. There is many things you can do with iptables but to keep it simple we will discuss the basics. These include viewing current firewall rules, adding or removing rules to allow open ports, and a few other tidbits.  If your new to iptables this will be a good primer, but absolutely NOT the definitive guide to iptables.

Firewalld is the new front end controller for iptables which ships with most modern Red Hat based distros . For information on Firewalld see our article on "Introduction to Firewalld Basics". Or you can disable firewalld and use iptables.

Information on Uncomplicated Firewall (UFW), which is the default firewall for Ubuntu, can be found in our article "UFW (Uncomplicated Firewall) Basics".

Before we go any further I would like to stress the fact that iptables rules are instantly enforced.  This means it is possible to lock yourself out of the machine if you are doing this remotely.  If you are working on a machine via SSH be very careful.  It is suggested that you have physical access to the machine before changing any iptables rules unless you are sure you know what your doing.

Concepts - Default Chains & Rules

Iptables is an IP filtering firewall that basically inspects IP traffic and matches it to rules that you specify.  When IP packets match one of the specified rules, it then handles the packet with the action that you specify in the rule.  An important thing to understand about iptables is it reads the rules starting at the first rule, and works it’s way down.  Once a packet meets a rule it is processed and the next one is inspected.  For this reason it is always good to have a “catch all” in your iptables chain. We will talk more about a “catch all” later.

Iptables is made up of CHAINS, each chain holds RULES.

The default chains are:
NOTE: You can add user defined chains but these are the default.

  • INPUT (Incoming traffic to this machine)
  • FORWARD (Traffic going to or from a machine on the other side of this firewall)
  • OUTPUT (Outgoing traffic from this machine)

Rules are then placed inside these chains in order to allow or deny specific traffic.  There are three basic “ACTIONS” that a rule can take.  Other rules exist, but these are the basic and most commonly used actions.

  • ACCEPT (Allows the traffic through the firewall)
  • DROP (The packet is dropped with no reply to sender)
  • REJECT (Packet is dropped and an appropriate message is sent back to the sender.)

Starting, Stopping and Restarting

Although iptables is not a traditional service, but we can interact with it like we would other services.  For example to stop, start, or restart iptables we can use the following command.

Red Hat 6 and below:

service iptables stop
service iptables start
service iptables restart

Red Hat 7, Ubuntu and other systems using systemd:

systemctl stop iptables
systemctl start iptables
systemctl restart iptables

Saving iptables Rules (persistent)

There is another very important command that you should know.  When you modify iptables in any way it changes the current running configuration instantly, but it does not save it to a configuration file.  Which means if you make changes and then restart iptables, or restart the machine, you will lose all your changes.  After making changes and confirming they work as intended you should always save your configuration with the following command.

For Red Hat based distros:

service iptables save

For Ubuntu it is recommended that you install the iptables-persistent package:

sudo apt-get iptables-persistent
sudo sh -c "/sbin/iptables-save > /etc/iptables/rules.v4"

Basic Commands

Now we will explore basic configuration options and the basic commands used to control iptables. Let’s look at some commands and even try opening a port for http traffic.

To list your current iptables configuration you can use the following command:

iptables -L

If you would like a little more information you can add the verbose switch:

iptables -L -v

To flush iptables rules (remove all rules) use the -F switch:

iptables -F

For a full listing of all available options and switches use the following command:

iptables --help

Opening Ports

Now let’s take a look at adding a very basic rule.  Let’s say you have a web server running and you want to open port 80 to serve your web pages, so you enter the following command:

iptables -I INPUT -p tcp --dport 80 -j ACCEPT

Let’s take a closer look at the above command.  We know what the iptables is in the command, that's the binary or program itself, now let’s look at the other options.

-I stands for insert.  This will insert the rule at the top of the chain.  You can also use -A for append, which will place the new rule at the end of the chain.

INPUT tells the iptables command which chain you want the rule entered into. In this case it's the INPUT chain, which controls incoming packets.

-p tcp tells the rule to match only packets using the TCP protocol.

--dport 80 says to match traffic headed for port 80, or http.  --dport stands for destination port.

-j stands for JUMP to jump to the specified action or chain. In our case we are using -j ACCEPT so it will jump to the ACCEPT action and allow the traffic through.

You can also specify a source network or host in your rule.  For example if we only wanted the machine named joe.local.lan to access our web server we could specify that in our rule like so.
NOTE: You can specify host by name or IP address using the -s switch, which stands for source.

iptables -I INPUT -p tcp -s joe.local.lan --dport 80 -j ACCEPT

Let’s say you have a small network using the following IP subnet 192.168.1.0/24.  You can limit access to your webserver to ONLY people in your LAN by specifying the network in the source.

iptables -I INPUT -p tcp -s 192.168.1.0/24 --dport 80 -j ACCEPT

You can subsitute ACCEPT for DROP or REJECT. If you want to reject all incoming traffic from IP address 192.168.1.9 use:

iptables -I INPUT -p tcp -s 192.168.1.9 -j REJECT

Default Policy / Catch All

One last thing I would like to discuss for our iptables basics lesson is called the chain default policy.  

Remember I mentioned earlier a “catch all”? Well using the chains default policy is a way of creating a catch all.  

For this example lets use the INPUT chain.  If we set the default policy for the INPUT chain to ACCEPT, when packets come in that do not match any of our rules they will be ACCEPTED or allowed to pass through the firewall.  This is a security risk since we would have to have a rule for every single type of traffic.  It is much more efficient and secure to set the chain default policy to DROP or REJECT so if the traffic does not match any of our defined rules it is NOT allowed to pass through the firewall.

NOTE: DO NOT SET THE DEFAULT POLICY REMOTELY UNLESS YOU HAVE RULES TO ALLOW YOUR SSH SESSION. YOU CAN BE LOCKED OUT!

You can set the chain default policy using the -P switch.  The command below sets the default policy for the INPUT chain to DROP.

iptables -P INPUT DROP

Another way to create a catch all for a chain it to make a rule that matches all traffic and drops it as the last rule in a chain.  Remember that iptables processes rules from top to bottom then exits?  Creating a drop rule at the bottom of the chain will ensure that if a packet does not match any rules we defined for ACCEPT it will be dropped and not allow to pass.  In my opinion this is less secure and more prone to errors.  I would recommend using the default policy instead of a catch all rule at the end of a chain.

Conclusion

Iptables is a very powerful tool. There is a lot more than can be done with it including NAT, PREROUTING, etc. A lot more than we can cover in this basic tutorial. A great thing about iptables, it is well documented. I will leave links to some resources so you can read and learn further if you wish.

Resources