Skip to content

Infra / Ops

Setting up Your First IPTables Rule on Ubuntu 14.04

A good firewall is essential — failing to secure your server leaves you and your customers open to breaches. Writing your first iptables rule.

4 min read
  • iptables
  • linux
  • firewall

What is a Firewall (view full size, opens in a new tab)

A good firewall to secure your server is essential. Failure to secure your server can leave you and your customers open to data breaches or unauthorized usage of the machine.

IPTables is a great, free tool for this job when securing an IPv4 server on the internet. If your server has IPv6 access, you will need to look into other tools such as ip6tables to secure your servers IPv6 access.

IPTables Basics

First things first, it's important to understand that IPTables requires root privliges to run. Not a big deal, this means we need to do one of the following:

  • Use sudo prior to each command we run
  • Use the su command to get the super user privileges

For this tutorial, I will assume you are running as a root user and I will not be using sudo before each command. If you decide to go through using sudo, please add that before each command shown. So before we worry about adding rules, changing rules, or removing rules, we need to know what rules we have on our server. We can get a a list of rules by using the -L flag, short for --list as seen below:

iptables -L  

This will create a list of rules for our server. A list without any rules will look something 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  

Here you will see three chains, INPUT, FORWARD, and OUTPUT. In IPTables, chains are how we define rules based on the type of packet the firewall is dealing with. For example, the default INPUT chain is used to specify rules for packets that are incoming to the server / firewall, the FORWARD chain is used to specify rules for packets that are meant for another NIC, or network interface controller, on the server. This means that the server is routing or forwarding those packets on. Or lastly, the OUTPUT chain is used to specify rules for packets that are leaving the server through the firewall.

While these are included with most IPTables installations, users can add or remove chains as necessary as well as access other tables with different rulesets by default such as the NAT table, Mangle table, or Raw table. By default, and for today's lesson, we will use the Filter table. Going into more detail about these tables and options falls outside of the scope of today's tutorial though.

A similar command which displays the rules in a format closer to how we declare them, use the -S flag, short for --list-rules like so:

iptables -S  

This will output the above list of rules, or lack there or, like so:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

Here the -P prior to each chain name means that it is a policy.

Adding Our Own Rules

The first rule to add, is often this rule:

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

This rule looks incredibly scary, but honestly it's pretty straightforward once we break it down and understand what's happening. So let's break each piece down in order:

  1. Starting at the very beginning of the command we have iptables, which is used to say that we would like all of this command to be handled by the IPTables program.
  2. -A, short for append, is used to say that we would like to append a rule to the end of a chain which we specify next.
  3. INPUT is where we tell IPTables which chain we would like to append the rule to. This corresponds with the Chain INPUT (policy ACCEPT) line that we saw when we used iptables -L.
  4. -m, short for module, says that we would like to use one, or multiple of IPTables' modules which we will specify.
  5. conntrack, short for connection tracking, states the name of the module we would like to use. The conntrack module allows us to track connections and find relationships between packets.
  6. --ctstate, short for connection state, is a command made available to us because we have used the conntrack command. This allows us to match and filter packets based on whether we have seen them before or if they are related to previously seen packets.
  7. We then tell --ctstate which states we would like this rule to apply to, in this case that is the ESTABLISHED state and RELATED state.
    • The ESTABLISHED state says that we would like to have this rule affect packets that are part of an existing connection
    • The RELATED state says that we would like to have this rule affect packets that are associated with an established connection such as an SSH connection.
  8. -j ACCEPT, short for jump to the ACCEPT chain, is used specify the target for packets that match the rule we've written. In this case, we have said that we would like to accept/allow any packets which match our aforementioned criteria.

You may be asking why add this rule first. Simply put, we want to ensure that if we add a DROP rule, that our current existing connection is not dropped by the firewall and this allows us to keep adding more rules.

If we run iptables -L again, we should see an updated list of rules.

Chain INPUT (policy ACCEPT)  
target     prot opt source               destination  
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT)  
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)  
target     prot opt source               destination  

Conclusion

This is very basic but I hope to talk more about how to add more rules for HTTP, HTTPS, SSH, etc. in future tutorials! Hope you enjoyed this!

Tag