nftables configuration alignment with CIS Ubuntu 22.04 LTS Benchmark v1.1.0.
All templates in this repository are designed to meet or exceed:
- CIS Benchmark Level 1 (essential security controls)
- CIS Benchmark Level 2 (defense-in-depth controls)
Benchmark: CIS Ubuntu Linux 22.04 LTS Benchmark v1.1.0 Section: 3.5 Firewall Configuration Last Verified: January 2026
Requirement: nftables package must be installed
Implementation:
sudo apt install nftablesVerification:
dpkg -s nftables | grep Status
# Expected: Status: install ok installed
nft --version
# Expected: nftables v0.9.3 or newerCompliance: ✅ All templates require nftables installation
Requirement: INPUT and FORWARD chains must have default deny policy
Implementation:
chain input {
type filter hook input priority 0; policy drop; # ← Default DENY
# ... rules ...
}
chain forward {
type filter hook forward priority 0; policy drop; # ← Default DENY
# ... rules ...
}
Verification:
sudo nft list ruleset | grep -E "policy (drop|reject)"
# Expected: policy drop (for input and forward)Compliance: ✅ All templates use policy drop by default
Requirement: Allow loopback traffic (localhost communication)
Implementation:
# Allow all traffic on loopback interface
iif lo accept
Why: Required for inter-process communication on localhost (127.0.0.1)
Verification:
sudo nft list chain inet filter input | grep "iif lo accept"
# Expected: iif lo acceptCompliance: ✅ All templates include loopback rule as first rule
Requirement: Allow established and related connections
Implementation:
# Allow established and related connections
ct state established,related accept
Why: Required for return traffic (e.g., responses to outgoing requests)
Verification:
sudo nft list chain inet filter input | grep "ct state"
# Expected: ct state established,related acceptCompliance: ✅ All templates include connection tracking as second rule
Requirement: Every open port must have an explicit allow rule
Implementation:
# Example: Allow SSH (port 22)
iifname $MGMT_INTERFACE tcp dport 22 accept comment "SSH"
# Example: Allow HTTP/HTTPS (ports 80, 443)
tcp dport { 80, 443 } accept comment "Web server"
Verification:
# List open ports
sudo ss -tulnp
# Check nftables rules for each open port
sudo nft list ruleset | grep "tcp dport"Compliance: ✅ All templates include explicit rules for all services
Requirement: nftables service must start on boot
Implementation:
sudo systemctl enable nftables.serviceVerification:
systemctl is-enabled nftables.service
# Expected: enabledCompliance: ✅ Deployment script enables service automatically
Requirement: Firewall rules must persist across reboots
Implementation:
# Rules are stored in /etc/nftables.conf
# Loaded by nftables.service on boot
sudo systemctl restart nftables.serviceVerification:
# Check config file exists
ls -l /etc/nftables.conf
# Test persistence (after reboot)
sudo reboot
# ... system reboots ...
sudo nft list ruleset # Rules should still be presentCompliance: ✅ All templates deploy to /etc/nftables.conf
Requirement: Protect against DoS/brute-force attacks
Implementation:
# SSH rate limiting (5 connections/minute)
tcp dport 22 ct state new limit rate over 5/minute counter log prefix "nft[ssh-ratelimit]: " reject
# HTTP rate limiting (100 requests/minute)
tcp dport { 80, 443 } ct state new limit rate over 100/minute counter drop
Verification:
sudo nft list ruleset | grep "limit rate"Compliance:
Requirement: Allow ICMP but rate-limit to prevent ping floods
Implementation:
# Allow ICMP but rate-limit
ip protocol icmp limit rate over 10/second drop
ip protocol icmp accept
Verification:
# Test rate limiting
ping -f <server-ip>
# Should see packet loss after rate limitCompliance:
Requirement: Log dropped packets for security auditing
Implementation:
# Rate-limited logging (prevents log spam)
limit rate 5/minute counter log prefix "nft[input-drop]: " drop
counter drop
Verification:
# View firewall logs
sudo journalctl -k | grep nft
sudo dmesg | grep nftCompliance: ✅ All templates include rate-limited logging
#!/bin/bash
echo "CIS 3.5.1.1 - nftables installed"
dpkg -s nftables | grep -q "install ok installed" && echo "✅ PASS" || echo "❌ FAIL"
echo "CIS 3.5.2.1 - Default deny policy"
sudo nft list ruleset | grep -q "policy drop" && echo "✅ PASS" || echo "❌ FAIL"
echo "CIS 3.5.2.2 - Loopback configured"
sudo nft list chain inet filter input | grep -q "iif lo accept" && echo "✅ PASS" || echo "❌ FAIL"
echo "CIS 3.5.2.3 - Established connections"
sudo nft list chain inet filter input | grep -q "ct state established,related accept" && echo "✅ PASS" || echo "❌ FAIL"
echo "CIS 3.5.3.1 - Service enabled"
systemctl is-enabled nftables.service | grep -q "enabled" && echo "✅ PASS" || echo "❌ FAIL"
echo "CIS 3.5.3.2 - Persistent config"
[ -f /etc/nftables.conf ] && echo "✅ PASS" || echo "❌ FAIL"| Template | Level 1 | Level 2 | Notes |
|---|---|---|---|
| 10-gateway.nft | ✅ Full | Add 60-rate-limiting.nft for full L2 | |
| 20-server.nft | ✅ Full | Add 60-rate-limiting.nft for full L2 | |
| 30-minimal.nft | ✅ Full | ❌ None | Minimal hardening only |
| 40-docker.nft | ✅ Full | Docker-specific, add rate-limiting | |
| 50-vpn-wireguard.nft | ✅ Full | VPN-specific | |
| 60-rate-limiting.nft | N/A | ✅ Full | Level 2 add-on |
Legend:
- ✅ Full - Meets all requirements
⚠️ Partial - Meets some requirements- ❌ None - Does not target this level
1. OUTPUT Chain Policy
- CIS Recommendation: policy drop (restrictive egress)
- Our Implementation: policy accept (allow outbound)
- Rationale: Servers need outbound connectivity (updates, API calls, DNS)
- Risk: Low (outbound restrictions rarely needed for servers)
2. IPv6 Support
- CIS Recommendation: Configure IPv6 if used
- Our Implementation: Basic IPv6 rules included
- Rationale: IPv6 adoption varies; templates support both IPv4/IPv6
- Risk: Low (disable IPv6 if not needed)
Our templates go beyond CIS requirements:
-
Management Network Isolation
- SSH restricted to management network (not just any IP)
- Separates admin access from production traffic
-
MSS Clamping
- Prevents MTU/fragmentation issues for NAT clients
- Not required by CIS but critical for routers
-
Docker Chain Preservation
- Prevents accidental destruction of Docker networking
- Production-tested pattern
-
WireGuard VPN Integration
- Secure remote access patterns
- Full DNS takeover support
# Download CIS-CAT tool (CIS Members)
https://www.cisecurity.org/cybersecurity-tools/cis-cat-pro/
# OR: Manual verification
sudo scripts/validate-nftables.sh /etc/nftables.confIf failing 3.5.2.1 (default deny):
# Add to chain definition
chain input {
type filter hook input priority 0; policy drop; # ← Add "policy drop"
}
If failing 3.5.2.2 (loopback):
# Add as FIRST rule
iif lo accept
If failing 3.5.3.1 (service enabled):
sudo systemctl enable nftables.service- SETUP.md - Installation and deployment
- NFTABLES_RULES.md - Rule syntax
- TROUBLESHOOTING.md - Common issues
CIS Benchmark: https://www.cisecurity.org/benchmark/ubuntu_linux
Questions? Open an issue at https://github.com/fidpa/ubuntu-server-security