UFW Essentials: A Beginner's Guide to Using UFW

UFW Essentials: A Beginner's Guide to Using UFW

Prateek Dagur Firewall

Table Of Contents

Introduction

As a system administrator, it is often necessary to configure firewall rules to ensure the security of your servers. UFW, or Uncomplicated Firewall, is a popular firewall manager for Linux systems. In this guide, we will cover the basics of using UFW to manage your firewall rules.

UFW is a frontend for the popular iptables firewall. Simply put, iptables is a program that helps to control traffic going in and out of your Linux system. It works with the underlying netfilter system to help decide which traffic should be allowed and which should be blocked.

UFW is even more simplified netfilter interface. It provides a simpler way to manage a netfilter firewall and uses iptables for configuration. It is ideal for users who are new to firewalls because of simple syntax and easier integration with other applications (such as nginx). UFW is installed by default on Ubuntu, and is available for other Linux distributions.

Note: It is not recommended to build new firewalls on top of iptables anymore. Nftables replaces the popular {ip,ip6,arp,eb}tables. It is available since Linux kernel 3.13 released in Jan 2014. It provides easier syntax and rule management and addresses problems like scalability and performance. If you need enterprise class firewalling, you should definitely invest the time and effort in learning nftables.

Note: If you're using Docker, please note that by default Docker manipulates iptables rules. Any rules you set up with UFW don't apply to Docker containers. If you're running Docker 20.10.0 or higher, Docker provides support for firewalld and automatically add firewall rules for you.

Prerequisites

Before you begin, make sure your system has a non-root user account with sudo privileges. Follow the Initial Server Setup for Ubuntu 22.04 guide to learn how to do this. If you don't want to use sudo, you can execute the same commands as root.

Install UFW

If you're running commands as root, use the same commands but minus sudo.

Debian / Ubuntu

UFW is installed on Ubuntu already. In case it's not, use this command:

sudo apt-get install ufw

Arch Linux


1. Install UFW

sudo pacman -S ufw

2. Start and enable UFW

sudo systemctl start ufw
sudo systemctl enable ufw

It should enable the autostart of the UFW service in init.d. This means UFW should be automatically enabled on boot now.

Note: Above command switches on the UFW daemon. This doesn't enable the firewall rules.

CentOS / RHEL and Fedora

Another iptables front-end firewalld is the default firewall application on RPM based distributions such as CentOS, RHEL, Fedora, OpenSUSE. It's suggested that you deactivate and disable firewalld before using UFW.

sudo systemctl stop firewalld
sudo systemctl disable firewalld

UFW is available in Fedora packages. So, try following command:

sudo dnf install ufw

Or using yum:

sudo yum install ufw

In case that doesn't work you need to install the EPEL(Extra Packages for Enterprise Linux) repository on your system.

sudo dnf install epel-release

Then install UFW by running this command:

sudo dnf install ufw

If above commands fail to install UFW, you may try these:

sudo yum install epel-release
sudo yum install --enablerepo="epel" ufw

Now, start and enable the UFW unit:

sudo systemctl start ufw
sudo systemctl enable ufw

SUSE / OpenSUSE

First of all, you should deactivate any of the previously installed firewall programs.

Stop and disable SuSEfirewall2:

sudo systemctl stop SuSEfirewall2
sudo systemctl disable SuSEfirewall2

Stop and disable firewalld:

sudo systemctl stop firewalld
sudo systemctl disable firewalld

Install UFW:

sudo zypper install ufw

Then start and enable the UFW's systemd unit:

sudo systemctl start ufw
sudo systemctl enable ufw

Understanding the UFW Command Structure

This is the UFW command structure:

ufw [--dry-run] [options] [rule syntax]

The UFW command structure consists of the ufw command, followed by optional parameters (--dry-run and options), followed by the rule syntax. The rule syntax defines the action to take (such as allow, deny), the protocol (tcp, udp, etc.), the source and destination addresses, and the port number.

Here --dry-run ensures that command will not modify anything, it will only show you what would happen if the command were to be run. This is useful to check what a command will do before you run it for real.

The rule syntax is used to create and manage the firewall rules in UFW. You can specify rules in two ways, using either a simple syntax or a full syntax.

  • Simple syntax: Specifies the port and optionally the protocol
  • Full syntax: Specifies the source and destination addresses, ports, and optionally the protocol

Example Rules Using the Simple Syntax

sudo ufw allow 22

This rule will allow traffic on port 22 (SSH). You can also specify a protocol by adding /protocol.

sudo ufw allow 22/tcp

This command will allow TCP packets on port 22.

If you don't know the port number for a service, don't worry. You can also specify a service by name and UFW will check /etc/services for the port and protocol. Now you can allow SSH traffic using:

sudo ufw allow ssh

And you can append protocol as you did before:

sudo ufw allow ssh/tcp

Most Used Arguments of UFW Firewall

  • allow: allows traffic that matches the specified criteria
  • deny: denies traffic that matches the specified criteria
  • limit: limit number of connections
  • status: displays whether the firewall is active
  • show: shows currently configured rules
  • reload: reloads the current running firewall
  • reset: disables and resets the firewall to its default state
  • disable: disables the firewall

Example Rules Using the Full(er) Syntax

In full syntax, we can define the source and destination addresses. Let's take an example. Suppose that someone is trying to get into your system through port 25. You can block them by creating a rule. How do you do it? Let's say their address is 10.8.0.0 and your machine's address is 192.168.0.3. Then you can write a deny rule like so:

sudo ufw deny from 10.8.0.0/6 to 192.168.0.3 port 25

The UFW command above denies traffic from the 10.8.0.0/6 subnet to the 192.168.0.3 host on port 25.

Check UFW Status

To check whether UFW is active, use:

sudo ufw status
Status: inactive

If you've firewall already enabled, you'll see a list of all the rules.

Caution: UFW is a powerful tool that can easily lock you out of your own system if not used correctly. Always make sure you know what you are doing before enabling or disabling any firewall rules. Remember to open up any ports that you need before enabling the firewall. UFW will block all incoming connections by default, so you will need to specifically allow any services you want to use. If you are using SSH to connect to the server, you must allow access via SSH port before enabling UFW or you'll be locked out from your server.

Allow SSH

SSH is a way to log into a remote server. To do so, you need to have the SSH port open on the server so that you can connect to it.

sudo ufw allow OpenSSH

You can also run sudo ufw allow ssh or sudo ufw allow 22. For added security, you should enable SSH with a limit instead(See next section).

Rules updated
Rules updated (v6)

Note: By default, UFW sets firewall rules for both IPv4 and IPv6 addresses.

How to Limit SSH with UFW

To protect your system against brute-forcing, you can allow automatic rate limiting for the connections to your SSH port. Setting a limit rule will deny the connections if an IP address tries to have six or more connections within 30 seconds.

sudo ufw limit OpenSSH

Note: You can also comment the rules. For example, if you write above command as sudo ufw limit OpenSSH comment 'Rate limiting for OpenSSH', you can see the specified comment when checking UFW status using sudo ufw status.

Note: Please note that if you add exactly same rule again, the previous rule gets overwritten.

Enable UFW

Warning: If you are connected via SSH, you must not ignore this warning. Before you enable UFW, make sure you've allowed access via SSH, otherwise you'll be locked out from your server.

You can enable UFW on your machine using:

sudo ufw enable
Firewall is active and enabled on system startup

To see what is allowed or denied, you can use status verbose to show verbose firewall status.

sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

Disable UFW

If you want to disable UFW for any reason, use:

sudo ufw disable

This command will completely disable the firewall on your server. This means that all incoming and outgoing traffic is allowed on your machine and no rules are applied.

List Available Application Profiles

When installed, applications can register their profiles with UFW. You can manage these profiles with UFW by their names. To list currently available profiles, run:

sudo ufw app list

If you installed a new service like Apache web server, make sure that it is enabled so that the profile is available in UFW.

Available applications:
  OpenSSH
  Apache
  Apache Full
  Apache Secure

Allow HTTP / HTTPS

Note: HTTP uses port 80 while HTTPS uses port 443 for data communication.

Allow Nginx HTTP / HTTPS

When you install Nginx web server, it creates some UFW profiles that can be used to set up firewall for the web server. Make sure you've enabled Nginx service and then run this command to list the available Nginx profiles:

sudo ufw app list | grep Nginx
  Nginx Full
  Nginx HTTP
  Nginx HTTPS

Choose Nginx Full if you want to enable both HTTP and HTTPS (ports 80 and 443). Or choose Nginx HTTP for HTTP or Nginx HTTPS for HTTPS.

sudo ufw allow "Nginx Full"
Rules updated
Rules updated (v6)

Allow Apache HTTP / HTTPS

When you install the Apache web server, it creates some UFW profiles that can be used to set up firewall for the web server. Make sure you've enabled Apache as a service and then run this command to list the available Apache profiles:

sudo ufw app list | grep Apache
  Apache
  Apache Full
  Apache Secure

Choose Apache Full if you want to enable both HTTP and HTTPS (ports 80 and 443). Or choose Apache for only HTTP or Apache Secure for only HTTPS.

sudo ufw allow "Apache Full"
Rules updated
Rules updated (v6)

Allow All Incoming HTTP Connections

Web servers usually listen for requests on port 80. To allow all the incoming HTTP connections, use:

sudo ufw allow http
# or
sudo ufw allow 80
Rules updated
Rules updated (v6)

Allow All Incoming HTTPS Connections

HTTPS runs on port 443. To allow all the incoming HTTPS connections, use:

sudo ufw allow https
# or
sudo ufw allow 443
Rules updated
Rules updated (v6)

Allow All Incoming HTTP and HTTPS Connections

You can create a single rule to enable both 80 and 443 ports. To do so, you have to define the tcp protocol with proto parameter.

sudo ufw allow proto tcp from any to any port 80,443
Rules updated
Rules updated (v6)

Delete UFW Rule

If you want to delete a previously set rule from UFW, you can use ufw delete followed by the rule.

sudo ufw delete allow http

Above command deletes the rule that allows traffic to the server on the HTTP port (80).

Rules updated

You can also delete a rule using the rule ID. To see these IDs, use:

sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 80/tcp                     ALLOW IN    Anywhere
[ 2] 80                         ALLOW IN    Anywhere

As you can see in above output, I have redundant rules for HTTP. To delete a rule by the number, use:

sudo ufw delete 2

Press y when prompted.

Deleting:
  allow 80
Proceed with operation (y|n)? y
Rules updated

Check the UFW status again (sudo ufw status), you'll no longer see that rule.

Enable UFW Application Profile

To get the names of available application profiles, run:

sudo ufw app list
Available applications:
  OpenSSH

To enable any application profile, append the name of the profile to ufw allow:

sudo ufw allow "OpenSSH"
Rules updated
Rules updated (v6)

Note: Quoting OpenSSH above wasn't necessary but If profile names have multiple words, you must quote them.

Disable UFW Application Profile

To disable the UFW application profile, you need to remove its corresponding rule. Consider the following results from sudo ufw status command:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Apache Full                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Apache Full (v6)            ALLOW       Anywhere (v6)

You can see that Apache Full profile is currently enabled, allowing connections via both HTTP and HTTPS. If you only want to allow HTTPS requests, you should first enable a more restrictive rule, Apache Secure in this case, and then disable the currently active one.

sudo ufw allow "Apache Secure"
sudo ufw delete allow "Apache Full"

Allow an IP Address

To allow all network connections from a specific IP address, run:

sudo ufw allow from 172.17.112.152

Replace 172.17.112.152 with your IP address.

Rules updated

Note: You can also provide subnet mask for a host.

Block an IP Address

To block all network connections from a specific IP address, run:

sudo ufw deny from 172.17.112.152

Replace 172.17.112.152 with your IP address.

Note: You can also block full subnet if that's your use case.

Allow Incoming Connections to a Network Interface

You can allow incoming connections from a specific IP address (or range of IP addresses) to a specific interface (such as eth0, eth1, etc.).

sudo ufw allow in on eth1 from 192.168.0.0/16

Replace 192.168.0.0/16 with your own IP address or subnet.

Rules updated

This command will allow inbound traffic on the eth1 interface from the 192.168.0.0/16 subnet. Here, in directive is used to apply the rule only for incoming connections while on directive is used to specify the network interface that the rule should apply to (eth1 in this case).

Block Incoming Connections to a Network Interface

You can block incoming connections from a specific IP address (or range of IP addresses) to a specific interface.

sudo ufw deny in on eth1 from 192.168.0.0/16

Replace 192.168.0.0/16 with your IP address or subnet.

This command will allow inbound traffic on the eth1 interface from the 192.168.0.0/16 subnet. Here, in directive is used to apply the rule only for incoming connections while on directive is used to specify the network interface that the rule should apply to (eth1 in this case).

Allow Incoming SSH from Specific IP Address or Subnet

You can allow incoming SSH connections from a specific IP address or subnet.

sudo ufw allow from 192.168.0.103 proto tcp to any port 22

Here, from directive specifies source address while to directive specifies the destination address. The proto keyword specifies that rule applies to tcp protocol only and port defines that rule applies to ssh service (which runs on port 22 by default).

You can allow incoming SSH from an entire network. To do so, use subnet address as source address.

sudo ufw allow from 192.168.0.0/16 proto tcp to any port 22

Allow Incoming Rsync from Specific IP Address or Subnet

The Rsync utility is used to transfer files between machines. It by default runs on port 873. You can allow incoming Rsync connections from specific IP address or subnet by using the from directive to specify the source IP address or subnet and port to define destination port (873 in this case).

sudo ufw allow from 192.168.0.103 to any port 873

This will allow Rsync connections coming from only 192.168.0.103.

You can allow incoming Rsync connections from an entire network. To do so, use subnet address like this:

sudo ufw allow from 192.168.0.0/16 to any port 873

Allow Incoming MySQL from Specific IP Address or Subnet

MySQL typically listens on port 3306. You can allow incoming MySQL connections from specific IP address or subnet by using the from directive to specify the source IP address or subnet and port to define destination port (3306 in this case).

sudo ufw allow from 192.168.0.103 to any port 3306

Use subnet to allow entire network like this:

sudo ufw allow from 192.168.0.0/16 to any port 3306

Allow Incoming PostgreSQL from Specific IP Address or Subnet

PostgreSQL typically listens on port 5432. You can allow incoming PostgreSQL connections from specific IP address or subnet by using the from directive to specify the source IP address or subnet and port to define destination port (5432 in this case).

sudo ufw allow from 192.168.0.103 to any port 5432

Use subnet to allow entire network like this:

sudo ufw allow from 192.168.0.0/16 to any port 5432

Block Outgoing SMTP Mail

Mail servers typically use port 25 for SMTP. If your server is not sending outgoing mail, you can block outgoing SMTP traffic:

sudo ufw deny out 25
Rules updated
Rules updated (v6)

Getting Help

You can check UFW's manual for detailed information about command directives and modifiers:

man ufw

You can also check out the UFW project page on the Ubuntu documentation.

Conclusion

UFW is an excellent tool for managing your server's firewall, and it's easy to get started with it. In this guide, we covered the basics of how to set up and use UFW. We hope you find it useful!

Comments