Quick IPTables setup
The Linux kernel has a great firewall built-in commonly referred to as iptables. Actually iptables is only the user-space tool that you as the user interact with, while the kernel module doing all the work is actually called Netfilter.
Here are a few tips on how to quickly set up a filtering firewall on a Linux box.
The filtering mechanism uses a series of groups called “chains” in the literature. The main predefined chains are:
- INPUT — All the packets reaching the host computer
- OUTPUT — Packets originating from the host computer
- FORWARD — Packets routed / passing through.
Each of these chains can have a default policy such as accepting all packets by default or dropping them.
Individual rules are then added to a List-like structure within each of these chains. Rules are then read from the top to the bottom for each intercepted IP packet.
Let’s go on and add a few rules. These commands are all run as the superuser.
iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
The iptables command can append (
-A), insert (
-I), delete (
-D) rules from the list.
In this case we append to the INPUT chain.
The first one will allow all requests to the
lo interface: a shorthand for the localhost.
-j flag indicates which action should be applied when the rule is matched,
The second rule will allow all inbound TCP packets on ports 80 and 443.
Iptables uses the concept of extensions. These are loaded using the
For the second rule we use the
multiport extension which allows to specify two
ports at once.
You probably also want to allow UDP traffic on the same ports to account for newer protocols such as QUIC.
We don’t necessarily have to use extensions, a simple rule will also work such as this one, where all inbound traffic on TCP port 22 is accepted.
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
However a cautious user will move their SSH daemon from port 22 to something a bit more obscure, and turn on public key based authentication.
All rules can then be visualised using a command such as:
iptables -nL --line-numbers
This will display each rule preceded by its line number. This is significant as we’ll see in the following example.
Due to how some protocols work we will also have to allow inbound traffic in reply to outbound traffic that was initiated from the host machine.
iptables -I INPUT 2 -m state --state ESTABLISHED -j ACCEPT
We want this rule to be inserted near the top of the INPUT chain on the 2nd position in the list,
because it will be used quite a lot.
We then use the
state extension here, which enables us to specify that for already established connections
the firewall should allow all inbound traffic.
This rule is important as without it many protocols will break
(such as outbound HTTP from the host machine).
If we now list the chain rules again we can see that this was added to the 2nd position:
Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED 3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443 4 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ...
Don’t worry if you make a mistake, rules can always be deleted by their index in the chain.
iptables -D INPUT 6
Or even flush the entire chain with:
iptables -F INPUT
Finally we could drop all the remaining traffic with something like:
iptables -A INPUT -j DROP
But then the drop rule will always have to stay at the bottom of the chain. A better practice is to change the Policy of the entire chain to DROP:
iptables -P INPUT DROP
This will then be the default catch-all action for each packet which doesn’t match one of the rules we defined.
Chain INPUT (policy DROP) ...
As for the OUTPUT chain, this usually has a default ACCEPT policy, as we generally trust all outbound traffic from our machine.
iptables -P OUTPUT ACCEPT
Finally persist the state of the chains to the disk, and make sure that the iptables service is enabled by your daemon manager — such as systemd.
iptables-save > /etc/iptables/iptables.rules systemctl enable iptables
This will ensure that the rules are actually kept and loaded between reboots. And we are done, you have now configured a few simple filtering rules for your Linux firewall. Below are a few good resources to further your knowledge with iptables.
- CentOS IPTables Howto
- IPTables Basic Concepts
- Google’s QUIC protocol: moving the web from TCP to UDP