Linux Firewalls with nftables: Core Concepts
Linux Firewalls with nftables: Core Concepts
A Linux firewall decides which network packets are allowed to enter, leave, or pass through the system. nftables is the modern framework that replaced iptables, providing a unified syntax for IPv4, IPv6, ARP, and bridge traffic, with atomic rule updates that eliminate the race conditions of the older iptables-restore approach.
Why nftables Replaced iptables
iptables had four separate kernel modules (iptables, ip6tables, arptables, ebtables) each with its own syntax and rule storage. A rule update required flushing and reloading the entire rule set, creating a window where the firewall was in an inconsistent state.
nftables unified these into a single framework with:
- One syntax for all protocol families
- Atomic updates — the entire rule set is replaced in a single transaction
- Maps and sets for efficient matching against large lists of IPs or ports
- Better performance through bytecode compilation in the kernel
The nftables Architecture
nftables organizes rules into tables, which contain chains, which contain rules.
- Table — A container for chains, bound to a protocol family (ip, ip6, inet, arp, bridge, netdev).
- Chain — A sequence of rules attached to a hook in the network stack. Chains have a type (filter, route, nat) and a priority that determines evaluation order.
- Rule — A single match-and-action statement within a chain.
The five chain hooks in the network stack are:
| Hook | Direction | Purpose |
|---|---|---|
| prerouting | Incoming | Before routing decision (DNAT, filtering) |
| input | Incoming | Packets destined for the local system |
| forward | Through | Packets routed through the system |
| output | Outgoing | Packets generated by the local system |
| postrouting | Outgoing | After routing decision (SNAT, masquerade) |
Basic Rule Syntax
# Create a table
nft add table inet filter
# Create a chain for incoming traffic
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
# Allow established connections
nft add rule inet filter input ct state established,related accept
# Allow loopback
nft add rule inet filter input iif lo accept
# Allow SSH
nft add rule inet filter input tcp dport 22 accept
# Drop everything else (implicit with policy drop)
The inet family handles both IPv4 and IPv6 in a single table, which is the recommended approach for most use cases.
Sets and Maps for Efficient Matching
Instead of writing dozens of individual rules, nftables lets you define sets:
# Create a set of allowed IPs
nft add set inet filter allowed_ips { type ipv4_addr \; flags interval \; }
# Populate the set
nft add element inet filter allowed_ips { 10.0.0.0/8, 192.168.1.0/24 }
# Use the set in a rule
nft add rule inet filter input ip saddr @allowed_ips tcp dport 22 accept
With flags interval, nftables uses an interval tree for O(log n) lookups instead of linear scanning, making it practical to match against thousands of IPs.
Where It Fits
nftables operates at the network layer. It controls which packets reach the system but does not inspect application-layer content. For application-layer filtering, you need a web application firewall (WAF) or proxy. Study SSH hardening first to understand what services need to be protected, then use nftables to restrict access to those services.
Linux Firewalls with nftables: Practice
Linux Firewall with nftables: Practice
Firewall rules are unforgiving — a single mistake can lock you out of a remote server. The exercises below build up from a basic web server configuration to a more complex multi-zone setup.
Exercise 1: Basic Web Server Firewall
Configure nftables to allow only HTTP, HTTPS, and SSH, dropping everything else:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established and related connections
ct state established,related accept
# Allow loopback
iif lo accept
# Allow ICMP (ping)
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# Allow SSH
tcp dport 22 accept
# Allow HTTP and HTTPS
tcp dport { 80, 443 } accept
# Log and drop everything else
limit rate 5/second burst 10 packets log prefix "nft-drop: " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Apply the ruleset:
nft -f firewall.nft
nft list ruleset # Verify
The limit rate 5/second on the log rule prevents log flooding from a port scan while still capturing evidence of the scan.
Exercise 2: Rate Limiting to Prevent Brute Force
Protect SSH from brute-force attacks by rate-limiting new connections:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
# Rate-limit SSH: max 3 new connections per minute per source IP
tcp dport 22 ct state new limit rate 3/minute accept
tcp dport { 80, 443 } accept
}
}
The ct state new ensures the rate limit only applies to new connections, not to packets belonging to already-established sessions.
Exercise 3: NAT and Port Forwarding
If your server acts as a gateway for internal machines, configure source NAT (masquerading):
table ip nat {
chain postrouting {
type nat hook postrouting priority 100;
# Masquerade outgoing traffic on the external interface
oifname "eth0" masquerade
}
}
For port forwarding (destination NAT):
table ip nat {
chain prerouting {
type nat hook prerouting priority 0;
# Forward port 8080 to internal server
tcp dport 8080 dnat to 192.168.1.50:80
}
}
Check Your Understanding
- Why is
ct state established,related accepttypically the first rule in the input chain? - What happens if you set
policy dropbut forget to allow loopback traffic? - How does
flags intervalin a set improve performance over a simple list of IPs?
Linux Firewalls with nftables: Trade-offs and Interviews
Linux Firewalls with nftables: Trade-offs and Interviews
nftables is powerful but not always the right tool. Understanding its limitations and alternatives is critical for making sound architectural decisions.
When nftables Is the Wrong Tool
- Cloud environments: In AWS, GCP, or Azure, security groups and network ACLs operate at the hypervisor level, before traffic reaches your VM. Managing firewall rules in both places creates confusion. Use cloud-native controls for network-level filtering and nftables only for host-level granularity.
- Container orchestration: Kubernetes Network Policies and service meshes (Istio, Linkerd) handle pod-to-pod traffic. nftables rules on the host can conflict with kube-proxy's rules.
- Application-layer filtering: nftables matches on IP, port, and protocol. It cannot inspect HTTP headers, SQL queries, or JSON payloads. For that, you need a WAF like ModSecurity or a reverse proxy with filtering capabilities.
Performance Considerations
nftables compiles rules to bytecode that runs in the kernel, which is significantly faster than iptables' linear rule evaluation. However:
- Large rule sets still have a cost. A ruleset with 10,000 rules will be slower than one with 100 rules, even with bytecode compilation.
- Sets with interval flags use O(log n) lookup, but a set without flags uses O(n) linear scan. For large IP lists, always use
flags interval. - Connection tracking (conntrack) consumes memory. On a busy server, the conntrack table can fill up, causing new connections to be dropped. Monitor with
conntrack -Cand adjustnf_conntrack_maxif needed.
Persistence Across Reboots
nftables rules are not persistent by default. After a reboot, the ruleset is empty. To persist:
# Save current ruleset
nft list ruleset > /etc/nftables.conf
# Enable the service to load on boot
systemctl enable nftables
The nftables.service reads /etc/nftables.conf at startup. Without this step, your firewall is inactive after every reboot.
How This Comes Up in Interviews
- "How do you prevent locking yourself out when applying firewall rules?" Use a scheduled job to reset the firewall after a timeout:
nft flush ruleset && nft -f /etc/nftables.confrun viaatorsystemd-runwith a 5-minute delay. If your rules are wrong, the reset restores access. - "When would you use nftables vs. cloud security groups?" Use cloud security groups for coarse-grained network segmentation (which subnets can reach the VM) and nftables for host-level granularity (which users can access which services, rate limiting, logging).
- "How do you handle firewall rules in a containerized environment?" Let the orchestrator (Kubernetes Network Policies, Calico) handle inter-pod traffic. Use nftables only for host-level protections like rate limiting and logging.
Practice Problems
Solution
```bash
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
ip saddr 10.0.0.0/8 tcp dport 22 accept
tcp dport { 80, 443 } accept
limit rate 5/second burst 10 packets log prefix "dropped: " drop
}
}
``` Solution
The filter chain with input hook filters packets destined for the local system — it decides what the host accepts. The nat chain with prerouting hook modifies packets before routing — it is used for DNAT (port forwarding). Use filter/input for access control and nat/prerouting for destination NAT. Quiz
1. What is the primary advantage of nftables over iptables?
2. In nftables, what does 'ct state established,related accept' accomplish?
3. What does 'flags interval' in an nftables set provide?
4. Why are nftables rules not persistent across reboots by default?
Flashcards
Question
What are the five chain hooks in nftables?
Click to reveal answer
Answer
prerouting, input, forward, output, postrouting — each corresponds to a point in the network stack's packet processing pipeline.
Question
What does 'policy drop' on a chain mean?
Click to reveal answer
Answer
If no rule in the chain matches a packet, the packet is dropped. This is the secure default for input and forward chains.
Question
Why use the 'inet' table family instead of 'ip'?
Click to reveal answer
Answer
The 'inet' family handles both IPv4 and IPv6 in a single table, avoiding duplicate rules for each protocol.
Question
What is the purpose of 'ct state new' in a rate-limiting rule?
Click to reveal answer
Answer
It ensures the rate limit only applies to new connections, not to packets belonging to already-established sessions.
Question
How do you persist nftables rules across reboots?
Click to reveal answer
Answer
Save with 'nft list ruleset > /etc/nftables.conf' and enable the nftables.service to load it at boot.
Revision Notes
Key Takeaways
- 1. nftables replaces iptables with unified syntax and atomic rule updates.
- 2. The inet family handles both IPv4 and IPv6 in a single table.
- 3. policy drop is the secure default for input and forward chains.
- 4. Sets with flags interval provide O(log n) lookup for large IP lists.
- 5. Rules are not persistent by default — save to /etc/nftables.conf and enable the service.
Interview Tips
- • Explain the table-chain-rule hierarchy and how hooks map to the network stack.
- • Discuss when nftables is the wrong tool (cloud environments, container orchestration).
- • Describe how to prevent lockout when applying firewall rules (scheduled reset).
- • Connect nftables to defense-in-depth: it is one layer alongside SSH hardening and audit logging.
Cheat Sheet
nftables Cheat Sheet
Phase: Linux and Windows Security Administration | Level: intermediate
Architecture:
- Table → Chain → Rule
- Five hooks: prerouting, input, forward, output, postrouting
- Chain types: filter, route, nat
Basic Commands:
nft add table inet filter— Create a tablenft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }— Create a chainnft add rule inet filter input ct state established,related accept— Allow establishednft list ruleset— Show current rulesnft flush ruleset— Remove all rules
Persistence:
nft list ruleset > /etc/nftables.confsystemctl enable nftables
Key Patterns:
ct state established,related accept— First rule in input chainiif lo accept— Allow loopbacktcp dport { 80, 443 } accept— Multiple portslimit rate 5/second burst 10 packets log prefix "drop: " drop— Rate-limited logging
Tags: linux, firewall
Continue Learning
Before You Start
- No prerequisites listed.