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.
Table of Contents
Prerequisites
- A non-root sudo user. You can set one up by following our tutorial How to Create a Sudo User on Ubuntu
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.