Guides 11793 Published by

Debian GNU/Linux 13 Trixie arrives with UFW version 0.36.2, delivering a pre-hardened default configuration where incoming traffic is denied and outgoing traffic is permitted by default. This tutorial shows you how to install and configure it. The tool handles both IPv4 and IPv6 through a hierarchical loading system of before.rules, user.rules, and after.rules, while application profiles provide pre-configured access for common services like Nginx and MySQL. For optimal security, set logging to medium and utilize rate limiting to block brute-force attempts without saturating disk space with excessive log entries.





How to Install and Configure UFW on Debian 13 Trixie

Debian 13 "Trixie" ships with UFW (Uncomplicated Firewall) version 0.36.2. You're starting with a hardened default configuration: incoming traffic denied, outgoing traffic allowed, and stateful connection tracking active. If you've been running older releases, the core behavior hasn't changed much, though the Debian package remains well-maintained.

Jamie Strandboge keeps the UFW package in Debian's archives. The stable build is currently 0.36.2-9, while the testing/unstable track sits at 0.36.2-10. Either way, you're getting a tool that bridges the gap between raw iptables complexity and a simple command-line interface.

Ufwtux

Installation

Check your baseline with ufw version. If it spits out a number, you're already halfway there.

To install from scratch:

sudo apt update
sudo apt install ufw -y

UFW arrives disabled by default. That's intentional. You'll want to set your rules before enabling the firewall, otherwise you risk locking yourself out of a remote SSH session.

How UFW Works Under the Hood

UFW manages three rule files. They load in a strict order:

  1. /etc/ufw/before.rules (or before6.rules) loads first.
  2. /etc/ufw/user.rules (or user6.rules) loads second.
  3. /etc/ufw/after.rules (or after6.rules) loads last.

The hierarchy matters more than most admins realize. A custom rule in user.rules can't override a DROP policy set in before.rules. If you're troubleshooting why a rule isn't firing, check that file first.

Each file has an IPv4 and IPv6 counterpart. UFW handles dual-stack traffic automatically, though you can force protocol-specific rules when needed.

Custom pre and post hooks live in /etc/ufw/before.init and /etc/ufw/after.init. They must be executable.

Default Policies

Debian 13 configures the following defaults via /etc/default/ufw:

ChainPolicy
INPUTdeny
OUTPUTallow
FORWARDdeny

Incoming traffic gets dropped unless you explicitly allow it. Outgoing traffic is wide open. This is the safe starting point for a desktop or single-purpose server. You can change these, but keep the defaults unless you have a routing setup that requires forwarding.

Enabling UFW

The interactive enable command looks like this:

sudo ufw enable

UFW will warn you if your SSH connection might get disrupted. Respond y to proceed.

If you're managing a remote server over SSH, skip the warning prompt. Add your SSH rule first, then force the enable:

sudo ufw allow proto tcp from any to any port 22
sudo ufw --force enable

The --force flag bypasses the SSH check. Without it, UFW will refuse to enable if it detects an active SSH session that isn't explicitly allowed.

Managing Rules

The basic syntax is ufw [allow|deny|reject|limit] [direction] [protocol] port. Direction defaults to in if you don't specify.

sudo ufw allow 80/tcp
sudo ufw deny 443
sudo ufw limit ssh/tcp

Rate limiting is the most useful defense against brute-force attacks. The limit action allows a connection but denies further attempts from the same IP if they exceed six new connections within 30 seconds. That's enough for a legitimate handshake, not enough for a dictionary attack.

Rule order is first-match-wins. If you place a broad allow before a specific deny, the deny rule will never fire. Keep your specific blocks near the top of the list.

Application Profiles

UFW ships with profiles for common services. Nginx, MySQL, OpenSSH, and Postfix are pre-configured rule sets stored in /etc/ufw/applications.d/.

List them with:

sudo ufw app list

Inspect one to see what ports it opens:

sudo ufw app info "Nginx Full"

Apply a profile:

sudo ufw allow "Nginx Full"

Note the quotes. Profile names with spaces require them. When you use app, UFW handles the protocol automatically based on the profile definition. Don't try to specify TCP or UDP on top of it.

IPv6 Configuration

IPv6 is enabled by default in Debian 13. Set IPV6=yes in /etc/default/ufw.

Most rules apply to both IPv4 and IPv6 simultaneously. If you allow port 22, you're allowing it for both stacks. You can write IPv6-only rules with specific syntax, but that's rarely necessary for standard service access.

For routing or NAT with IPv6, edit /etc/ufw/sysctl.conf to enable forwarding, then reload UFW.

Logging

Logging lives at five levels. The medium setting is the sweet spot for most servers. It logs allowed non-policy packets, invalid packets, and new connections.

sudo ufw logging medium

low logs only blocked packets. high and full generate substantial output. On a busy system, those levels can fill your disk fast. Use them for short diagnostic runs, then dial it back.

Logs use the LOG_KERN facility. Check them with journalctl -k | grep UFW or look at /var/log/ufw.log if rsyslog is configured.

A Few Gotchas

Keep in mind that ufw delete <number> only removes one rule if you have both IPv4 and IPv6 entries. Use the full rule syntax to delete both:

ufw delete allow 80/tcp

When you add or remove rules, UFW doesn't flush the kernel chains. It only reloads on policy changes or explicit reload commands. Active connections survive normal management operations. That's a notable improvement over older versions.

Connection tracking modules like nf_conntrack_ftp can be loaded via IPT_MODULES in /etc/default/ufw. Kernel 4.7 and newer disables automatic helper assignment, so configure helpers per-connection to avoid abuse.

Resetting Everything

If you've tangled the rules too badly, start over:

sudo ufw reset --force

This disables the firewall and resets all rules to installation defaults. It's the nuclear option.

Testing Before You Commit

Dry-run mode lets you see what a rule would do without applying it:

ufw --dry-run allow 80/tcp

It's worth using before you add rules to a production box.

Verification

Once you've configured your rules, check the status:

ufw status verbose

To show the full kernel ruleset if you need to debug deeper:

sudo ufw show raw

UFW remains the standard firewall tool for Debian. It's reliable, the syntax is intuitive, and the defaults keep you safe from day one. Just pay attention to rule order and don't forget to allow SSH before you flip the switch.