iptables is the backend of popular firewall programs like ufw. In this tutorial you will learn the basics of iptables.

Table of Contents

Installation

Your operating system will likely to have iptables installed. Run iptables --version to check it out. If it’s not installed, you can install it with your system package manager (APT, pacman, yum, etc.).

Firewall programs that use iptables

ufw, firewalld and other firewall programs use iptables as their backend. Take into account that these programs can overwrite your iptables rules, so if you don’t use them, you may want to uninstall them.

System permissions

In order to use iptables you need to run the commands as root or use sudo (or doas).

Usage

Listing firewall rules

Run iptables -L. You’ll see three main sections:

  • Chain INPUT: this section applies to network packets that go from outside to your system.
  • Chain OUTPUT: here you’ll see rules for packets that go from your system to outside.
  • Chain FORWARD: this applies to packets forwarded for your system.

You can display only one chain by adding chain name at the end of the command:

iptables -L OUTPUT
# iptables -L
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

Firewall actions: ACCEPT, DROP, REJECT

When you create a firewall rule, you decide if a packet that matches that rule will be accepted (pass through), rejected (don’t pass and report the sender) or dropped (don’t pass and don’t report the sender).

Rules order

Each network packet is analyzed to find if it matches a firewall rule in order, from top to bottom. When you run iptables -L you’ll see the order in which the rules are checked. You can add the --line-numbers parameter to also display rules position numbers.

Add a rule

  • -I <chain> [<rule number>] <rule>, --insert <chain> [<rule number>] <rule>: insert a rule before another rule (add a rule number) or at the beginning if no rule number is defined.
  • -A <chain> <rule>, --append <chain> <rule>: append, insert the rule at the end.
  • -j <ACTION>, --jump <ACTION>: define what to do with the packet if it matches the rule (ACCEPT, DROP, REJECT).
  • -s <address>, --source <address>: source IP (or range). For example, 123.45.67.89 or 172.0.0.0/24.
  • -d <address>, --destination <address>: destination IP (or range).
  • -p <protocol>, --protocol <protocol>: specify a network protocol (tcp, udp, icmp).
  • --dport <port>, --destination-port <port>: define a destination port. You must specify a protocol before.
  • --sport <port>, --source-port <port>: define a source port. You must specify a protocol before.

These are some examples:

# Block access to port 80
iptables -A INPUT -p tcp --dport 80 -j DROP
# Allow access from one IP address
iptables -A INPUT -s 123.45.67.89  -j ACCEPT

Modify the default policy

When you list firewall rules, next to the chain name you’ll find the default policy for that chain: that means when a network packet does not match any rule, will be accepted, rejected or dropped.

To modify this policy, run iptables --policy <CHAIN> <ACTION>. <ACTION> must be either ACCEPT or DROP.

# Remember to add `INPUT` rules before to not block yourself.
iptables --policy INPUT DROP

Delete a rule

Use -D <chain> <rule>, or -D <chain> <rule number>.

  • List rules and their numbers:
    # iptables -L --line-numbers
    Chain INPUT (policy DROP)
    num  target     prot opt source               destination
    1    ACCEPT     all  --  123.45.67.89        anywhere
    ...
    
  • Remove rule number 1
    # iptables -D INPUT 1