Configuring a firewall on Debian (Debian 12 “bookworm” or Debian 13 “trixie” in 2026) is a foundational security step that enforces the principle of least exposure: block all incoming traffic by default and explicitly allow only the flows required for the server’s intended role (e.g., SSH on port 22, HTTP/HTTPS on 80/443, database on 5432 to specific IPs).
Debian’s kernel uses the Netfilter framework for packet filtering, NAT, and mangling. Since Debian 10 Buster, nftables is the native, default backend — a modern replacement for the legacy iptables that offers better performance, unified IPv4/IPv6 syntax, atomic rule-set updates, sets/maps for efficient matching, and reduced kernel memory footprint.
UFW (Uncomplicated Firewall) remains the most popular user-facing tool on Debian servers because it provides a simple, human-readable syntax while transparently using nftables (or iptables-legacy if configured) as the backend. This makes UFW ideal for most administrators who want effective protection without mastering nftables syntax.
Core Firewall Concepts (2026 Perspective)
- Default Policy — The cornerstone of any secure firewall is default-deny incoming.
- Incoming packets are dropped unless explicitly matched by an allow rule.
- Outgoing is usually allowed (servers initiate connections like DNS, updates, NTP).
- This follows the “block everything, permit only necessary” model, reducing the attack surface dramatically.
- Stateful vs Stateless Modern firewalls are stateful: they track connection state (NEW, ESTABLISHED, RELATED).
- Allow ESTABLISHED/RELATED → return traffic for outbound-initiated sessions flows automatically.
- This prevents asymmetric routing issues and reduces rule bloat.
- nftables Advantages Over Legacy iptables
- Single syntax for IPv4/IPv6/NAT/bridging.
- Incremental, atomic rule updates (no flushing/reloading gaps).
- Variables, sets, maps, concatenations → efficient large-scale rules (e.g., IP blocklists).
- Lower overhead in high-packet-rate environments.
- UFW Strengths
- Abstracts complexity: “ufw allow OpenSSH” instead of writing nft/iptables chains.
- Automatic persistence across reboots.
- Built-in support for rate limiting, logging, IPv6.
- Backend-agnostic (defaults to nftables in trixie).
Recommended Approach for Most Debian Servers
Use UFW unless you need advanced nftables features (e.g., complex NAT, dynamic sets, or integration with orchestration tools). UFW + nftables backend gives excellent security/usability balance.
Step-by-Step UFW Configuration Theory & Practice
- Installation (usually pre-installed on servers; confirm) UFW is lightweight and pulls nftables dependencies automatically.
- Set Default Policies Block unsolicited incoming; permit outbound. This immediately protects against port scans and unauthorized access attempts.
- Allow Required Services
- Use named services (from /etc/services) for readability: “ufw allow OpenSSH”.
- Or ports/protocols: “ufw allow 443/tcp”.
- Restrict sources when possible: “ufw allow from 203.0.113.0/24 to any port 5432” (PostgreSQL from trusted subnet).
- Rate Limiting & Logging
- Rate-limit SSH to mitigate brute-force: “ufw limit OpenSSH”.
- Enable logging for denied packets → feed into fail2ban or monitoring.
- IPv6 Enable if your network uses it; UFW handles dual-stack cleanly.
- Enable & Verify Dry-run first to preview changes. Check status with numbered rules for easy deletion.
- Common Production Rules
- SSH (port 22 or custom)
- HTTP/HTTPS (80, 443) for web servers
- Specific ports for services (e.g., WireGuard 51820/udp, SMTP 25 but often restricted)
- Deny everything else incoming
Alternative: Pure nftables (Advanced Use Cases)
Install the nftables package and enable the service. Rules live in /etc/nftables.conf. Use cases: high-performance filtering, large blocklists via sets, custom NAT chains, integration with tools like nftfw or ansible-nftables.
Example minimal server policy (theory): drop invalid packets early, allow loopback, established/related, then specific allows, final drop.
Best Practices Summary (2026)
- Always start with default deny incoming + allow outgoing.
- Prefer UFW for 80–90% of servers — simplicity reduces misconfiguration risk.
- Use source restrictions (IP/subnet) wherever feasible.
- Combine with fail2ban for dynamic banning on brute-force attempts.
- Enable logging (low or medium) and monitor /var/log/ufw.log or journalctl.
- Test rules with dry-run or temporary enable.
- Never expose unnecessary services (check with ss -tuln).
- For containers/VMs → consider podman/firewalld zones or host-level nftables.
- Review periodically: remove stale allows, tighten sources.
Firewall configuration is not set-and-forget — pair it with automatic security updates, AppArmor enforcement, key-based SSH, and monitoring (e.g., Netdata alerts on new open ports).