← back

2018-08-25: a practical introduction to iptables


The well-known and oft-used Linux networking tool, iptables, is something that eventually in the career of a Linux sysadmin or developer, will require manual configuration. From the man page:

iptables/ip6tables - administration tool for IPv4/IPv6 packet filtering and NAT

In more recent years an IPv6 variant of this tool has been implemented, uncreatively denoted ip6tables for the sake of simplicity.

Admittedly, filtering IPv6 addresses is perhaps worthy of an article itself due to the current prevalence in the industry for IPv4 addresses and the commonality of IPv6 addresses in use among hackers and other smaller online communities.

Instead, the focus will be on using the original IPv4 variant. Start by printing a verbose list of the current filtering rules in place on a given host. Type the following into a terminal:

iptables -vL

Upon doing so, the various uniquely defined filtering groups, called chains, will be printed out with their name (e.g. INPUT, OUTPUT) and their policy (e.g. ACCEPT, DROP) and their subrules (i.e. for individual IPs or CIDR ranges). Specifically, output similar to the below will be displayed:

Chain INPUT (policy ACCEPT x packets, y bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any any anywhere anywhere

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

Chain OUTPUT (policy ACCEPT x packets, y bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any any anywhere anywhere

Where x and y are the number of packets and total size in kilobytes or megabytes, respectively. Immediately below the chain definition are the columns labels, which are:

To add a rule, decide which chain to append to, the protocol, the port and the intended action. For example, to allow any SSH traffic into the given system, type the following:

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

Afterwards, the iptables INPUT chain looks like the following:

Chain INPUT (policy ACCEPT x packets, y bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh

To delete a rule, use the -D flag and type the number of the rule, like so:

iptables -D INPUT 1

Packets that are incoming from a certain port can be blocked as well to prevent traffic from being accessed. This can be done by setting the DROP action:

iptables -A INPUT -p udp --dport 35353 -j DROP

Rules can also be edited by specifying the -I flag with the chain and number. Then the other flags may be specified alongside to set the different attributes of the rule.

iptables -I OUTPUT 4 -p tcp -i enp4s0 -j DROP

Another action that can be assigned to rules is logging. Say you wanted to tweak a rule to allow for a hard limit of 10 responses from a given IP address per second, and then have it log all of the information to file. This can be done as follows:

iptables -I INPUT 1 -m limit --limit 10/sec -j LOG --log-prefix "iptables denied: " --log-level 7

If there are multiple groups of IP addresses that are being rate limited for different reasons, consider setting the log-prefix to something meaningful than simply the "denied" text used above.

Now, all of the iptables rules that were implemented will by default disappear at the next reboot or shutdown of the host. To store these rules more permanently, use the save commandline utility as follows to dump it to file:

iptables-save > /etc/iptables/iptables.rules

The rules will now be loaded on startup. To immediately have them loaded, merely restart iptables via systemctl.

systemctl restart iptables

Please note that it is possible to accidently break a connected session and be locked out of a system, say if the session is connected via ssh and port 22 is now blocked. Consider testing the rules file on a non-critical local machine first to prevent unforeseen consequences.

If you change the rules later on and want to reset them to the default, the rules may then be reloaded using the restore program like so:

iptables-restore < /etc/iptables/iptables.rules

There are quite a few other features in iptables, however, this covers all of the basics. Perhaps at some later date a post that details further scenarios will be written.