Tutorial

How To Set Up a Firewall Using Iptables on Ubuntu 12.04

Published on August 3, 2012
How To Set Up a Firewall Using Iptables on Ubuntu 12.04
Not using Ubuntu 12.04?Choose a different version or distribution.
Ubuntu 12.04

Status: Deprecated

This article covers a version of Ubuntu that is no longer supported. If you are currently operate a server running Ubuntu 12.04, we highly recommend upgrading or migrating to a supported version of Ubuntu:

Reason: Ubuntu 12.04 reached end of life (EOL) on April 28, 2017 and no longer receives security patches or updates. This guide is no longer maintained.

See Instead:
This guide might still be useful as a reference, but may not work on other Ubuntu releases. If available, we strongly recommend using a guide written for the version of Ubuntu you are using. You can use the search functionality at the top of the page to find a more recent version.

About Iptables

In order to make a server more secure after the initial set up, Ubuntu ships with iptables which is the distribution’s default firewall. At the outset, although the Ubuntu firewall is configured, it is set up to allow all incoming and outgoing traffic on a virtual private server. To enable some stronger protection on the server, we can add some basic iptables rules.

The iptables rules come from a series of options that can be combined to create each specific process. Each packet that crossing the firewall is checked by each rule in order. As soon as it matches a rule, the packet follows the associated action, otherwise it proceeds down the line.

Note: This tutorial covers IPv4 security. In Linux, IPv6 security is maintained separately from IPv4. For example, "iptables" only maintains firewall rules for IPv4 addresses but it has an IPv6 counterpart called "ip6tables", which can be used to maintain firewall rules for IPv6 network addresses.

If your VPS is configured for IPv6, please remember to secure both your IPv4 and IPv6 network interfaces with the appropriate tools. For more information about IPv6 tools, refer to this guide: How To Configure Tools to Use IPv6 on a Linux VPS

Iptables Commands

Although this tutorial will go over a limited amount of commands that would provide a server with some basic security, there are a variety of nuanced and specific cases that can be developed for iptables. Below are some of the most useful commands for developing a firewall for your VPS, but keep in mind that this is a short list and there are a variety of other options.

-A: (Append), adds a rule to iptables
-L:  (List), shows the current rules
-m conntrack: allows rules to be based on the current connection state, elaborated in the the --cstate command.
--cstate: explains the states that connections can be in, there are 4: New, Related, Established, and Invalid
-p: (protocol), refers to the the protocol of the rule or of the packet to check.The specified protocol can be one of tcp, udp, udplite, icmp, esp, ah, sctp or the special keyword "all".
--dport: (port), refers to the the port through which the machine connects
-j: (jump), this command refers to the action that needs to be taken if something matches a  rule perfectly. It translates to one of four possibilities:
	-ACCEPT: the packet is accepted, and no further rules are processed
	-REJECT: the packet is rejected, and the 	sender is notified, and no further rules are processed
	-DROP: the packet is rejected, but the 	sender is not notified, and no further rules are processed
	-LOG: the packet is accepted but logged, and the following rules are processed 
-I: (Insert), adds a rule between two previous ones
-I INPUT 3: inserts a rule to make it the third in the list
-v: (verbose), offers more details about a rule

Creating the Iptables Rules:

If you type in the following, you can see the current iptables rules:

sudo iptables -L

They should look like this:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

If you have another set of rules in place or want to start fresh, you can always set the rules back to the default by flushing and deleting all of them:

sudo iptables -F

Additionally, if you want speed up your work with iptables, you can include -n in the command. This option disables DNS lookups and prevents the command from trying to find the reverse of each IP in the ruleset. You could use this to list rules, as an example:

iptables -L -n

A Basic Firewall

As it stands the current rules allow all connections, both incoming and outgoing. There are no security measures in place whatsoever. As we build up the table, keep in mind that as soon as a packet is ACCEPTED, REJECTED, or DROPPED, no further rules are processed. Therefore the rules that come first take priority over later ones.

While creating the rules, we have to be sure to prevent ourselves from accidentally blocking SSH (the method through which we connected to the server).

To start off, let’s be sure to allow all current connections, all of the connections at the time of making the rule, will stay online:

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

We can go ahead and break this down:

  1. -A tells iptables to append a rule to the table.
  2. INPUT designates this rule as part of the Input chain.
  3. m conntrack followed by the --cstate ESTABLISHED,RELATED guarantees that the result of this rule will only apply to current connections and those related to them are allowed
  4. -j ACCEPT tells the packet to JUMP to accept and the connections are still in place.

After we are assured that all the current connections to the virtual private server can stay up uninterrupted, we can proceed to start blocking off other insecure connections.

Let’s assume that we want to block all incoming traffic, except for those coming in on 2 common ports: 22 for SSH and 80 for web traffic. We proceed by allowing all traffic on the designated ports with the following commands:

sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

In both of these commands, the -p option stands for the protocol with which the connection is being made, in this case tcp, while the --dport specifies the port through which the packet is being transmitted.

After we have guaranteed that the desirable traffic will make it through the firewall, we can finish up by blocking all remaing traffic from accessing our virtual server. Because this is the last rule in the list, all traffic that matches any of the previous rules in iptables will not be affected, and will be treated as we set up previously.

Let’s make a rule to block all of the remaining traffic:

sudo iptables -P INPUT DROP

With that, we can see what our updated rules look like:

sudo iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http 

We are almost finished. However, we are missing one more rule. We need to provide our VPS with loopback access. If we were to add the rule now without further qualifiers, it would go to the end of the list and, since it would follow the rule to block all traffic, would never be put into effect.

In order to counter this issue, we need to make this rule first in the list, using the INPUT option :

sudo iptables -I INPUT 1 -i lo -j ACCEPT
  1. -I INPUT 1 places this rule at the beginning of the table
  2. lo refers to the loopback interface
  3. -j ACCEPT then guarantees that the loopback traffic will be accepted

Now we have finished creating a basic firewall. Your rules should look like this (we can see the details of the iptable by typing -v):

sudo iptables -L -v
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere            
 1289 93442 ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
    2   212 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:http     

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 157 packets, 25300 bytes)
 pkts bytes target     prot opt in     out     source               destination       

However, as soon as the virtual server reboots, the iptables rules will be wiped. The next step will go over saving and restoring the iptables rules.

Saving Iptables Rules

Although the iptables rules are effective, they will automatically be deleted if the server reboots. To make sure that they remain in effect, we can use a package called IP-Tables persistent.

We can install it using apt-get:

sudo apt-get install iptables-persistent

During the installation, you will be asked if you want to save the iptables rules to both the IPv4 rules and the IPv6 rules. Say yes to both.

Your rules will then be saved in /etc/iptables/rules.v4 and /etc/iptables/rules.v6.

Once the installation is complete, start iptables-persistent running:

sudo service iptables-persistent start

After any server reboot, you will see that the rules remain in place.

By Etel Sverdlov

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
10 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I’m having the same sort of issues as ihk2010.

When attempting to do anything with iptables I get the following error;

FATAL: Error inserting ip_tables (/lib/modules/3.8.0-36-generic/kernel/net/ipv4/netfilter/ip_tables.ko): Invalid module format

I have updated the linux-headers and linux-image but still get the same issues.

Can anyone help please?

When trying to run sudo iptables -L I got

FATAL: Error inserting ip_tables (/lib/modules/3.8.0-37-generic/kernel/net/ipv4/netfilter/ip_tables.ko): Invalid module format
iptables v1.4.12: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

uname -r 3.8.0-37-generic

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
September 6, 2013

@gasperzi: First, create a chain for SSH:

<pre>sudo iptables -N SSH</pre> and another chain for FTP:

<pre>sudo iptables -N FTP</pre> Add the whitelisted IPs to the SSH chain:

<pre>sudo iptables -A SSH -s 1.2.3.4 -j ACCEPT sudo iptables -A SSH -s 1.2.3.5 -j ACCEPT #etc.</pre> Do the same for FTP:

<pre>sudo iptables -A FTP -s 1.2.3.4 -j ACCEPT sudo iptables -A FTP -s 1.2.3.5 -j ACCEPT</pre> Then, have iptables check the SSH chain on connection to ssh and see if the IP that is trying to connect is whitelisted and if not, drop the packets:

<pre>sudo iptables -p tcp -m tcp --dport 22 -j SSH sudo iptables -p tcp -m tcp --dport 22 -j DROP</pre> Do the same for FTP:

<pre>sudo iptables -p tcp -m tcp --dport 21 -j FTP sudo iptables -p tcp -m tcp --dport 21 -j DROP</pre> Now, whenever you want to add another IP address to the whitelist, you can simply run one of these commands according to which service you want to access:

<pre>sudo iptables -A SSH -s 111.222.111.222 -j ACCEPT</pre>

$ sudo service iptables-persistent start
Failed to start iptables-persistent.service: Unit iptables-persistent.service not found.

It seems like the name has changed to netfilter-persistent.

$ sudo service netfilter-persistent start
$ 

It’s still installed using sudo apt install iptables-persistent though.

got the error on running sudo service iptables-persistent start

Failed to start iptables-persistent.service: Unit iptables-persistent.service not found

sudo iptables -P INPUT DROP after this all previous rules gets dropped where as it should not happen, i am using Ubuntu 12.04, any updates to resolve this be much appreciated. Thanks

I would like to inform everyone of a concern on this tutorial. Please be aware, that doing “sudo iptables -F” will make your website, server and ssh unresponsive.

I wish the author had given us precaution…

Now, my server is useless already… I think I just have to reconfigure another one as I don’t have a backup.

But I am hoping that someone could help?

Hi,

Thanks for this article! I have now setup IPtables on my Linux Ubuntu VPS, running with VirtualMin / Webmin. Strange thing is, although I added the rules for TCP port 80, it still rejects the connection. I also added a rule for SSL and IMAP, those seem to work. As soon as I change default action to ACCEPT instead of REJECT, I can access my website again. I also did a grep on port 80, which shows apache is running it. In virtualmin I configured the website to use apache on port 80, but still I cannot see my website with the rule for port 80.

Any ideas or tips? Thanks!

Hi,

Thanks for this article! I have now setup IPtables on my Linux Ubuntu VPS, running with VirtualMin / Webmin. Strange thing is, although I added the rules for TCP port 80, it still rejects the connection. I also added a rule for SSL and IMAP, those seem to work. As soon as I change default action to ACCEPT instead of REJECT, I can access my website again. I also did a grep on port 80, which shows apache is running it. In virtualmin I configured the website to use apache on port 80, but still I cannot see my website with the rule for port 80.

Any ideas or tips? Thanks!

What is SSH if is on another port number? And I’m assuming you add “sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT” for secure connections. Thank you for a great, simple article.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.