A fresh Debian install often leaves firewall setup until the moment you need to lock down SSH or open a web port cleanly. To install UFW on Debian, you only need the default APT package, and the same workflow applies on Debian 13, 12, and 11.
UFW is the simpler rule layer on top of Debian’s firewall stack, so you can allow SSH, HTTP, HTTPS, or subnet-specific access without writing raw nftables or iptables rules by hand. Once it is installed, you get application profiles, IPv6-aware rules, status checks, and logging from the same command set.
Debian does not preinstall UFW on Debian 13, 12, or 11. Debian still uses the kernel netfilter firewall stack underneath, while UFW is the front end you install when you want simpler rule commands. If you see
ufw: command not found, install the package first, and remember that plain user shells can also miss/usr/sbin, where theufwbinary lives.
Install UFW on Debian with APT
UFW installs directly from Debian’s default repositories. The Debian package page for UFW lists the package in Debian 13 (Trixie), Debian 12 (Bookworm), and Debian 11 (Bullseye), so no third-party repository or direct download is needed. Before installation, update your system to avoid package conflicts:
sudo apt update && sudo apt upgrade
These commands use
sudofor tasks that need root privileges. If your user is not in the sudoers file yet, follow the guide on how to add a user to sudoers on Debian.
If the update pulled in a new kernel, reboot before you start changing firewall rules.
Install the package once the system is current:
sudo apt install ufw
A minimal Debian 13 transaction can add iptables, libip4tc2, and libip6tc2 with UFW, while Debian 12 may add only iptables and libip6tc2. Debian 11 can install only ufw when the lower-level firewall packages are already present. On Debian 13, the final setup line looks like this:
Setting up ufw (0.36.2-9) ...
Verify the installed package state with dpkg-query:
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package} ${Version}\n' ufw
In the default repositories, Debian 13 reports 0.36.2-9, Debian 12 reports 0.36.2-1, and Debian 11 reports 0.36-7.1. The ii status is the stable part to check:
ii ufw 0.36.2-9
The package enables the ufw.service unit during setup, but the firewall remains inactive until you run sudo ufw enable. Across Debian 13, 12, and 11, apt-cache policy ufw starts at Installed: (none) on a fresh system, so do not expect UFW to be present before installation.
UFW is now installed but the firewall is not yet active. Before enabling it, configure essential rules to avoid losing access to your system.
Allow SSH on Debian Before Enabling UFW
If you are connected over SSH, allow SSH before you enable UFW. Otherwise the new firewall policy can cut off the session immediately.
Allow SSH connections through the firewall:
sudo ufw allow ssh
UFW confirms the rule was added for both IPv4 and IPv6:
Rules updated Rules updated (v6)
If you use a custom SSH port instead of the default port 22, allow that port instead:
sudo ufw allow 2222/tcp
Replace 2222 with your actual SSH port number.
Enable the UFW Firewall on Debian
With SSH access secured, enable the firewall. UFW blocks all incoming traffic and allows all outbound traffic by default, protecting your system from unauthorized access while permitting normal internet use.
Run the enable step once the SSH rule is in place:
sudo ufw enable
The first run can ask for confirmation because enabling the firewall may disrupt SSH. After you answer y, the output ends with:
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
Once the firewall is active, UFW blocks new inbound connections unless a rule allows them. That protects unused services, but it also means every legitimate remote service needs an allow rule before you rely on it.
Check UFW Status on Debian
Verify the active rules and defaults as soon as the firewall is enabled:
sudo ufw status verbose
Expected output after allowing SSH and enabling UFW:
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW IN Anywhere 22/tcp (v6) ALLOW IN Anywhere (v6)
This confirms that UFW is active, logging at the low level, denying new inbound traffic, allowing outbound traffic, and preserving the SSH rule needed for remote access.
Use the numbered view when you want rule positions for later edits or deletions:
sudo ufw status numbered
Expected output after the initial SSH rule:
Status: active To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 22/tcp (v6) ALLOW IN Anywhere (v6)
This view becomes especially useful once you start adding HTTP, HTTPS, subnet, or interface-specific rules and need to remove only one of them later.
Set UFW Default Policies on Debian
The default UFW policy blocks new incoming connections and allows outgoing connections. This is a safe baseline for most desktops and simple servers because only explicitly allowed inbound services remain reachable. To allow incoming connections, create specific rules that permit traffic by profile, port, IP address, subnet, or interface.
These two commands restore Debian’s standard inbound and outbound defaults:
Deny all incoming connections:
sudo ufw default deny incoming
Allow all outgoing connections:
sudo ufw default allow outgoing
These policy values are the package defaults, but they do not protect the host until UFW is enabled. Adjust them only when your system has a clear need for a different inbound or outbound baseline.
Block All Outgoing Traffic with UFW
Blocking all outbound traffic also blocks DNS lookups, package updates, and ordinary web requests. Use this only on systems where you plan to allow every required outbound service explicitly.
To block all outgoing connections:
sudo ufw default deny outgoing
After blocking outgoing traffic, you must explicitly allow each service your system needs. For example, to allow DNS and HTTP/HTTPS:
sudo ufw allow out 53/udp
sudo ufw allow out 80/tcp
sudo ufw allow out 443/tcp
To restore normal outbound connectivity:
sudo ufw default allow outgoing
The default UFW firewall policies live in the /etc/default/ufw file. This file contains the configuration settings for UFW, including the default policies for incoming and outgoing traffic. By modifying the settings in this file, you can customize the firewall rules to meet your specific security needs.
Configure UFW Application Profiles and Advanced Rules on Debian
Once the default policy is in place, the next step is deciding which services, ports, and networks should stay reachable. These examples cover the UFW patterns that are most useful on Debian desktops, servers, and small lab systems.
View UFW Application Profiles
Start by listing the application profiles that ship with UFW and any packages already installed on the system:
sudo ufw app list
Relevant output on Debian included more than a single SSH profile:
Available applications: AIM Bonjour CIFS CUPS DNS IMAP OpenSSH SSH WWW WWW Secure
The exact list changes with installed packages, but Debian’s UFW package already ships a longer built-in profile list than a one-line SSH-only example. When you add web servers such as Nginx or Apache, you also pick up their application-specific profiles.
Check a single profile when you want to confirm which ports it opens:
sudo ufw app info SSH
Expected output showing the application profile details:
Profile: SSH Title: SSH server Description: SSH server Port: 22/tcp
Replace SSH with the profile name you want to inspect. Current Debian builds can expose both OpenSSH and SSH profiles, but sudo ufw allow ssh remains the safer command to remember in the main workflow.
Enable IPv6 in UFW on Debian
Debian’s UFW package sets IPv6 support to yes by default on Debian 13, 12, and 11. Confirm the setting before you depend on IPv6 rules, especially on upgraded systems or images with older local configuration files.
Open the default UFW settings file to verify the IPv6 toggle:
sudo nano /etc/default/ufw
The setting you want is:
IPV6=yes
If the value is set to no, change it to yes and save the file by pressing CTRL+O and then CTRL+X to exit.
After making changes to the file, restart the UFW firewall service:
sudo systemctl restart ufw
UFW now handles both IPv4 and IPv6 traffic. When you create rules later, UFW writes matching IPv4 and IPv6 entries for rules that apply to both protocol families. If IPv6 is disabled, only the IPv4 rule confirmation appears.
Configure SSH Access Rules in UFW
If SSH is not installed yet, install and enable SSH on Debian first. The base SSH allow rule was already added earlier, so this section moves to the changes that usually happen after that first safe setup.
Change the SSH Port in UFW
If you change the SSH listening port (configured in /etc/ssh/sshd_config), update UFW rules to match. The correct sequence prevents lockout:
Step 1: Allow the new SSH port before changing the SSH configuration:
sudo ufw allow 3541/tcp
Step 2: Update SSH configuration to use the new port and restart the service.
Step 3: Test the new connection in a separate terminal before closing your current session.
Step 4: Once confirmed working, remove the old port rule:
sudo ufw delete allow 22/tcp
Keep the existing SSH session open until the new port accepts a second login cleanly. Remove the old rule only after that test succeeds.
Block SSH Access with UFW
Blocking SSH cuts off remote administration. Only use this rule when you still have local console access or another out-of-band way back into the machine.
To block all SSH connections:
sudo ufw deny ssh
Allow Ports with UFW
Web services usually need HTTP and HTTPS open alongside SSH. If you are still building the stack, install Nginx on Debian or install Apache on Debian first, then come back here to expose only the ports you need. For tighter web-layer filtering later, install ModSecurity with Apache on Debian or secure Nginx with Let’s Encrypt on Debian after the firewall basics are in place.
HTTP on port 80 can be opened with an application profile, service name, or direct port rule. Use one form for the same service; running multiple equivalent forms can create duplicate or skipped rules. Application-profile commands require the matching package profile to exist, so install Nginx before using the Nginx examples.
Allow by application profile:
sudo ufw allow 'Nginx HTTP'
Allow by service name:
sudo ufw allow http
Allow by port number:
sudo ufw allow 80/tcp
A successful new rule returns confirmation for IPv4 and IPv6 when IPv6 support is enabled:
Rules updated Rules updated (v6)
HTTPS on port 443 works the same way:
Allow by application profile:
sudo ufw allow 'Nginx HTTPS'
Allow by service name:
sudo ufw allow https
Allow by port number:
sudo ufw allow 443/tcp
Allow both web ports together with the combined profile when that matches your stack:
sudo ufw allow 'Nginx Full'
If UFW returns ERROR: Could not find a profile matching, the profile is not registered on that system. Install the web server package that owns the profile, or use the service name or port-number form instead.
Allow UFW Port Ranges
You can allow individual ports and port ranges. When opening a port range, specify the protocol. Use TCP for connection-oriented services (web servers, SSH, databases) and UDP for stateless protocols (DNS, VPN, streaming media).
Open the range for both protocols with:
sudo ufw allow 6500:6800/tcp
sudo ufw allow 6500:6800/udp
If you only need a few ports, a comma-separated list is shorter:
sudo ufw allow 6500,6501,6505,6509/tcp
sudo ufw allow 6500,6501,6505,6509/udp
Allow IP-Based Access with UFW
UFW supports IP-based access control for restricting services to specific networks or hosts. This section covers allowing connections from individual IPs, subnets, and specific network interfaces.
Allow Specific IP Addresses with UFW
Allow a single client address when only one host should reach the system:
sudo ufw allow from 192.168.55.131
UFW confirms the rule:
Rule added
Allow a Specific IP Address on a UFW Port
Combine the source address with a single destination port when the service should stay private:
sudo ufw allow from 192.168.55.131 to any port 3900
Allow Subnet Connections on a UFW Port
Allow an entire subnet on one port with:
sudo ufw allow from 192.168.1.0/24 to any port 3900
As a result, this command allows all IP addresses from 192.168.1.1 to 192.168.1.254 to connect to port 3900.
Allow a Specific Network Interface with UFW
Use the interface form when the host has multiple NICs and only one should accept the traffic:
sudo ufw allow in on eth2 to any port 3900
Replace eth2 with the actual interface name from your system before applying the rule.
Deny Remote Connections with UFW
When a source address repeatedly hits a service, use a deny rule to block that address or subnet before it reaches the application. UFW denies unmatched incoming traffic by default, but explicit deny rules are useful when you want the block to appear clearly in the rule list.
Block one source address with:
sudo ufw deny from 203.13.56.121
The rule takes effect immediately:
Rule added
If repeated traffic comes from the same subnet, block the range in CIDR notation:
sudo ufw deny from 203.13.56.0/24
This command blocks all 256 addresses from 203.13.56.0 to 203.13.56.255.
Target only specific ports when you do not want to block every connection from that subnet:
sudo ufw deny from 203.13.56.0/24 to any port 80
sudo ufw deny from 203.13.56.0/24 to any port 443
Address-based blocks are a traffic filter, not authentication. Keep SSH keys, service passwords, system updates, and log-based protections in place instead of relying only on IP rules.
Delete UFW Rules on Debian
Deleting unnecessary or unwanted UFW rules is essential for maintaining an organized and efficient firewall. You can delete UFW rules in two different ways. First, list your current rules with their numbers:
sudo ufw status numbered
The output displays numbered rules, making it easy to identify which rule to delete:
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 443/tcp (v6) ALLOW IN Anywhere (v6)
To delete a rule, specify its number. For example, to remove the HTTP rule (rule 2), run:
sudo ufw delete 2
UFW asks for confirmation before deleting:
Deleting: allow 80/tcp Proceed with operation (y|n)? y Rule deleted
Alternatively, delete a rule by specifying the original command with delete added:
sudo ufw delete allow 443/tcp
When you delete a rule, the remaining entries are renumbered. Run
sudo ufw status numberedagain before deleting anything else so you do not target the wrong line.
View UFW Logs on Debian
UFW can log blocked and allowed packets according to the logging level you choose. Review these logs when you are troubleshooting a service that should be reachable or investigating repeated connection attempts. The default low level is usually enough for desktops and small servers; noisy systems may need a temporary higher level while you diagnose a problem.
Adjust logging to low, medium, high, or fully off depending on how much detail you need. Start with the low level first:
sudo ufw logging low
Expected output:
Logging enabled
To set UFW logging to medium:
sudo ufw logging medium
To set UFW logging to high:
sudo ufw logging high
Finally, to disable logging entirely:
sudo ufw logging off
The logging levels capture different amounts of detail:
- Low: Logs blocked packets not matching default policy
- Medium: Adds logging for packets matching rules (allows and denies)
- High: Logs all packets with rate limiting disabled
UFW writes logs to /var/log/ufw.log. Tail the last 30 lines with this command; for follow mode, filters, and other log-reading patterns, use the tail command examples reference.
sudo tail -n 30 /var/log/ufw.log
Use the log entries to identify source addresses, destination ports, and repeated blocked traffic before you add or remove rules.
Preview UFW Rule Changes Before Applying Them
The --dry-run flag prints the rules UFW would generate without writing them to the live rule set. Use it for high-risk changes where a typo could expose a service or block a remote session.
Preview a new TCP rule:
sudo ufw --dry-run allow 8080/tcp
Relevant output begins with the generated filter table instead of applying the rule:
*filter :ufw-user-input - [0:0] :ufw-user-output - [0:0] :ufw-user-forward - [0:0] :ufw-before-logging-input - [0:0] :ufw-before-logging-output - [0:0] ### RULES ###
Review the generated rules, then rerun the command without --dry-run when the preview matches what you intended. State-changing actions such as enable can still ask for confirmation, so dry-run is most useful for checking rule syntax and generated firewall entries.
Reset UFW Rules on Debian
Resetting UFW deletes every saved rule, including the SSH allow rule. Only do this from a local console or another session where you can recover immediately.
Reset UFW only when you want to wipe the saved rules and start over:
sudo ufw reset
Relevant output includes the confirmation prompt and the timestamped backups written into /etc/ufw/:
Resetting all rules to installed defaults. This may disrupt existing ssh connections. Proceed with operation (y|n)? y Backing up 'user.rules' to '/etc/ufw/user.rules.20260402_100918' Backing up 'before.rules' to '/etc/ufw/before.rules.20260402_100918' Backing up 'after.rules' to '/etc/ufw/after.rules.20260402_100918' Backing up 'user6.rules' to '/etc/ufw/user6.rules.20260402_100918' Backing up 'before6.rules' to '/etc/ufw/before6.rules.20260402_100918' Backing up 'after6.rules' to '/etc/ufw/after6.rules.20260402_100918'
Verify the reset completed:
sudo ufw status
Status: inactive
After a reset, UFW is inactive and all rules are cleared. The backup filenames always carry the time of the reset, so your timestamp will differ from this example. To bring the firewall back online, allow SSH first and then enable UFW again:
sudo ufw allow ssh
sudo ufw enable
Scan Open Ports on Debian with Nmap
After enabling or changing UFW rules, verify the result from another machine when possible. UFW can report a clean rule set while another service, Docker rule, or listener state still affects what clients can reach.
Nmap is the easiest way to check whether the ports you meant to expose are actually reachable. If you want a full walkthrough for the scanner itself, see how to install Nmap on Debian; for scan patterns beyond this quick port check, use the Nmap commands for beginners reference.
sudo apt install nmap
Start by identifying the host address you want to scan:
hostname -I
Example output:
192.168.50.45
Scan that address from another machine on the same network:
nmap 192.168.50.45
Nmap scans your system and lists all open ports. Example output:
Starting Nmap 7.x ( https://nmap.org ) Nmap scan report for 192.168.50.45 Host is up (0.00012s latency). Not shown: 998 filtered tcp ports (no-response) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http
If you find any open ports you are unsure about, investigate them before closing or blocking them, as it may break services or lock you out of your system.
Once you know which ports are actually open, you can tighten or remove the matching UFW rules instead of guessing.
Update, Disable, or Remove UFW on Debian
Update UFW on Debian
UFW updates through Debian’s normal APT package flow. To refresh package metadata and apply only an available UFW package upgrade:
sudo apt update
sudo apt install --only-upgrade ufw
If UFW is already current, APT reports that no upgrade is needed. Package updates do not replace your saved rule set, but keep SSH allowed before upgrading firewall-related packages on a remote system.
Temporarily Disable UFW on Debian
Disabling UFW stops the live firewall rules but keeps the saved configuration on disk.
Disabling UFW opens the machine to whatever the rest of the network allows. Use this only for short troubleshooting windows and turn the firewall back on as soon as the test is finished.
To disable UFW temporarily:
sudo ufw disable
Expected output:
Firewall stopped and disabled on system startup
Your firewall rules are preserved. To re-enable UFW:
sudo ufw enable
Remove UFW on Debian
Before removing the package, stop the firewall and clear the saved rule set so you know exactly what state you are leaving behind:
sudo ufw disable
sudo ufw reset
Remove only the package itself first:
sudo apt remove ufw
Review
sudo apt autoremovemanually before you run it here. On reused Debian systems, APT can also target older kernel packages, which is not a safe blind cleanup step for firewall removal.
Refresh the package cache and verify removal:
sudo apt update
apt-cache policy ufw
Expected output confirming the package is gone on Debian 13:
ufw:
Installed: (none)
Candidate: 0.36.2-9
Version table:
0.36.2-9 500
500 http://deb.debian.org/debian trixie/main amd64 Packages
100 /var/lib/dpkg/status
Debian 12 shows 0.36.2-1 as the candidate, and Debian 11 shows 0.36-7.1. The important line after removal is Installed: (none). The trailing 100 /var/lib/dpkg/status entry is only local package history, not proof that UFW is still installed.
Removing UFW leaves Debian without this front end for firewall rules. If you want a zone-based replacement, install firewalld on Debian. If you want mandatory access control beyond network filtering, install SELinux on Debian as a separate hardening layer.
Troubleshoot Common UFW Issues on Debian
Most UFW problems on Debian come down to one of three things: SSH access was not allowed before the firewall was enabled, Docker inserted its own packet rules ahead of UFW, or a later rule is shadowing the one you expected to match.
Locked Out After Enabling UFW on Debian
If you enabled UFW on a remote server without allowing SSH first, you cannot connect remotely. Access the server through a local console or recovery mode, then allow SSH:
sudo ufw allow ssh
sudo ufw reload
Verify the rule appears in the status output:
sudo ufw status numbered
Status: active To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 22/tcp (v6) ALLOW IN Anywhere (v6)
UFW Conflicts with Docker on Debian
Docker publishes container ports with its own iptables rules, so traffic can reach published containers before a normal UFW deny rule sees it. Docker’s documentation recommends putting user-defined filtering in the DOCKER-USER chain when you need to restrict container traffic before Docker’s own forwarding rules.
Do not set
"iptables": falsein Docker’s daemon.json as a quick UFW fix. Docker warns that disabling its iptables management is not recommended for most users because it can break container networking.
For Docker hosts, either bind published ports to localhost or a private address when possible, or add tested filtering rules to DOCKER-USER for the real external interface and source networks. Avoid pasting a generic drop block into production without testing from a separate client, because Docker bridge networks, IPv6, and published-port requirements vary by host. For the supported chain behavior and current examples, use the official Docker iptables documentation.
UFW Rules Not Taking Effect on Debian
After adding rules, reload UFW to ensure changes apply:
sudo ufw reload
If rules still do not work, check rule order with sudo ufw status numbered. UFW evaluates rules from top to bottom, so an earlier deny rule can block a later allow rule even when both look correct on their own.
Fix ufw: Command Not Found on Debian
If sudo: ufw: command not found appears before installation, install the ufw package from Debian’s default repositories. If the package is installed but a plain ufw command still fails, your user PATH probably does not include /usr/sbin.
Confirm the package is installed:
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package} ${Version}\n' ufw
ii ufw 0.36.2-9
Debian 12 and Debian 11 report their own repository versions, so use the ii status as the package-installed signal.
Then run UFW through sudo or call the full path directly:
sudo ufw status
sudo /usr/sbin/ufw status
The sudo ufw form is preferred for normal administration because firewall status and rule changes require root privileges. The direct path is useful when you are diagnosing PATH behavior on minimal or server-oriented shells.
Conclusion
UFW is now ready on Debian with SSH protected, sensible default policies in place, and enough rule patterns to handle the usual web, subnet, and logging tasks without dropping into raw firewall syntax. For the next hardening step, install Fail2ban on Debian, or add deeper HTTP filtering later with install ModSecurity with Apache on Debian.


Thank you