The Linux Five Minute Firewall

A practical iptables setup guide for Debian-based servers

Introduction

A firewall or packet filter is an important security tool for your headless Linux server. This guide gives you the framework for setting up a firewall that filters all incoming connections by default and only allows access to the ports you specify.

The first time you follow this guide it will take more than five minutes. The idea is that once you have done it a couple of times you can quickly spin up a new server with a reproducible firewall that is exactly to your specifications.

These instructions apply to Debian-based systems. This guide uses the following:

The Setup

These instructions simulate building a firewall for a Minecraft server. The process is identical for web, DNS, or email servers — only the ports change.

This firewall will block all incoming requests by default and open only these ports:

The steps are:

Step 1 — Verify iptables

Check that your iptables packet filter is ready. It is installed by default on Ubuntu. The following command shows the default setup is wide open — all connections are accepted on every port. On a fresh install, most ports except 22 (SSH) are closed by default anyway.

Command

sudo iptables -nL

Output

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

Good. Now let’s get rules in place before anything else.

Step 2 — Create the Scripts

Create three empty scripts in /etc/network and lock down their permissions so only root can read them.

Create the files

cd /etc/network
sudo touch firewall firewall-down firewall-reload
sudo chmod 700 firewall firewall-down firewall-reload

Script 1 — firewall

Open /etc/network/firewall and paste in the following script. This is the main firewall that activates your rules.

/etc/network/firewall

#!/bin/bash
#
# iptables example configuration script

# Drop ICMP echo-request messages sent to broadcast or multicast addresses
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Drop source routed packets
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route

# Enable TCP SYN cookie protection from SYN floods
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

# Don't accept ICMP redirect messages
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects

# Don't send ICMP redirect messages
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

# Enable source address spoofing protection
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

# Log packets with impossible source addresses
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

# Flush all chains
/sbin/iptables --flush

# Allow unlimited traffic on the loopback interface
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT

# Set default policies
/sbin/iptables --policy INPUT DROP
/sbin/iptables --policy OUTPUT DROP
/sbin/iptables --policy FORWARD DROP

# Previously initiated and accepted exchanges bypass rule checking
# Allow unlimited outbound traffic
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Ratelimit SSH for attack protection
/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# Allow certain ports to be accessible from the outside
/sbin/iptables -A INPUT -p tcp --dport 25565 -m state --state NEW -j ACCEPT  #Minecraft
/sbin/iptables -A INPUT -p tcp --dport 8123  -m state --state NEW -j ACCEPT  #Dynmap plugin

# Other rules for future use. Uncomment to activate.
# /sbin/iptables -A INPUT -p tcp --dport 80  -m state --state NEW -j ACCEPT  # http
# /sbin/iptables -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT  # https

# UDP packet rule — example only
# /sbin/iptables -A INPUT -p udp --dport 5021 -m state --state NEW -j ACCEPT

# Allow pinging of your server
/sbin/iptables -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Drop all other traffic
/sbin/iptables -A INPUT -j DROP

# Print the activated rules to the console
/sbin/iptables -nL

Engage the firewall and review each line to understand what it does — commented lines give hints.

Activate

sudo /etc/network/firewall

Script 2 — firewall-down

Open /etc/network/firewall-down and paste in the following. This flushes all rules and re-opens all traffic so you can reconnect if needed.

/etc/network/firewall-down

#!/bin/bash
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -t nat -F
/sbin/iptables -t nat -X
/sbin/iptables -t mangle -F
/sbin/iptables -t mangle -X

# Open up all traffic so you can reconnect
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -P OUTPUT ACCEPT

# Print rules to the console
/sbin/iptables -nL

Script 3 — firewall-reload

Open /etc/network/firewall-reload and paste in the following. Use this after editing the firewall script to flush and reload changes without rebooting.

/etc/network/firewall-reload

#!/bin/bash
/etc/network/firewall-down
/etc/network/firewall

Reload

sudo /etc/network/firewall-reload

Step 3 — Making Rules Permanent

The firewall rules are lost on reboot until you persist them. Install iptables-persistent to activate the firewall automatically before the network interface comes up.

Install

sudo apt install iptables-persistent

When prompted, say Yes to save current IPv4 rules and Yes to save current IPv6 rules.

Screenshot: save current IPv4 rules prompt

The iptables-persistent installer prompting to save current IPv4 rules.

Once installed, netfilter-persistent is available at /etc/init.d/netfilter-persistent. Its available commands are:

Usage

sudo /etc/init.d/netfilter-persistent {start|restart|reload|force-reload|save|flush}

Save the current rules to make them boot-persistent:

Save rules

sudo /etc/init.d/netfilter-persistent save

From now on, after modifying /etc/network/firewall and running firewall-reload, always follow up with netfilter-persistent save to make the changes permanent.

Viewing Your Current Rules

Use iptables -nL at any time to see the active ruleset.

Output with rules active

al@sandbox:/etc$ sudo iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW recent: UPDATE seconds: 60 hit_count: 4 name: DEFAULT side: source mask: 255.255.255.255
           tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:25565 state NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8123 state NEW
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8 state NEW,RELATED,ESTABLISHED
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state NEW,RELATED,ESTABLISHED

Closing Comments

This guide provides a framework for quickly setting up a secure and reproducible iptables firewall on any Debian-based server or desktop. Adapt the open ports to match your own services.

If you spot any errors or have feedback, feel free to contact me directly.