Basic Ubuntu Hardening: Default iptables rule preset for your machines

Introduction
Let the one who has always meticulously secured all their public servers cast the first stone. For me, it was standard practice to configure a server specifically for the intended use — delivering the service was the priority. Properly securing the machine was always postponed, meaning: never.
I won't pretend life harshly taught me to secure servers. It simply started bothering me enough that I prepared a default configuration template for my servers.
Use Case
- Time saver: add this ready-to-use step-by-step iptables setup guide to your notes for configuring new machines.
Prerequisites
- Estimated time: 5 minutes per server.
- Ubuntu 24.04 (should work on other Ubuntu versions too) with root access.
Step-by-Step Guide
At this stage, I assume you have the default Ubuntu configuration and have not yet modified iptables settings. The following steps will overwrite all existing iptables rules on your server. Keep this in mind if you apply this guide on a server already running other public services.
Installing iptables-persistent
This package is a helper that makes it easier to keep your rules after reboot or shutdown.
sudo apt updatesudo apt install iptables-persistentsudo nano /etc/iptables/rules.v4Paste the following config into /etc/iptables/rules.v4 file:
*filter
# Default policies for each chain
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]
# Accept SSH
-A TCP -p tcp --dport 22 -j ACCEPT
# Accept established, related (e.g. replies to outgoing connections) input and loopback
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP
# Direct packets to protocol-specific chains
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
# Reject everything else from this point
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
COMMIT
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMITApply the iptables rules from the file we just edited:
sudo iptables-restore -t /etc/iptables/rules.v4I do a similar setup for IPv6. I don't use this protocol at all on my servers, so I completely restrict IPv6 traffic.
sudo nano /etc/iptables/rules.v6Paste the following into /etc/iptables/rules.v6:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
*raw
:PREROUTING DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
*nat
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT
*security
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
*mangle
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMITApply IPv6 iptables rules:
ip6tables-restore -t /etc/iptables/rules.v6Reload netfilter-persistent service:
service netfilter-persistent reloadFor Docker users
Docker manages communication in its virtual networks using iptables rules. If you have running containers on the server, after applying this guide and removing existing rules, you may encounter connectivity issues with your containers. I solve this by always rebooting the machine at the end:
sudo rebootDocker will automatically recreate all necessary rules on service start. Alternatively, you can restart just the docker service, but rebooting is better as it also tests rule restoration and final configuration.
Do not rely solely on this guide for securing production infrastructure. If your server is critical or holds important data, consider consulting an expert individually.
