Skip to main content

Linux Firewall

A Linux firewall controls which network packets are allowed into, out of, or through a server using rules evaluated by the kernel's netfilter framework. Tools like iptables, nftables, and ufw write rules into netfilter. The default-deny model blocks all traffic not explicitly permitted.

Understanding Linux Firewalls

What Is a Linux Firewall in Simple Terms

A firewall is a gatekeeper for network traffic. Every packet arriving at or leaving a server passes through the firewall's ruleset. The firewall checks each packet against its rules in order and takes an action: ACCEPT (let it through), DROP (silently discard), or REJECT (discard and notify sender).

Without a firewall, every port on every service on the server is reachable by anyone on the internet. With a firewall configured with default-deny, only explicitly permitted traffic gets through.

How It Works

◈ DIAGRAM
+------------------------------------------+
| Packet arrives at server |
+------------------------------------------+
|
v
+------------------------------------------+
| INPUT chain rules (top to bottom) |
| Rule 1: Allow SSH from 10.0.0.0/8 -> OK |
| Rule 2: Allow HTTPS from any -> OK |
| Rule 3: Allow established connections |
| Default: DROP (no match = blocked) |
+------------------------------------------+
|
match found
|
ACCEPT or DROP/REJECT

Three layers in production:

◈ DIAGRAM
+------------------------------------------+
| Cloud Security Group (AWS/GCP/Azure) |
| First layer -- blocks before reaching VM |
+------------------------------------------+
| Host Firewall (iptables/ufw/nftables) |
| Second layer -- on the server itself |
+------------------------------------------+
| Application firewall (nginx, AppArmor) |
| Third layer -- at the application level |
+------------------------------------------+

Practical Commands

Bash
## UFW (Uncomplicated Firewall) -- Ubuntu/Debian standard
## Check status
sudo ufw status verbose
## Enable with default-deny incoming
sudo ufw default deny incoming
sudo ufw default allow outgoing
## Allow specific services
sudo ufw allow 22/tcp ## SSH
sudo ufw allow 80/tcp ## HTTP
sudo ufw allow 443/tcp ## HTTPS
sudo ufw allow 5432/tcp ## PostgreSQL
## Allow from specific IP only
sudo ufw allow from 10.0.0.0/8 to any port 22
sudo ufw allow from 52.66.1.100 to any port 5432
## Enable the firewall
sudo ufw enable
## View rules with numbers (for deletion)
sudo ufw status numbered
## Delete a rule by number
sudo ufw delete 3
## iptables -- lower level, more powerful
sudo iptables -L -n -v ## list all rules
sudo iptables -L INPUT -n -v ## list INPUT chain
## Save rules permanently
sudo iptables-save > /etc/iptables/rules.v4

Troubleshooting

Symptom Command What to Check
Service unreachable sudo ufw status Port not allowed in firewall
SSH locked out Boot into recovery mode Allow port 22 from your IP
Docker ports bypassing ufw sudo iptables -L DOCKER Docker modifies iptables directly
Rule not taking effect sudo ufw reload Reload after changes
Common Mistake

Docker bypasses ufw. When you run docker run -p 80:80, Docker adds its own iptables rules that allow port 80 from anywhere, ignoring your ufw rules. To prevent this, set DOCKER_OPTS="--iptables=false" or use Docker's internal network controls.

Security

Always test firewall rules in a second terminal before closing your current SSH session. If you lock yourself out, you need console access to recover. Enable port 22 from your IP before enabling default-deny.

Frequently Asked Questions

What's the actual relationship between iptables, nftables, and netfilter?

netfilter is the kernel framework that intercepts and processes packets at defined hook points (like before routing, before local delivery); iptables and nftables are userspace tools that write rule sets into netfilter — they don't filter packets themselves, they configure the kernel to do it. nftables is the newer replacement (default on most modern distros since around 2020) with a more efficient single ruleset structure, while iptables remains widely used and is often implemented as a compatibility shim over nftables under the hood.

What's a common mistake that locks admins out of a remote server while configuring firewall rules?

Applying a default-deny policy (or flushing existing rules) over an SSH session without first ensuring a rule explicitly allows the current SSH connection — the moment the policy takes effect, the admin's own connection gets cut and there's no way back in without console/out-of-band access. The safe pattern is either testing on a rule set with a timed rollback, or explicitly allowing the current source IP on the SSH port before applying a default-deny policy.