I keep seeing people overcomplicate their firewall setup with fancy wrappers and GUI tools. iptables is not that hard, and understanding it directly saves you when those wrappers break ( because they always do at the worst time ).
Here's how I set up iptables on every new server.
The Three Default Chains
iptables has three built-in chains: INPUT, OUTPUT, and FORWARD. INPUT handles traffic coming into the server, OUTPUT handles traffic going out, and FORWARD handles traffic being routed through the server ( which you only care about if it's a gateway ).
Rules are processed top to bottom. First match wins. That's the whole model.
Step 1: Set Default Policies
Before adding any rules, lock everything down. Accept all outbound, drop all inbound and forwarded.
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPTIf you're doing this over SSH, congratulations you just locked yourself out. Add the SSH rule first. I'll get to that.
Step 2: Allow Established Connections
This one rule covers 90% of return traffic. Without it, your server can send requests out but can't receive the responses.
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTStep 3: Allow Loopback
Local services talk on loopback. Break this and things get weird fast.
iptables -A INPUT -i lo -j ACCEPTStep 4: Open the Ports You Need
SSH, HTTP, HTTPS. That's what most web servers need.
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPTIf you changed your SSH port ( you should ), swap 22 for whatever you picked.
Step 5: Save the Rules
iptables rules vanish on reboot. On Debian/Ubuntu:
apt install iptables-persistent
netfilter-persistent saveOn RHEL/CentOS:
iptables-save > /etc/sysconfig/iptablesUseful One-Liners
List all rules with line numbers ( so you can delete by number ):
iptables -L -n -v --line-numbersDelete rule number 3 from INPUT:
iptables -D INPUT 3Block a specific IP:
iptables -A INPUT -s 192.168.1.100 -j DROPRate-limit SSH ( max 3 connections per minute from any IP ):
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROPConclusion
That's it. Five rules and your server is locked down. No ufw, no firewalld, no wrappers. Just iptables. If you need more complex stuff ( NAT, port forwarding, custom chains ), the same pattern applies: add the rule, test it, save it.
One gotcha: if you're on a VPS provider that offers a cloud firewall ( Hetzner, DigitalOcean, etc. ), use both. Defense in depth. The cloud firewall drops traffic before it even reaches your kernel.