How to Configure a Firewall (UFW) on Ubuntu 18.04

UFW, also called Uncomplicated Firewall or sometimes Ubuntu Firewall, is an easy to use interface for iptables, that’s great for filtering traffic and has good documentation. It’s main purpose is to simplify managing iptables.

In this tutorial you’ll learn how to set up and use UFW on Ubuntu 18.04.

Prerequisites

Ubuntu comes with UFW installed by default. Should it be uninstalled, for whatever reason, you can install it by running:

$ sudo apt install ufw

You can check the status of UFW by running:

$ sudo ufw status

You can check the list of available commands by running:

$ sudo ufw -h

Set Up Default Rules

To set UFW default rules, run these commands:

$ sudo ufw default allow outgoing
$ sudo ufw default deny incoming

Application Profiles

When you install an application using apt, it will add that application’s profile to /etc/ufw/applications.d. That profile contains some information about the server and settings for UFW.

You can check the application profiles on your server by running:

$ sudo ufw app list

Here’s my output:

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

If you’re on a new server, your output may look like this:

Available applications:
  OpenSSH

To view information about that application and included rules, then run:

$ sudo ufw app info OpenSSH

Output:

Profile: OpenSSH
Title: Secure shell server, an rshd replacement
Description: OpenSSH is a free implementation of the Secure Shell protocol.

Port:
  22/tcp

As we can see, OpenSSH profile opens port 22.

Let’s check another one, say Apache Full:

$ sudo ufw app info 'Apache Full' 

Output:

Profile: Apache Full
Title: Web Server (HTTP,HTTPS)
Description: Apache v2 is the next generation of the omnipresent Apache web
server.

Ports:
  80,443/tcp

The Apache Full profile opens ports 80 and 443.

Allow SSH Connections

Before enabling UFW, we need to enable SSH connections. Given the fact that probably most of us are using our server via SSH, if we enable UFW without creating a rule to allow SSH, then we’ll get locked out of the server, since the rule is not added by default.

To configure UFW to allow SSH connections, run:

$ sudo ufw allow ssh

Output:

Rules updated
Rules updated (v6)

UFW knows to create firewall rules that will allow connections on port 22, which is the port that the SSH service listens to by default. It knows this because SSH is listed as a service in the /etc/services file:

$ cat /etc/services | grep ssh
ssh                22/tcp                                # SSH Remote Login Protocol

You can write the equivalent to this rule by specifying the port number you want to allow connections to, instead of using service name. Since SSH uses Port 22, the command would be:

$ sudo ufw allow 22

If you’ve configured SSH to use a different port, other than 22, then you can run the same command with the port you’ve configured for SSH. Say your server is listening on port 45231 , the command would be:

$ sudo ufw allow 45231

Enable UFW

Now that UFW is configured to allow incoming SSH connections and we have access to reconfigure it, should we make a mistake, we can enable it. To enable UFW, use this command:

$ sudo ufw enable

You’ll receive a warning that says that enabling UFW may disrupt SSH connections. Since you’ve already allowed connections on SSH, you can enter y and confirm:

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Check UFW Status & Rules

Now the firewall is enabled and you can run sudo ufw status to check it’s status and to see what rules are set:

Here’s my output right now, after allowing SSH:

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)

To view a more detailed report, you can also add the parameter verbose :

$ sudo ufw status verbose

Allow Other Connections

You should also allow other connections that your server needs to respond to, depending on your needs. For example, web servers, like Apache, use port 80 for HTTP and port 443 for HTTPS

Allow Specific Ports

To allow access to port 80 for HTTP and 443 for HTTPS, we can write the rule to allow connections based on the port or service name, such as we did with SSH:

$ sudo ufw allow 80
$ sudo ufw allow 443

OR

$ sudo ufw allow http
$ sudo ufw allow https

Alternatively, since we have the application profile for Apache, we can use the application profile name, which opens up both ports 80 and 443, as it shows when we run sudo ufw app info 'Apache Full':

$ sudo ufw allow 'Apache Full'

Allow Port Ranges

UFW also give us the option of allowing a range of ports. When allowing port ranges, however, you need to specify the protocol – udp or tcp:

$ sudo ufw allow 1000:2000/tcp
$ sudo ufw allow 1000:2000/udp

Allow Specific IP Addresses

If you want, for example, to whitelist an IP address and allow it access on all ports, you can add from followed by the IP address. Say my IP home/work IP address is 196.148.222.123, then I’d run:

$ sudo ufw allow from 196.148.222.123

Allow Specific IP Addresses on Specific Ports

If you want to allow access to an IP address on a specific port, say 22 , and the IP I want to allow is 196.148.222.123, then I’d run a command similar to when allowing an IP address on all ports, but specifying to any and followed by the port:

$ sudo ufw allow from 196.148.222.123 to any port 22 

Allow Subnets

Allowing access to a subnet is similar to the one allowing access to a single IP address, but instead of the IP address you will have to use the CIDR notation to specify the netmask. Say I want to allow access to IPs ranging from 196.148.222.1 to 196.148.222.254, then I’d run:

$ sudo ufw allow from 196.148.222.0/24

Allow Subnets on Specific Ports

To allow a subnet on a specific port, the command is similar to the previous example when allowing a single IP address on a specific port:

$ sudo ufw allow from 196.148.222.0/24 to any port 22

Allow Specific Network Interfaces

If you want to allow access only on specific network interfaces, then you can do this by using allow in on .

We can check our network interfaces by running:

$ ip addr

Output:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
...

The network interfaces are lo and eth0. Say I want to allow access on eth0 for HTTP ( port 80 ). To do this I’d run:

$ sudo ufw allow in on eth0 on any port 80

Deny Connections

The default policy for UFW is to deny all incoming connections, so unless you specify otherwise, UFW will deny all incoming connections.

To write deny rules, you can use the deny subcommand similarly to how you use the allow subcommand. For example, if I want to deny all HTTP and HTTPS traffic I can run:

$ sudo ufw deny HTTP
$ sudo ufw deny HTTPS

I can also deny HTTP and HTTPS by specifying the port numbers:

$ sudo ufw deny port 80
$ sudo ufw deny port 443

If I’m under attack from a certain IP address, then I can deny connections from that IP address:

$ sudo ufw deny from 196.148.222.123

Writing deny rules is the same as with allow rules. You just have to replace allow with deny.

Delete Rules

There are two ways you can delete rules. You can either delete them by the rule number or by specifying the rule.

To check the rules by their number you can run the following command:

$ sudo ufw status numbered

And you’ll get an output like this:

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)

If you’d like to delete rule number 2, you can use the delete subcommand followed by the rule number:

$ sudo ufw delete 2

Alternatively, you can delete it by specifying the actual rule. For example if you created the rule using sudo ufw allow 80/tcp you can run:

$ sudo ufw delete allow 80/tcp

You can also delete by service name:

$ sudo ufw delete allow https

This will delete both IPv4 and IPv6 rules.

Enabling IPv6 Support (Optional)

This tutorial is written with IPv4 in mind, however you may have noticed that I’ve had IPv6 enabled. Should you not have IPv6 enabled you can configure UFW to support it by editing the UFW configuration file in your favorite editor:

$ sudo nano /etc/default/ufw

And make sure that the value of IPV6 is set to yes:

...
IPV6=yes
...

Save and close the file when you’re finished.

To apply the changes, restart UFW by disabling and re-enabling it:

$ sudo ufw disable
$ sudo ufw enable

Disable/Reload/Restart UFW

To disable UFW use the disable subcommand:

$ sudo ufw disable

If you need to reload ( reload rules ) use the reload subcommand:

$ sudo ufw reload

To restart UFW, you’ll have to disable and enable it again:

$ sudo ufw disable
$ sudo ufw enable

Reset to Default Settings

If you’ve already configured UFW but need to reset it back to default settings then you can run the reset command:

$ sudo ufw reset

Output:

Resetting all rules to installed defaults. This may disrupt existing ssh
connections. Proceed with operation (y|n)?

This will disable UFW and delete any rules that you previously configured and give you a fresh start.

IMPORTANT: If you plan to enable it again, then remember to allow SSH connections again, or you won’t be able to SSH into the server.

Conclusion

Well done! You’ve learned how to configure UFW Firewall and secure your Ubuntu 18.04 machine. If you plan to remotely connect then remember to allow SSH access, allow other connections that your server needs, and limit any unnecessary connections to keep your server secure.

If you’re looking for a high-performance VPS at entry-level prices, then feel free to check out our KVM Plans. Our plans start at 1GB RAM + 10GB SSD for only $9.99/mo.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments