iptables Cheatsheet

Reference guide for iptables.

The tables are the following:

  • filter: is the default table and is used for packet filtering.
  • nat: is used for network address translation.
  • mangle: is used for packet modification.
  • raw: is used to work with packets before they are modified by other tables.
  • security: is used for managing mandatory access controls (MAC).

Each table contains a series of predefined chains:

  • INPUT: contains the rules for incoming packets.
  • OUTPUT: contains the rules for outgoing packets.
  • FORWARD: contains the rules for packets that are to be forwarded elsewhere.
  • PREROUTING: contains the rules for packets that should be routed,
  • POSTROUTING: contains the rules for packets that have already been routed.

All chains contain an arbitrary number of rules that are evaluated in sequence, until the conditions of a rule are met. This will determine the action to take, which can be ACCEPT, DROP, REJECT, LOG, RETURN, etc. A default policy determines what to do with packets for which no match is found.

The sequence of rule evaluation is summarised as follows:

Current iptables Ruleset

Check current iptables ruleset

sudo iptables -S
sudo iptables -L -v

Enable Traffic on Localhost

Allow communication between applications and databases on the server.

sudo iptables -A INPUT -lo -j ACCEPT

Enable Connections on HTTP, SSH, SSL

Allow regular connections to continue as usual.

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

Filter Packets Based on Source

Allow packets from a source

sudo iptables -A INPUT -s 192.168.1.213 -j ACCEPT

Reject packets from a source

sudo iptables -A INPUT -s 192.168.1.213 -j DROP

Drop All Other Traffic

sudo iptables -A INPUT -j DROP

Delete Rules

Remove all rules withe the flush command.

sudo iptables -F

Persisting Changes

To make changes persistent after reboot save the rules using the following command:

sudo /sbin/iptables-save

Disable Firewall

Flush all the rules and make changes persistent

sudo iptables -F
sudo /sbin/iptables-save

iptables is the userspace command line program used to configure the Linux 2.4.x and later packet filtering ruleset.

When a connection tries to establish itself on your system, iptables looks for a rule in its list to match it to.
If it doesn’t find one, it resorts to the default action.

How it works

iptables uses three different chains to allow or block traffic: input, output and forward

  • Input – This chain is used to control the behavior for incoming connections.
  • Output – This chain is used for outgoing connections.
  • Forward – This chain is used for incoming connections that aren’t actually being delivered locally like routing and NATing.

Let’s start to configure rules

By default all chains are configured to the accept rule, so during the hardening process the suggestion is to start with a deny all configuration and then open only needed ports:

iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP

Display rules

Verbose print out all active iptables rules

iptables -n -L -v

…same output with line numbers:

iptables -n -L -v --line-numbers

Finally, same data output but related to INPUT/OUTPUT chains:

iptables -L INPUT -n -viptables -L OUTPUT -n -v --line-numbers

List Rules as for a specific chain

iptables -L INPUT

same data with rules specifications:

iptables -S INPUT

rules list with packet count

iptables -L INPUT -v

Delete/Insert rules

Delete Rule by Chain and Number

iptables -D INPUT 10

Delete Rule by Specification

iptables -D INPUT -m conntrack --ctstate INVALID -j DROP

Flush All Rules, Delete All Chains, and Accept All

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X

Flush All Chains

iptables -F

Flush a Single Chain

iptables -F INPUT

Insert Rule

iptables -I INPUT 2 -s 202.54.1.2 -j DROP

Rules examples

Allow Loopback Connections

iptables -A INPUT -i lo -j ACCEPTiptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Allow Established Outgoing Connections

iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT

Internal to External

iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

Drop Invalid Packets

iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Block an IP Address

iptables -A INPUT -s 192.168.1.10 -j DROP

Block and IP Address and Reject

iptables -A INPUT -s 192.168.1.10 -j REJECT

Block Connections to a Network Interface

iptables -A INPUT -i eth0 -s 192.168.1.10 -j DROP

Allow All Incoming SSH

iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow Incoming SSH from Specific IP address or subnet

iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow Outgoing SSH

iptables -A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow Incoming Rsync from Specific IP Address or Subnet

iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 873 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 873 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow Incoming HTTP

iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow Incoming HTTPS

iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow Incoming HTTP and HTTPS

iptables -A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow MySQL from Specific IP Address or Subnet

iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3306 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow MySQL to Specific Network Interface

iptables -A INPUT -i eth1 -p tcp --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth1 -p tcp --sport 3306 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow PostgreSQL from Specific IP Address or Subnet

iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 5432 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 5432 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow PostgreSQL to Specific Network Interface

iptables -A INPUT -i eth1 -p tcp --dport 5432 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth1 -p tcp --sport 5432 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Block Outgoing SMTP Mail

iptables -A OUTPUT -p tcp --dport 25 -j REJECT

Allow All Incoming SMTP

iptables -A INPUT -p tcp --dport 25 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 25 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow All Incoming IMAP

iptables -A INPUT -p tcp --dport 143 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 143 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow All Incoming IMAPS

iptables -A INPUT -p tcp --dport 993 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 993 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow All Incoming POP3

iptables -A INPUT -p tcp --dport 110 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 110 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Allow All Incoming POP3S

iptables -A INPUT -p tcp --dport 995 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 995 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Drop Private Network Address On Public Interface

iptables -A INPUT -i eth1 -s 192.168.1.0/24 -j DROP
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

Drop All Outgoing to Facebook Networks

Get Facebook AS:

whois -h v4.whois.cymru.com " -v $(host facebook.com | grep "has address" | cut -d " " -f4)" | tail -n1 | awk '{print $1}'

Drop:

for i in $(whois -h whois.radb.net -- '-i origin AS1273' | grep "^route:" | cut -d ":" -f2 | sed -e 's/^[ \t]*//' | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 | cut -d ":" -f2 | sed 's/$/;/') ; do  iptables -A OUTPUT -s "$i" -j REJECTdone

Log and Drop Packets

iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: "
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

By default everything is logged to /var/log/messages file:

tail -f /var/log/messagesgrep --color 'IP SPOOF' /var/log/messages

Log and Drop Packets with Limited Number of Log Entries

iptables -A INPUT -i eth1 -s 10.0.0.0/8 -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix "IP_SPOOF A: "
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

Drop or Accept Traffic From Mac Address

iptables -A INPUT -m mac --mac-source 00:0F:EA:91:04:08 -j DROP
iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 00:0F:EA:91:04:07 -j ACCEPT

Block or Allow ICMP Ping Request

iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP

Specifying Multiple Ports with multiport

iptables -A INPUT -i eth0 -p tcp -m state --state NEW -m multiport --dports ssh,smtp,http,https -j ACCEPT

Load Balancing with random* or nth*

_ips=("172.31.250.10" "172.31.250.11" "172.31.250.12" "172.31.250.13")for ip in "${_ips[@]}" ; do  iptables -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW -m nth --counter 0 --every 4 --packet 0 \    -j DNAT --to-destination ${ip}:80done

or

_ips=("172.31.250.10" "172.31.250.11" "172.31.250.12" "172.31.250.13")for ip in "${_ips[@]}" ; do  iptables -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW -m random --average 25 \    -j DNAT --to-destination ${ip}:80done

Restricting the Number of Connections with limit and iplimit*

iptables -A FORWARD -m state --state NEW -p tcp -m multiport --dport http,https -o eth0 -i eth1 -m limit --limit 20/hour --limit-burst 5 -j ACCEPT

or

iptables -A INPUT -p tcp -m state --state NEW --dport http -m iplimit --iplimit-above 5 -j DROP

Maintaining a List of recent Connections to Match Against

iptables -A FORWARD -m recent --name portscan --rcheck --seconds 100 -j DROPiptables -A FORWARD -p tcp -i eth0 --dport 443 -m recent --name portscan --set -j DROP

Matching Against a string* in a Packet’s Data Payload

iptables -A FORWARD -m string --string '.com' -j DROP
iptables -A FORWARD -m string --string '.exe' -j DROP

Time-based Rules with time*

iptables -A FORWARD -p tcp -m multiport --dport http,https -o eth0 -i eth1 -m time --timestart 21:30 --timestop 22:30 --days Mon,Tue,Wed,Thu,Fri -j ACCEPT

Packet Matching Based on TTL Values

iptables -A INPUT -s 1.2.3.4 -m ttl --ttl-lt 40 -j REJECT

Protection against port scanning

iptables -N port-scanningiptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURNiptables -A port-scanning -j DROP

SSH brute-force protection

iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --setiptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

Syn-flood protection

iptables -N syn_floodiptables -A INPUT -p tcp --syn -j syn_floodiptables -A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN
iptables -A syn_flood -j DROPiptables -A INPUT -p icmp -m limit --limit  1/s --limit-burst 1 -j ACCEPT
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j LOG --log-prefix PING-DROP:
iptables -A INPUT -p icmp -j DROPiptables -A OUTPUT -p icmp -j ACCEPT

Mitigating SYN Floods With SYNPROXY

iptables -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack
iptables -A INPUT -p tcp -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Block New Packets That Are Not SYN

iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

or

iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

Force Fragments packets check

iptables -A INPUT -f -j DROP

XMAS packets

iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

Drop all NULL packets

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

Block Uncommon MSS Values

iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

Block Packets With Bogus TCP Flags

iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

Block Packets From Private Subnets (Spoofing)

_subnets=("224.0.0.0/3" "169.254.0.0/16" "172.16.0.0/12" "192.0.2.0/24" "192.168.0.0/16" "10.0.0.0/8" "0.0.0.0/8" "240.0.0.0/5")for _sub in "${_subnets[@]}" ; do  iptables -t mangle -A PREROUTING -s "$_sub" -j DROPdoneiptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP

Saving Rules

On Debian Based systems:

netfilter-persistent save

On RedHat Based systems

service iptables save

References