This tutorial is another part in a series of a security-related tutorials. This time, I’m going to talk about IPtables. IPtables is a software firewall that can filter out certain types of traffic. More specifically, it can filter based on source, packet type, protocol, port, connection status and more. It’s an extremely powerful tool to protect your server from unwanted access.
IPtables has two “versions”: iptables and ip6tables. The former is for IPv4 while the latter is for IPv6. The IPv4 and IPv6 packets are quite different from each other, thus each needing an own firewall. However, iptables functions mostly the same for both.
This is a bit of a theoretical tutorial, but understading how IPtables works helps a lot in working with it or in debugging problems with it. Let’s start with explaining what tables and chains are, as they are a fundamental concept in IPtables.
IPtables: tables and chains
IPtables contains four tables, each of which contains chains. A chain is a list of rules.
The four tables IPtables contains are:
- raw: this is the first place packets go through, unaltered
- filter: this is where packets may be filtered
- nat: this is where Network Address Translation is regulated/handled
- mangle: user for i.e. ToS or TTL alteration
I’m going to be focussing on the filter table this time. This is where most common filtering takes place. In a future guide (focusing on more advanced IPtables) I will be focussing on things like NAT. IPtables defaults to the filter table when adding rules without defining a table.
The filter table has three chains by default:
- INPUT: for incoming packets
- OUTPUT: for outgoing packets
- FORWARD: for packets routed through the local server/for another device on the local server
In order to see current IPtables rules for the filter table, run:
sudo iptables -L
It should output something like this in case there are no rules:
Chain INPUT (policy ACCEPT)
target prot opt source destinationChain FORWARD (policy ACCEPT)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destination
As you can see, no rules are defined. All three chains have a default policy, which is currently ACCEPT. ACCEPT is a target value. Other targets value that are valid are DROP, REJECT and LOG.
Each target value has a different response:
- ACCEPT: packet is let through and processing rules in this chain is stopped
- DROP: Ignore the packet and stop processing rules in this chain
- REJECT: Reject the packet and inform the other end of doing so, then stop processing rules in this chain
- LOG: Log the packet and continue processing rules in this chain
As you can see from the above, if you want to absolutely allow no traffic to your server at all, you could set all chains to default to DROP. In that case all packets are dropped, including SSH.
These target are also very important for rules. A chain contains one or more rules. When it is done processing rules and the packets has matched no rule, the default target is applied. In the above case, if there were any rules and no rules were matched, the packet would be allowed. Such a scenario allows for blocking certain ports or packets from certain IP addresses.
Let’s head on to adding rules to chains.
Inserting and Deleting Rules
Rules can be very complicated or very simple. Let’s dive into a simple example for this tutorial:
sudo iptables -A INPUT -s 198.51.100.51 -j DROP
The above command appends (-A) a rules to the INPUT chain. Any packet from source IP/subnet (-s) will be given DROP as a target (-j for jump). So any incoming packet coming from 198.51.100.51 will be dropped when this rule is matched. This command is something you should learn by heart, by the way, as it’s quite effective when you want to stop somebody attacking your server (i.e. password guessing or lots of requests).
It is important to note that rules are processed in the order that they have been added to a chain. So, for the above example, if the following rule would have been added before that one, the packets would not be dropped, but accepted:
sudo iptables -A INPUT -s 198.51.100.51 -j ACCEPT
But let’s stick with the first example and list the contents of the filter table:
mpkossen@gibbs:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all — 198.51.100.51 anywhereChain FORWARD (policy ACCEPT)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destination
mpkossen@gibbs:~$
As you can see, the rules has been added to the INPUT chain and is currently the first and only rule in there. If you add more rules with -A, they are appended to the chain. If you want to add a rule at a specific position in the chain, you can use the -I flag with the number of the position you want to add the rule to. Example:
sudo iptables -I INPUT 1 -s 198.51.100.50 -j DROP
This adds the rule to the first position in the chain and moves all other rules downwards. If you had changed the 1 to 2, it would have been added to the second position. This would have ensured the first rule to stay in place and the other rules to move downwards.
If you run the following command you get to see line numbers as well:
mpkossen@gibbs:~$ sudo iptables -L –line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all — 198.51.100.50 anywhere
2 DROP all — 198.51.100.51 anywhereChain FORWARD (policy ACCEPT)
num target prot opt source destinationChain OUTPUT (policy ACCEPT)
num target prot opt source destination
mpkossen@gibbs:~$
To delete rules, you have the -D flag. This has two options:
- You specify the chain and the rule number (as defined in the above tables)
- You specify the rule (if more than one rule matches the first is removed)
So, let’s say we want to remove rule number one, we have the following two options:
sudo iptables -D INPUT 1
Or:
sudo iptables -D INPUT -s 198.51.100.50 -j DROP
Both will result in the following:
mpkossen@gibbs:~$ sudo iptables -L –line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all — 198.51.100.51 anywhereChain FORWARD (policy ACCEPT)
num target prot opt source destinationChain OUTPUT (policy ACCEPT)
num target prot opt source destination
mpkossen@gibbs:~$
The rules we have added above are not permanent, however. They are flushed as soon as iptables has been restarted or your server is rebooted. In a future tutorial, I will show how to persist these rules on both CentOS and Ubuntu.
Final notes on my introduction to IPtables
As you may have noticed, there is a lot to tell about IPtables. For example: you can also filter on source and destination IP address, source and destination port, protocol or even the state of a connection. But you can also log packets under certain circumstances.
For now, you know how to add rules to drop packets from a source address and how to delete rules. The iptables man-pages are a good starting point to find out more. In my next tutorial, I will focus on persisting rules and setting up some basic rules.
Related Posts:
- How to Rapidly Install Java, OpenJDK & Oracle JDK on your VPS - December 14, 2015
- It’s been a great ride - December 14, 2015
- Cheap Windows VPS – $21/quarter 1GB KVM-based Windows VPS in 11 worldwide locations - November 30, 2015
Come to learn~
“you could set all chains to default to DROP”
…and that is when you go to support with your tail between your legs!
lol, i remember doing something like that with my router, and i must hard reset it to be able to use it (and reconfigure everything)
Everyone has locked themselves out of their own server at some point!
Well this site is hardly known for it’s wise and experienced patrons. It’s mostly known as a hotbed of cheapskates and amateurs.
True, but that is why it is helpful to test your console access before you make significant iptables changes. Many (most?) VPS providers include a special console through SSH or VNC so that you can connect to your VPS even if you make an iptables change where your VPS cuts off all network access.
Nice tutorial. :D
This tutorial must see and learn most OpenVZ providers!
As a provider we should already know this :)
You are lucky :) most providers have no idea what is this and how to handle, as well I learn
is it same for all virtualisation?
OpenVZ
Fairly certain it’s for all virtualization.
Yeah worse case operating system specific – shouldn’t be a virtualization thing.
I saw openvpn tutorial.. they provide iptables rules for openvz and xen & kvm..
Yes. It’s the same for OpenVZ, Xen, KVM and probably others. The above is not OS-specific. The follow-up to this will have OS-specific stuff in it, but I’ll do a CentOS/Ubuntu hybrid.
Very simple tutorial for a very useful operation, thank you.
Thank you and you’re welcome!
good good study,day day up.←_←
Mini three is a good student
Very good tutorials and bookmarked it.
Do you think there is benefit to using IPTABLES over Ubuntu’s ufw for simple, lightweight stuff? For example, locking a VPS down to just HTTP and SSH traffic? ufw seems pretty easy to get up and running with in a short space of time.
UFW is a simplified layer on top op IPTables, AFAIK. I read it’s a easier to use than plain IPTables.
It’s junk. Like everything that comes out of Ubuntu.
That’s a very good tutorial. Thank you.