Linux Firewall with nftables
You learn nftables — the modern successor to iptables, now the default on 75% of Linux servers. You build a production-grade firewall step by step: create tables and chains, allow SSH and HTTP/S, block everything else, and persist your rules. 6 tasks, about 75 minutes.
Build a production firewall with nftables
What is a firewall — and what is nftables?
A firewall is a filter that decides which network packets may reach a server and which are dropped. It is a server's first line of defence: without one, every open service is directly exposed to the internet.
nftables is the modern firewall framework of the Linux kernel. It replaces the older iptables and is the standard on most Linux servers today. You describe in a clear syntax what traffic is allowed — everything else is blocked.
The three building blocks of nftables
- Table: the top-level container for your rules. Its family defines what it applies to —
inetcovers both IPv4 and IPv6. - Chain: attaches to a hook, a fixed point in the kernel's packet path. The
inputchain handles all incoming packets. Every chain has a policy (default behaviour):policy dropmeans "drop everything that no rule explicitly allows" — the safe default-deny principle. - Rule: a single allowance inside a chain, e.g. "permit TCP port 22 (SSH)".
Your goal in this lesson
You build a production-grade firewall step by step: an inet table with an input chain (default drop) that allows only the essentials — SSH (port 22), HTTP (80), HTTPS (443), already-established connections, and local loopback. Finally you make the rules survive a reboot. The VM starts with no active firewall rules.
Exercises
1. Create inet table
Concept: table. The table is the top-level container in nftables — it will hold your chains and rules. The family defines which protocols it applies to:
inetmeans IPv4 and IPv6 together, so you maintain your rules only once.Create a table named
filterin theinetfamily:nft add table inet filterCheck:
nft list tableslists all tables —table inet filtermust appear.2. Create input chain with drop policy
Concept: chain & policy. A chain attaches to a hook — a fixed point in the kernel's packet path. The
inputhook intercepts all incoming packets. The policy is the default behaviour when no rule matches:policy drop= drop everything (default-deny). That is safer thanaccept, because you then explicitly allow only what you need.In the
inet filtertable, create aninputchain with a drop policy:nft 'add chain inet filter input { type filter hook input priority 0; policy drop; }'⚠️ Important: Once
policy dropis active, the firewall also blocks your own SSH connection — until you explicitly allow SSH in the next steps. On this practice VM that is harmless (the platform validator has its own access).Check:
nft list chain inet filter inputmust showpolicy drop.3. Allow established connections
Concept: connection tracking. The kernel remembers the state of every connection.
ct state established,relatedmatches packets that belong to an already-established connection (or are directly related to one, e.g. an FTP data channel).Why make it the first rule? Without it, the
droppolicy would also discard the reply packets of your own outbound connections (e.g. the response to anapt update). This rule lets exactly those legitimate replies back in — so it belongs at the very top.nft add rule inet filter input ct state established,related acceptCheck:
nft list chain inet filter inputcontainsct state established.4. Allow SSH, HTTP, and HTTPS
Concept: port &
dport. A port is the "door" to a specific service on the server.dport(destination port) is the target port of the incoming packet. You explicitly allow the services that should be reachable from outside:- 22 = SSH (remote access / administration)
- 80 = HTTP (unencrypted website, also used for the Let's Encrypt check)
- 443 = HTTPS (encrypted website)
Add three rules — one per port:
nft add rule inet filter input tcp dport 22 accept nft add rule inet filter input tcp dport 80 accept nft add rule inet filter input tcp dport 443 acceptCheck:
nft list chain inet filter inputshowsdport 22,dport 80anddport 443, each withaccept.5. Allow loopback interface
Concept: loopback (
lo). The loopback interfacelois the server's internal network interface to itself (address127.0.0.1). Many local services — databases, caches, mail — communicate exclusively overlo. If thedroppolicy also blocks loopback, these internal connections break — a common, hard-to-find bug.Allow all traffic that comes in over the
lointerface:nft add rule inet filter input iifname lo acceptiifname= input interface name, i.e. the interface the packet arrived on.Check:
nft list chain inet filter inputcontains anlorule withaccept.6. Persist the ruleset
Problem: nftables rules live only in memory (the kernel). After a reboot they would be gone — the server would stand there with no firewall. You therefore have to make them persistent, in two steps:
- Export the rules to a file:
/etc/nftables.confis the standard file nftables reads on startup. - Enable the service:
systemctl enable nftablesmakes nftables start automatically at boot and load/etc/nftables.conf.
nft list ruleset > /etc/nftables.conf systemctl enable nftablesCheck:
/etc/nftables.confcontainstable inet filter, andsystemctl is-enabled nftablesreportsenabled.- Export the rules to a file:
Now practice it yourself
Reading is good – doing is better. Start this course on a real Linux VM, right in your browser. A free account is all it takes.
Start for freeLab content under CC BY 4.0 – free to use with attribution (© TechLogia).
