A firewall on Debian
Build a Debian firewall with nftables, from a host firewall to an office router with NAT and port forwards: safe changes with a timed rollback, sets and maps, logging and packet tracing, and what iptables really is on Debian 13.
By the end you will be able to:
- Explain tables, chains, hooks, priorities and policies, and why every chain on a hook must accept a packet
- Write and persist a host firewall, and change it remotely with a check and a timed rollback
- Turn a Debian machine into a router firewall with forwarding, masquerade, a port forward and a forward policy
- Use sets, dynamic sets and maps, and find a dropped packet with counters, logs and nft monitor trace
- Recognise iptables-nft, translate iptables rules, and avoid clashes with other software's rules
Prerequisites: Linux Network Connectivity
Every packet a Linux machine receives, sends or routes passes through netfilter, the packet-filtering framework inside the kernel. You don't talk to netfilter directly; you load rules into it with a tool. On Debian 13 that tool is nftables (the nft command), which replaced the older iptables family. iptables still exists, but on a current Debian system it's a compatibility layer that writes nftables rules underneath, and that matters as soon as both are in use. This lesson covers both.
A fresh Debian install has no firewall at all. The nftables package is installed, but its service is disabled, and its default configuration has no rules and accepts everything. In the lab, the internet host can reach the new server's SSH port straight away.
What you'll build
One Debian 13 machine, fw, protects itself and then routes for a small office:
- A host firewall: SSH only from the office, everything else dropped.
- Safe changes: checking a ruleset before loading it, and a timed rollback, so a mistake can't lock you out for good.
- A router firewall with NAT and a port forward, and why NAT on its own is not a firewall.
- Sets and maps, logging and packet tracing.
- iptables: what it really is on Debian 13, translating old rules, and what happens when the two meet.
The VPN lessons, OpenVPN on Debian and WireGuard on Debian, use exactly this kind of ruleset on their servers; this is where it's explained. Every output is from a real run of the lab.
- Protecting the firewall itself. Packets addressed to fw go through the input hook. SSH is allowed only from the admin PC on the LAN; from the internet it's dropped.
- The office to the internet. Traffic through fw goes through the forward hook, then masquerade rewrites the source to 203.0.113.10, the only address the internet can reply to.
- A port forward. A connection to 203.0.113.10:8080 is rewritten (DNAT) to the office web server, 10.10.0.80:80, before routing, and the forward chain accepts it because conntrack knows it was DNATed.
- NAT is not a firewall. A neighbour on the WAN segment can route 10.10.0.0/24 at fw. Only the forward chain's drop policy stops it reaching the office directly.
root@fw:~# cat /etc/debian_version; dpkg-query -W nftables iptables; uname -r
13.7
iptables 1.8.11-2
nftables 1.1.3-1
7.0.14-linuxkit- Line 2: Debian 13 (trixie).
- Lines 3–4: iptables 1.8 and nftables 1.1, both installed by default on a Debian server.
root@inet:~# nc -zv -w 2 203.0.113.10 22
Connection to 203.0.113.10 22 port [tcp/ssh] succeeded!- Lines 1–2: SSH answers anyone: there's no firewall until you configure one.