Sunday, January 5

IP Tables

Name

iptables – administration tool for IPv4 packet filtering and NAT

Synopsis

iptables [-t table] -[AD] chain rule-specification [options]
iptables [-t table] -I
 chain [rulenum] rule-specification [options]
iptables [-t table] -R
 chain rulenum rule-specification [options]
iptables [-t table] -D
 chain rulenum [options]
iptables [-t table] -[LFZ]
 [chain] [options]
iptables [-t table] -N
 chain
iptables [-t table] -X
 [chain]
iptables [-t table] -P
 chain target [options]
iptables [-t table] -E
 old-chain-name new-chain-name

Description

Iptables is used to set up, maintain, and inspect the tables of IP packet filter rules in the Linux kernel. Several different tables may be defined. Each table contains a number of built-in chains and may also contain user-defined chains.

Each chain is a list of rules which can match a set of packets. Each rule specifies what to do with a packet that matches. This is called a ‘target’, which may be a jump to a user-defined chain in the same table.

In this guide, I’ll explain to you how you can secure your server by dropping all incoming traffic that you haven’t explicitly allowed.

The Rules

Accept loopback traffic

In order for your server to communicate with itself, you’ll need to accept loopback (127.0.0.1) traffic.

sudo iptables -A INPUT -i lo -p all -j ACCEPT
Bash

Accept return traffic

Accept related and established traffic. You can read more about connection states here.

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Bash

Accept incoming connections to specific ports

Open the ports for whatever services you’re running. At a minimum, you’ll need to open up the port for SSH, which is by default on port 22.

Accept SSH connections

sudo iptables -I INPUT -p tcp --dport 22 -j ACCEPT
Bash

Accept HTTP connections

sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
Bash

Accept HTTPS connections

sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT
Bash

Drop policy

Set the policy to drop all incoming traffic that’s not explicitly permitted

sudo iptables -P INPUT DROP
Bash

Iptables New Server Template

Here is the template I use for setting up new servers:

# Flush existing rules
sudo iptables -F

# Accept loopback traffic
sudo iptables -A INPUT -i lo -p all -j ACCEPT

# Accept return traffic
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Accept SSH & HTTP traffic
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# Set default INPUT policy to DROP
sudo iptables -P INPUT DROP

# Set default FORWARD policy to DROP
sudo iptables -P FORWARD DROP

# Set default OUTPUT policy to ACCEPT
sudo iptables -P OUTPUT ACCEPT
Bash

Make Iptables Persistent

Everytime that your server is restarted, all of the Iptables rules will be flushed and no longer exist.

One way to make the rules persistent is to use a package called iptables-persistent

sudo apt-get update
sudo apt-get install iptables-persistent
Bash

Every time that you modify the Iptables rules, if you want to make the changes persist after a reboot, you’ll need to save them.

sudo iptables-save > /etc/iptables/rules.v4
Bash

Common Commands

List all of the rules

sudo iptables -L
Bash

Flush (delete) all of the rules

sudo iptables -F
Bash

Delete specific rule

Start off by listing all of the rules with line numbers.

sudo iptables -L INPUT --line-numbers
Bash
Chain INPUT (policy DROP)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere
2    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
3    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
4    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
Bash

In this example, if I wanted to delete the rule which permits HTTP traffic, I’d type:

sudo iptables -D INPUT 4
Bash

Accept incoming ping requests

sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
Bash

Block a specific IP address

sudo iptables -A INPUT -s "IP_ADDRESS_TO_BLOCK" -j DROP
Bash

Log dropped connection attempts

sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROPPED:" --log-level 7
sudo iptables -A INPUT -j DROP
Bash

Log files will be stored in the following locations:

Ubuntu and Debian: /var/log/kern.log

CentOS/RHEL and Fedora: /var/log/messages

Did you find this guide useful? Are you having trouble and locked out of your server? Let us know in the comments below!