Tutorial | iptables Basics and Examples

by Thomas german version


Translated at 2022-01-16

Last update at 2021-11-16

Created at 2019-08-28


Firewall

Secure Your Server with the Firewall Software iptables

A firewall is used to protect your server or clients. It makes sure that unauthorized people do not gain access to certain services. Ports without any service behind can be closed completely. In this tutorial you will learn how to use iptables and understand the basic principle behind it.

iptables Basics

If iptables is enabled, all incoming, outgoing and forwarded IP packets are monitored by the Linux Kernel. Iptables is organized in so called tables and chains. Every tatble can have one or more chains. Chains are nothing more than the concatenation of rules that are processed with each IP packet. The kernel can perform suitable actions with an IP packet. The four main actions are as followed:

  • ACCEPT – The IP packet is accepted and processed.
  • DROP – The IP packet is not accepted and dropped.
  • REJECT – The IP packet is not accepted and dropped. However, the sender receives a message about the process that the packet is not accepted.
  • RETURN – If a packet matches this filter, the default rule of the main chain is executed.

In this tutorial we will limit ourselves to the basics of the main filter table. Other examples of tables would be nat, mangle and raw. The table filter has three chains:

  • INPUT – Incoming packets can be controlled in this chain.
  • OUTPUT – Outgoing packets are controlled in this chain.
  • FORWARD – Incoming packets assigned to another destination can be controlled with this chain.
iptables tutorial - table filter

Install iptables

Most Linux distributions include pre-installed iptables. Note that CentOS comes with the firewall firewallD. You have to uninstall firewallD, if you want to use iptables.

apt-get update
apt-get install iptables

Get Current iptables Status

The current tables and chains can be displayed with the following command:

iptables -L -v

The output of the above command on a server without current rules looks like this:

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

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

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

All three chains have the default policy ACCEPT. The default rule is always placed directly next to the chain name and is executed if no rule in the chain applies.

Create Rules with iptables

The default command looks like this:

iptables -A <chain> -i <interface> -p <protocol (tcp/udp) > -s <source> --dport <port no>  -j <target>

The -A stands for attached and requires a chain name. The rule is always appended to a chain. The interface is optional and describes the NIC to which the rule should apply. The protocol is the network protocol which should be filtered. Much more than tcp/udp can be filtered here. Source describes the source IP of the IP packet. The --port option can be used to filter the incoming port. Last but not least, the action is executed with the target.

Example Rules with SSH and HTTP(s)

We want to allow SSH and HTTP(s) protocol on ports 22, 80 and 443 from requesting clients. All other requests should be blocked by default.
To do this, we first unblock the ports and then block the rest:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -P INPUT DROP

Example output from the iptables -L -v command after executing the four commands:

Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
 292 31342 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh
   0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:http
   0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:https

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

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

Permit Established Connections

Established connections are connections from one server to another server or client that have been established by the device itself. Since the connection was established by us, the computer trusts the incoming traffic of this connection.

iptables -A INPUT -i $WAN -m state --state ESTABLISHED,RELATED -j ACCEPT

Replace $WAN with the name of the NIC.
Thereby the following most used options can be set with the --state option:

  • NEW - The data packet is new to the server, usually through a new connection.
  • ESTABLISHED - The data packet has already entered and left the server.
  • RELATED - The data packet has started a new connection but is involved in an existing connection, e.g. an FTP data transfer or an ICMP error.

More options can be found directly on the documentation page of iptables.

Filter Packets by Source Address

We want to completely block all incoming connections of IP 10.10.10.1:

iptables -A INPUT -s 10.10.10.1 -j DROP

Note, here you can also work with ranges:

iptables -A INPUT -m iprange --src-range 10.10.10.1-10.10.10.255 -j DROP

Delete Rules

All rules can be deleted with the following command:

iptables -F

Individual specific rules are deleted with the -D option. When doing that, we first have to find out the number of the rule:

iptables -L --line-numbers

After that, a special rule can be deleted:

iptables -D INPUT 3

Saving Persistent Rules in iptables

To keep rules persistent, an extra tool must be installed. Iptables-persistent ensures that saved rules are loaded on restart.

apt-get install iptables-persistent

The rules are stored in the following files. A differentiation is made between IPv4 and IPv6:

/etc/iptables/rules.v4
/etc/iptables/rules.v6

To save the currently valid rules, the following command must be used:

iptables-save > /etc/iptables/rules.v4
### or
ip6tables-save > /etc/iptables/rules.v6

Thus, when restarting, the rules will be loaded automatically.