Just as regular visitors reach our server every day, so do others with more nefarious intentions. It is simply not reasonable to run an online service without some layer of protection. To protect against some of these attacks, Ubuntu ships with ufw (Uncomplicated Firewall). This is a tool designed to make Ubuntu firewall management as easy and user-friendly as possible. Specifically, ufw provides a cleaner interface for the core firewall tools netfilter and iptables, which, while robust, can be challenging to master.
What Is a Firewall?
Broadly speaking, a firewall is part of a network or server that is designed to restrict potentially malicious and unauthorized access to the hardware while still allowing outward communication from the network or server. To help make sense of the concepts here, we first need to have a comfortable understanding of how a firewall works. Feel free to skip over this section if you are already familiar with it.
How a Firewall Works
Any connection coming in or going out of a server has two main pieces of information that can be used to identify it.
- The remote address (who the server is talking to).
- The ports.
Think of the port as a two-way street. Each port can have its own service running on it to communicate with the outside world or nothing at all. By convention, ports between 0 and 1023 are dedicated specifically to system services. The ports between 1024 and 49151 while dynamically allocated. Ports between 49152 and 65535 and are used and released when needed.
A firewall has a set of rules that are checked against every incoming connection. Using those rules, the firewall decides whether to allow or dent the connection. It is a good idea to disallow all connections by default and then only allow those we need. This prevents an attacker from connecting to the server.
Initial Setup of our Ubuntu Firewall
All the following examples are based on using a new Ubuntu server, installed using one of the official Ubuntu images.
Every ubuntu version since 8.04 LTS comes with ufw installed by default. We can run the below command to install it if needed.
sudo apt install ufw -y
Fresh after installation, the firewall is disabled.
user@host:~$ sudo ufw status [sudo] password for user: Status: inactive
Allow User Access
Now, we don’t want to enable it just yet, since we are connected to the server via port 22 over SSH. If the firewall cuts that connection, we could be in a lot of trouble. Fortunately, it is easy to tell the firewall to let us through.
First, we have to figure out what IP address the server sees us using. We can find that info by issuing the who command.
user@host:~$ who user pts/0 2021-01-02 23:55 (192.168.226.1)
There we can see our current connection, with its remote IP address in parentheses. We will then whitelist that IP address, so any connections coming from our IP are allowed.
user@host:~$ sudo ufw allow from 192.168.226.1 Rules updated
Even though we have already added our first rule, the firewall is not yet filtering anything. We can change that by running ufw enable.
user@host:~$ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
We now receive a clear warning that this command may disrupt existing SSH connections. This is a good sanity check to make sure we’ve actually gone through the earlier step of allowing ourselves access. Since we have already done it, we go ahead and say yes.
In checking the server status, we now see that the firewall is active. Also, it is denying incoming connections by default with only one rule in place.
user@host:~$ sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- Anywhere ALLOW IN 192.168.226.1
Adding and Removing Firewall Rules
Since we plan to use this as a web server, we need to open ports 80 and 443. These are commonly used ports for HTTP and HTTPS traffic. While we can add a rule using the port number, ufw includes the ability to use the service name.
user@host:~$ sudo ufw allow 80/tcp Rule added Rule added (v6) user@host:~$ sudo ufw allow https Rule added Rule added (v6) user@host:~$ sudo ufw status Status: active To Action From -- ------ ---- Anywhere ALLOW 192.168.226.1 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere 80/tcp (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
Here we have allowed HTTP traffic using the port number (80) and allowed HTTPS traffic using the service name. Note that the result is the same; Ports 80 and 443 are now open for both IPv4 and IPv6 traffic.
The full list of protocols is available on the /etc/services file. It is quite long, but we can review it by running the less /etc/services command. Some useful protocols to keep in mind are below.
For email transfer:
For file transfer:
The above protocols ending in S denote secure usage via TLS protocol equivalents. There are many options from which to choose, depending on what we plan to do with our server.
Add Allow Rules
Let’s go with a practical example. Imagine we have a remote developer who needs to connect to a MySQL database on the server. Again, it is a good idea only to allow the connections we need. So, we only want to open this port to their IP address. If their IP is, for example, 192.168.1.50, we can give them access to the MySQL port using this command:
user@host:~$ sudo ufw allow from 192.168.1.50 to any port mysql Rule added user@host:~$ sudo ufw status Status: active To Action From -- ------ ---- Anywhere ALLOW 192.168.226.1 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere 3306/tcp ALLOW 192.168.1.50 80/tcp (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
Add Deny Rules
Note that port 3306 is now only open for the developer’s IP. Once we decide they no longer need this access, we can delete the rule. We accomplish this running the same command with ufw delete, as shown below.
user@host:~$ sudo ufw delete allow from 192.168.1.50 to any port mysql Rule deleted
If, for any reason, we would like to block this ex-developer from accessing our server at all, we can do so easily using this command.
user@host:~$ sudo ufw deny from 192.168.1.50 Rule added
The above command works the same for IP ranges or subnets, such as 192.168.0.0/24. It is a time-saver for allowing connections coming from internal IP addresses.
Another simple way of deleting rules is to address them by number. We can view the numbers for each rule by running ufw status numbered.
user@host:~$ sudo ufw status numbered Status: active To Action From -- ------ ---- [ 1] Anywhere ALLOW IN 192.168.226.1 [ 2] 80/tcp ALLOW IN Anywhere [ 3] 443/tcp ALLOW IN Anywhere [ 4] Anywhere DENY IN 192.168.1.50 [ 5] 80/tcp (v6) ALLOW IN Anywhere (v6) [ 6] 443/tcp (v6) ALLOW IN Anywhere (v6) user@host:~$ sudo ufw delete 4 Deleting: deny from 192.168.1.50 Proceed with operation (y|n)? y Rule deleted
One other very useful feature of ufw is the ability for apps we install to register themselves on the Ubuntu firewall. We can view these rules using ufw app list command. In the following example, we already have Apache and OpenSSH installed. The list feature allows us the ability to open other ports easily.
user@host:~$ sudo apt install apache2 [...] apache2 is already the newest version (2.4.41-4ubuntu3.1). user@host:~$ sudo ufw app list Available applications: Apache Apache Full Apache Secure OpenSSH
With this, we can use the service’s full name to allow or deny the complete service quickly. For this example, we’ve also already removed ports 80 and 443 that we had added previously.
user@host:~$ sudo ufw status Status: active To Action From -- ------ ---- Anywhere ALLOW 192.168.226.1 user@host:~$ sudo ufw allow "Apache Full" Rule added Rule added (v6) user@host:~$ sudo ufw status Status: active To Action From -- ------ ---- Anywhere ALLOW 192.168.226.1 Apache Full ALLOW Anywhere Apache Full (v6) ALLOW Anywhere (v6)
These app integrations are different from the pseudonyms we used earlier (for HTTPS and MySQL, respectively). It allows applications to have complex rules for their specific needs instead of simply translating to a single open port. Likewise, it has the convenience of letting us enable or disable all rules needed by this application with just one command.
Many more tools are included in ufw that go beyond the scope of this article’. These include logging control, more complex rule syntax, rate limiting, and management of multiple network interfaces. If you are interested in advanced features related to this Ubuntu firewall tool, we encourage you to explore ufw on a non-production server or virtual machine where we are more comfortable making changes. More information about the capabilities of ufw can be found via man page.
We pride ourselves on being The Most Helpful Humans In Hosting™!
Our technical support staff is always available to assist with any issues related to this article, 24 hours a day, 7 days a week 365 days a year.
We are available, via our ticketing systems at firstname.lastname@example.org, by phone (at 800-580-4986) or via a LiveChat or whatever method you prefer. We work hard for you so you can relax.