Report this

What is the reason for this report?

Set Up a Firewall with UFW on Ubuntu and Debian

Updated on June 22, 2026
Shaun LewisManikandan Kurup

By Shaun Lewis and Manikandan Kurup

English
Set Up a Firewall with UFW on Ubuntu and Debian

Introduction

Setting up a functioning firewall is crucial to securing your cloud server. Previously, setting up a firewall was done through complicated or arcane utilities. Many of these utilities, such as iptables, have a lot of functionality built into them, but they require extra effort from the user to learn and understand.

Another option is UFW, or Uncomplicated Firewall. UFW is a front-end to the kernel’s netfilter system that aims to provide a more user-friendly interface than other firewall management utilities. UFW is well-supported in the Linux community and is installed by default on Ubuntu, where it ships disabled until you enable it.

In this tutorial, you will set up a firewall using UFW to secure an Ubuntu or Debian cloud server. You will install UFW where it is not already present, set default rules to allow or deny connections, open ports for specific services and IP addresses, use application profiles, enable logging, delete rules, and reset everything back to default settings.

Key takeaways

  • UFW (Uncomplicated Firewall) is a friendly front-end for the kernel’s netfilter firewall, sparing you the complexity of raw iptables or nftables rules.
  • On Ubuntu, UFW is installed by default but inactive; on Debian it is in the repositories but must be installed with sudo apt install ufw.
  • Recent UFW releases (0.36.x) use the nftables backend on current Ubuntu and Debian through the iptables-nft compatibility layer, while the commands you type stay the same.
  • The recommended baseline is to deny all incoming traffic and allow all outgoing traffic, then open only the ports you need.
  • Always allow SSH (sudo ufw allow OpenSSH or sudo ufw allow ssh) before running sudo ufw enable, or you risk locking yourself out of a remote server.
  • You can allow or deny traffic by service name, port number, port range, IP address, or application profile, which makes rules readable and precise.
  • sudo ufw limit ssh adds basic brute-force protection by capping new connections at six per 30 seconds from a single IP address.
  • sudo ufw status verbose shows the active rules, default policies, and logging level in one place.
  • UFW manages IPv6 rules automatically when IPV6=yes is set in /etc/default/ufw, which is the default on modern systems.
  • sudo ufw reset backs up and removes all user-defined rules, disables the firewall, and resets the default policies to deny incoming and allow outgoing.

Prerequisites

To follow this tutorial, you will need a server running either Ubuntu or Debian. Your server should have a non-root user with sudo privileges.

The steps in that guide apply equally to Debian 12 and Debian 13. Both of these initial server setup guides help you create a secure environment that you can use to practice creating firewall rules.

Once you have a sudo user ready, you can move on to understanding what UFW does before you configure it.

Understanding UFW and how it works

UFW does not replace the firewall in the Linux kernel; it manages it. The kernel filters network traffic through its netfilter framework, which administrators traditionally configure with iptables or, more recently, nftables. Writing those rules by hand is powerful but error-prone. UFW sits on top of that machinery and translates short, readable commands such as sudo ufw allow ssh into the lower-level rules the kernel enforces.

On current Ubuntu and Debian releases, UFW 0.36.x uses the nftables backend through the iptables-nft compatibility layer, so even when you think in iptables terms, the rules are applied through nftables under the hood. This change is transparent: the UFW commands in this guide are identical regardless of the backend.

To see which version is installed, run the following:

  1. sudo ufw version

The command reports the UFW version and license, similar to the following:

Output
ufw 0.36.2
Copyright 2008-2023 Canonical Ltd.

UFW is not the only option, so the following table compares it with the two other common Linux firewall tools to help you choose the right one for your environment.

Tool Interface Default On Best For
UFW Simple command line (ufw allow ssh) Ubuntu (easily added to Debian) Single servers and straightforward rule sets
firewalld Zone-based, firewall-cmd RHEL, Rocky Linux, Fedora Dynamic environments with multiple network zones
iptables / nftables Low-level rule syntax All distributions Fine-grained control, complex routing or NAT

For most single Ubuntu or Debian cloud servers, UFW is the simplest choice that still gives you complete control. Choose firewalld if you are on a Red Hat family system or need zone-based management, and reach for raw nftables only when you need advanced features that the front-ends do not expose.

Installing UFW on Ubuntu and Debian

On Ubuntu, UFW is installed by default, so you usually do not need to install anything. You can confirm it is present by checking its status:

  1. sudo ufw status

If UFW is installed but not yet enabled, the output is simply:

Output
Status: inactive

On Debian, UFW is available in the standard repositories but is not installed by default. Install it with apt:

  1. sudo apt update
  2. sudo apt install ufw

Note for Debian users: Installing the ufw package does not enable the firewall automatically. UFW stays inactive until you run sudo ufw enable, which gives you time to add an SSH rule first so you do not lock yourself out. The rest of this guide applies identically to Ubuntu and Debian unless a step says otherwise.

With UFW installed, the next step is to make sure it handles IPv6 traffic correctly.

Using IPv6 with UFW

If your Virtual Private Server (VPS) is configured for IPv6, ensure that UFW is set to support IPv6 so it configures both your IPv4 and IPv6 firewall rules. To do this, open the UFW configuration file in your preferred text editor. This example uses nano:

  1. sudo nano /etc/default/ufw

Confirm that IPV6 is set to yes. On modern Ubuntu and Debian this is already the default:

/etc/default/ufw
# /etc/default/ufw
#

# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take effect.
IPV6=yes

After you make your changes, save and exit the file. If you are using nano, press CTRL + X, then Y, and then ENTER.

For any change to /etc/default/ufw to take effect, restart the firewall by first disabling it:

  1. sudo ufw disable

Disabling the firewall returns the following confirmation:

Output
Firewall stopped and disabled on system startup

Then enable it again:

  1. sudo ufw enable

Re-enabling the firewall confirms it is active:

Output
Firewall is active and enabled on system startup

Your UFW firewall is now set up to handle both IPv4 and IPv6. Next, you will adjust the default rules that apply to connections.

Setting up UFW defaults

You can improve your firewall’s efficiency by defining default rules for allowing and denying connections. UFW’s default is to deny all incoming connections and allow all outgoing connections. This means anyone trying to reach your server cannot connect, while any application within the server can still connect out. To set these rules explicitly, first address the incoming connections rule:

  1. sudo ufw default deny incoming

Setting the incoming policy returns the following:

Output
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

Next, address the outgoing connections rule:

  1. sudo ufw default allow outgoing

Setting the outgoing policy returns a similar confirmation:

Output
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)

Note: If you want to be more restrictive, you can deny all outgoing requests. This option is based on personal preference. For example, on a public-facing cloud server it can help prevent unwanted outbound connections such as remote shells. It does make your firewall more cumbersome to manage, because you have to add rules for every outgoing connection you want to allow. You can set this as the default with the following:

  1. sudo ufw default deny outgoing

Allowing connections to the firewall

Allowing connections requires changing the firewall rules, which you do by issuing commands in the terminal. If you enabled your firewall right now, it would deny all incoming connections. If you are connected over SSH, this would be a problem because you would be locked out of your server. Prevent this by allowing SSH connections before you enable UFW:

  1. sudo ufw allow ssh

If your change was successful, you receive the following output:

Output
Rule added
Rule added (v6)

UFW understands some service names out of the box, such as the ssh keyword used above. Alternatively, you can allow incoming connections to port 22/tcp, which uses Transmission Control Protocol (TCP) to accomplish the same thing:

  1. sudo ufw allow 22/tcp

If you run this after you have already run allow ssh, UFW tells you the rule already exists:

Output
Skipping adding existing rule
Skipping adding existing rule (v6)

If your SSH server runs on a non-standard port such as 2222, allow connections with the same syntax but the different port. If you specify the port number by itself, the rule applies to both tcp and udp, so naming the protocol is more precise:

  1. sudo ufw allow 2222/tcp

Allowing the custom port returns the same confirmation as before:

Output
Rule added
Rule added (v6)

To reduce the risk of brute-force login attempts, you can rate-limit SSH instead of simply allowing it. The limit command caps new connections at six within 30 seconds from any single IP address:

  1. sudo ufw limit ssh

Allowing web server connections

Web servers such as Apache and Nginx listen for HTTP requests on port 80 and HTTPS requests on port 443. To serve unencrypted traffic, allow connections to port 80/tcp:

  1. sudo ufw allow 80/tcp

To serve encrypted HTTPS traffic, also allow port 443/tcp:

  1. sudo ufw allow 443/tcp

UFW provides named application profiles for common web servers, which is often cleaner than remembering port numbers. For example, if Nginx is installed you can allow HTTP traffic using its profile name:

  1. sudo ufw allow 'Nginx HTTP'

If Apache is installed instead, use the Apache profile:

  1. sudo ufw allow 'Apache'

If you prefer to allow by port number regardless of which web server is installed, the equivalent command is:

  1. sudo ufw allow 80/tcp

Allowing FTP connections

File Transfer Protocol (FTP) is unrelated to web traffic and uses its own ports: 21 for control and 20 for data transfer. If you specifically need an FTP server, allow the control port by name:

  1. sudo ufw allow ftp

Allowing by name is equivalent to allowing port 21/tcp directly:

  1. sudo ufw allow 21/tcp

For active-mode FTP connections, you also need to allow the data port 20:

  1. sudo ufw allow 20/tcp

Note: Most modern FTP deployments use passive mode rather than active mode. Passive mode requires opening an additional range of high-numbered ports beyond 20 and 21. The exact range is configured in your FTP server (for example, pasv_min_port and pasv_max_port in vsftpd.conf, or PassivePorts in proftpd.conf). Once you know that range, open it with a rule such as sudo ufw allow 49152:65535/tcp. Consult your FTP server’s documentation for the correct values before exposing a passive port range.

Your adjustments depend on which ports and services you need to open, and some testing may be necessary. Remember to leave your SSH connection allowed as well.

Specifying port ranges

You can specify ranges of ports to allow or deny with UFW. To do this, specify the port at the low end of the range, follow it with a colon (:), then the high end of the range, and finally the protocol (either tcp or udp).

For example, the following command allows TCP access to every port from 1000 to 2000, inclusive:

  1. sudo ufw allow 1000:2000/tcp

Likewise, the following command denies UDP connections to every port from 1234 to 4321:

  1. sudo ufw deny 1234:4321/udp

Many important services use UDP rather than TCP. DNS, NTP, and VPN protocols such as WireGuard all rely on UDP, so you need to specify udp explicitly when writing rules for them. The following examples show how to allow the WireGuard VPN port and the DNS port over UDP:

  1. sudo ufw allow 51820/udp
  2. sudo ufw allow 53/udp

Specifying IP addresses

You can allow connections from a specific IP address. Be sure to replace the example address with your own:

  1. sudo ufw allow from your_server_ip

To restrict that allowance to a single port, append to any port and the port number, which is a common pattern for limiting SSH to a trusted address:

  1. sudo ufw allow from your_server_ip to any port 22

As these examples show, you have a lot of flexibility when adjusting firewall rules by selectively allowing certain ports and IP addresses. Check out our guide to learn more about allowing incoming connections from a specific IP address or subnet.

Working with UFW application profiles

When you install network software, it often registers a UFW application profile, which is a named bundle of the ports that service needs. Using profiles keeps your rules readable. To see which profiles are available on your system, list them:

  1. sudo ufw app list

The output shows the registered profiles, which vary depending on what you have installed:

Output
Available applications:
  Apache
  Apache Full
  Apache Secure
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH

To see exactly which ports a profile opens, ask for its details:

  1. sudo ufw app info 'Nginx Full'

The profile description lists the ports it covers, in this case both HTTP and HTTPS:

Output
Profile: Nginx Full
Title: Web Server (Nginx, HTTP + HTTPS)
Description: Small, but very powerful and efficient web server

Ports:
  80,443/tcp

Once you know what a profile does, allow it by name to open all of its ports at once:

  1. sudo ufw allow 'Nginx Full'

Using the OpenSSH profile is the recommended way to permit SSH, since it is clearer than a bare port number and is the form most initial-server-setup guides use.

When a package is upgraded, its application profile may change to reflect new or updated ports. To make sure UFW is using the latest version of a profile, run ufw app update with the profile name after upgrading the corresponding package:

  1. sudo ufw app update 'Nginx Full'

To refresh all registered profiles at once, omit the profile name:

  1. sudo ufw app update all

You can confirm the current list of registered profiles at any time with:

  1. sudo ufw app list

Denying connections

If you wanted to open all of your server’s ports, which is not recommended, you could allow all connections and then deny only the ports you want to block. The following example denies access to port 80:

  1. sudo ufw deny 80/tcp

You can deny by service name or application profile in the same way, for example sudo ufw deny ftp. Denying is also useful for temporarily blocking a service without deleting its allow rule permanently.

Deleting rules

If you want to delete some of the rules you created, use delete and specify the rule you want to remove:

  1. sudo ufw delete allow 80/tcp

Removing the rule returns the following:

Output
Rule deleted
Rule deleted (v6)

If the rules are long or complex, there is an alternative two-step approach. First, generate a numbered list of current rules:

  1. sudo ufw status numbered

The numbered list lets you see each rule and the index you will use to delete it:

Output
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 22/tcp                     ALLOW IN    Anywhere
[ 3] 2222/tcp                   ALLOW IN    Anywhere
[ 4] 80                        ALLOW IN    Anywhere
[ 5] 20/tcp                     ALLOW IN    Anywhere
…

With the numbered list in front of you, delete a rule by referring to its number. For example, if port 80 is number 4 on the list, use the following. You may be prompted to confirm with y (yes) or n (no):

  1. sudo ufw delete 4

Confirming the prompt deletes the rule:

Output
Deleting:
 allow 80
Proceed with operation (y|n)? y
Rule deleted (v6)

Enabling UFW

Once you have defined all the rules you want to apply to your firewall, you can enable UFW so it starts enforcing them. If you are connecting via SSH, make sure you have allowed your SSH port, commonly port 22, before enabling. Otherwise, you could lock yourself out of your server:

  1. sudo ufw enable

Enabling the firewall confirms it is now active and will start on boot:

Output
Firewall is active and enabled on system startup

To confirm your changes went through, check the status to review the list of rules:

  1. sudo ufw status

The status output lists each active rule and the action UFW takes:

Output
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
22/tcp                     ALLOW       Anywhere
2222/tcp                   ALLOW       Anywhere
20/tcp                     ALLOW       Anywhere
80/tcp                     DENY        Anywhere
…

For a more comprehensive view that also shows the default policies and logging level, use verbose:

  1. sudo ufw status verbose

To disable UFW at any time, run the following:

  1. sudo ufw disable

Disabling the firewall stops it and removes it from startup:

Output
Firewall stopped and disabled on system startup

Enabling UFW logging

Logging records the traffic UFW handles, which is invaluable for spotting blocked connection attempts and debugging your rules. Turn logging on with the following:

  1. sudo ufw logging on

UFW supports several logging levels, so you can balance detail against log volume. Set a level by name:

  1. sudo ufw logging medium

The available levels are low (logs blocked packets that do not match the policy), medium (adds logging of new connections and some matched packets), high (logs with rate limiting and more detail), and full (logs everything with no rate limit). On most cloud servers, low or medium is a good balance. UFW writes its entries to /var/log/ufw.log, where you can review them:

  1. sudo tail /var/log/ufw.log

To confirm that logging is active and to see which level is currently set, run:

  1. sudo ufw status verbose

The output includes a Logging: line such as Logging: on (medium) that shows the active level alongside your rules and default policies.

Resetting default settings

If for some reason you need to clear your server’s rules and start over, you can do so with the ufw reset command. You receive a prompt to confirm with y or n before resetting, since doing so can disrupt existing SSH connections:

  1. sudo ufw reset

UFW backs up your current rule files before clearing them, then disables itself:

Output
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.20220217_190530'
Backing up 'before.rules' to '/etc/ufw/before.rules.20220217_190530'
Backing up 'user6.rules' to '/etc/ufw/user6.rules.20220217_190530'
Backing up 'before6.rules' to '/etc/ufw/before6.rules.20220217_190530'

Resetting disables UFW and deletes any rules you previously defined. It also restores the default policies (deny incoming and allow outgoing). After a reset, re-allow required services (especially SSH) and then re-enable the firewall.

Troubleshooting common UFW issues

A few problems come up often when you first work with UFW. The following subsections cover each one with its specific fix.

Locked out of SSH after enabling UFW

This is the most common UFW problem, and it happens when you run sudo ufw enable without first allowing your SSH port, so the default deny-incoming policy blocks your own session. If you still have an open terminal, add the SSH rule immediately with sudo ufw allow OpenSSH and the existing session will continue to work. If you have already been disconnected, use your provider’s web console or recovery console to log in locally, then run sudo ufw allow OpenSSH before reconnecting over SSH. To avoid this entirely, always allow SSH before enabling the firewall.

Rules not persisting after reboot

UFW rules are saved to disk and reloaded on boot once the firewall is enabled, so persistence problems usually mean UFW itself is not enabled to start at boot. Confirm the service is active and enabled with sudo ufw status verbose, which should report Status: active. If it reports inactive after a reboot, run sudo ufw enable (which also registers it for startup) and, on systems using systemd, confirm the unit is enabled with sudo systemctl enable ufw.

IPv6 rules not applying

If your IPv4 rules work but IPv6 traffic is not being filtered as expected, the cause is almost always that IPv6 support is turned off in the configuration. Open /etc/default/ufw and confirm that IPV6=yes is set, then reload the firewall by running sudo ufw disable followed by sudo ufw enable, since changes to that file only take effect after a restart. After re-enabling, rule confirmations should show both Rule added and Rule added (v6).

UFW status shows inactive after reboot

If sudo ufw status reports inactive even though you added rules, the firewall was never enabled or its startup unit is disabled. Enabling UFW with sudo ufw enable both activates it now and configures it to load on every boot. On a minimal Debian install, also verify the service is enabled in systemd with sudo systemctl is-enabled ufw; if it returns disabled, enable it with sudo systemctl enable --now ufw.

FAQs

1. How do I set up a UFW firewall on Ubuntu?

The minimal sequence is to set your default policies, allow SSH, then enable the firewall. Run sudo ufw default deny incoming, sudo ufw default allow outgoing, sudo ufw allow OpenSSH, and finally sudo ufw enable. After that, open any additional ports your services need, such as sudo ufw allow 80/tcp for a web server, and confirm everything with sudo ufw status verbose. The relevant steps are covered in the “Setting up UFW defaults” and “Enabling UFW” sections above.

2. Does UFW work on Debian?

Yes, UFW works on Debian. The difference from Ubuntu is that UFW is not installed by default on Debian, so you install it with sudo apt update followed by sudo apt install ufw. Once installed, every command behaves the same as on Ubuntu, and the firewall remains inactive until you run sudo ufw enable.

3. Which is better, firewalld or UFW?

Neither is universally better; the right choice depends on your system and needs. UFW is simpler and is the natural fit for single-server setups on Ubuntu and Debian, where you mostly open a handful of ports. firewalld is better suited to Red Hat family systems such as Rocky Linux and Fedora, and to environments that need dynamic zone management for different network interfaces. For a straightforward Ubuntu or Debian cloud server, UFW is usually the easier and quite capable option.

4. What are UFW best practices for an Ubuntu cloud server?

Always allow SSH before enabling the firewall, keep the default policy set to deny incoming and allow outgoing, and open only the ports your services actually require. Use sudo ufw limit ssh to slow down brute-force attempts, turn on logging with sudo ufw logging on, and review your rules periodically with sudo ufw status numbered. Where possible, restrict sensitive services such as SSH to known IP addresses rather than leaving them open to the entire internet.

5. How do I allow a specific port with UFW on Ubuntu?

Use sudo ufw allow followed by the port number and protocol, for example sudo ufw allow 8080/tcp to open TCP port 8080. Naming the protocol (tcp or udp) is more precise; if you provide only the port number, the rule applies to both protocols. You can confirm the rule was added with sudo ufw status.

6. How do I delete a UFW rule?

There are two ways to delete a rule. You can delete by rule specification, which mirrors how you created it, for example sudo ufw delete allow 80/tcp. Alternatively, run sudo ufw status numbered to list the rules with index numbers, then delete by number, for example sudo ufw delete 2. Deleting by number is easier when rules are long or complex, and UFW prompts you to confirm.

7. How do I check if UFW is enabled and active?

Run sudo ufw status verbose. If the firewall is on, the first line reads Status: active, followed by the default incoming and outgoing policies, the logging level, and the full list of rules. If it reads Status: inactive, UFW is installed but not currently enforcing any rules, and you enable it with sudo ufw enable.

8. Does enabling UFW affect IPv6 traffic?

Yes, as long as IPv6 support is enabled in UFW, which it is by default on modern systems through the IPV6=yes setting in /etc/default/ufw. When IPv6 is enabled, each rule you add applies to both IPv4 and IPv6, which is why rule confirmations show both Rule added and Rule added (v6). If you change that setting, you must run sudo ufw disable and sudo ufw enable for it to take effect.

Conclusion

In this tutorial, you installed and configured UFW to allow or restrict access to a subset of ports and IP addresses on an Ubuntu or Debian cloud server. You set default policies, opened ports for SSH and web traffic, worked with application profiles, enabled logging, deleted rules, and learned how to reset the firewall and troubleshoot the most common problems.

With these fundamentals in place, you have a solid, secure baseline for any cloud server. To read more about what is possible with UFW, check out our guide on UFW Essentials: Common Firewall Rules and Commands.

Further reading

To deepen your knowledge of Linux firewalls, explore these related DigitalOcean tutorials:

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Shaun Lewis
Shaun Lewis
Author
Manikandan Kurup
Manikandan Kurup
Editor
Senior Technical Content Engineer I
See author profile

With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers.

Still looking for an answer?

Was this helpful?


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Great article, glad I found this because looking at the iptables firewall option was way over my head as a noob. Quick question, aside from having this firewall setup, should I still use the iptables firewall option as well or is there another form of server security I should be using as well. Thanks for the info here and the help.

@james: UFW is an iptables wrapper, you’re indirectly using iptables while using ufw. ;]

useful article, I set up everything I needed in 5 minutes…

This works in Debian too; you might want to change the title so as not to imply that it’s just for Ubuntu.

@caesarsgrunt: Thanks! Updated.

So to allow ssh should I use:

sudo ufw allow ssh

AND

sudo ufw allow 22/tcp ?

Thanks

No, you should use only one of them, not both.

What’s the easiest way to add a whole range of specific IP addresses, such as https://www.cloudflare.com/ips?

Thanks for this. Made it pretty quick for me to get started. Used iptable setups before, but they can be annoying to setup, and have remember the rules etc.

On my debian/wheezy64 i keep having problems with ufw: trying to enable it causes the error “ERROR: problem running ufw-init” and it will not autostart at boot, does anyone know how to solve this? On my local wheezy installation everything works fine, but my box at digitalocean won’t do it :(

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Start building today

From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.