Uncomplicated Firewall, or UFW, is an
iptables interface that aims at facilitating the configuration process of a firewall. Although
iptables is a solid and flexible tool, it can be difficult for beginners to learn how to use them to properly configure a firewall. If you want to start protecting your network and don’t know what tool to use, UFW may be the right choice for you.
In this tutorial you will learn how to configure a firewall with UFW on Ubuntu 18.04.
To follow this tutorial, you will need:
A Ubuntu 18.04 server.
UFW is installed by default on Ubuntu. If it is uninstalled for some reason, you can install it with
apt install ufw.
Step 1: Using IPv6 with UFW (optional)
Although this tutorial was written with IPv4, it also works for IPv6. If you’re using IPv6, make sure that UFW is configured to support IPv6, so it can manage the firewall rules to IPv6 and IPv4. To do this, open the UFW configuration with
nano on your editor.
sudo nano /etc/default/ufw
After, verify if
yes. It should be like this:
Save your progress and close the file. Now, when UFW is enabled, it is configured to record the firewall rules to IPv4 and IPv6. However, before activating UFW, we want to make sure your firewall is setup to allow SSH connection. We will start by defining the default policies.
Step 2: Setting Up Default Policies
If you’re only starting with your firewall, the first rules to define are the default policies. These rules control how to deal with traffic that doesn’t explicitly correspond to any other rule. By default, UFW is configured to deny all the input connections and allow all the output connections. That means that any person that tries to access your server won’t be able to connect, while any application in the server will be able to reach the external world.
We will set UFW rules back to default, so we can be sure that you will be able to follow this tutorial. To define the patterns used by UFW, use the commands:
ufw default deny incoming ufw default allow outgoing
These commands define the patterns to deny the incoming and allow the output connections. Only these firewall patterns can be enough to a personal computer, but the servers generally need to answer the demands it gets from external users.
Step 3: Allowing SSH connections
If we activate our UFW firewall, it would deny all the input connections. That means we will need to create rules that allow legit income connections - SSH or HTTP ones, for example - if we want our server to answer to this kind of demands. If you are using a cloud server, you’ll probably wish to allow SSH input connections to be able to connect and manage your server.
To setup your server in order to allow SSH input connections, you can use this command:
ufw allow ssh
This will create firewall rules that will allow all connections on port 22, which is the port that daemon SSH listens by default. UFW knows that
allow ssh means port because it is listed as a service in the /etc/services file.
However, we can really make an equivalent rule specifying the port instead of the service name. For example, this command works the same way above:
ufw allow 22
If your daemon is configured to a different port, you’ll have to specify the proper port. For example, if your SSH server is listening to port
2222, you can use this command to allow connections to this port:
ufw allow 2222
Now that your firewall is configured to allow input SSH connections, we can activate it.
Step 4: Activating UFW
To enable UFW, use this command:
You’ll get a notice telling that the command can interrupt the existing SSH connections. We already set up a firewall rule that allows SSH connections, so it might be good to continue. Answer the prompt with
y and press
Now your firewall is active. Run the
ufw status verbose command to see the defined rules. The rest of this tutorial is about how to use UFW in more details, such as allow or deny different kinds of connection.
Step 5: Allowing Other Connections
At this point, you might allow all other connections your server needs to answer. The connections you need to allow depend on specific necessities. Happily, you already know how to write rules that allow connections based in a name or service port; we already made it through SSH on port
22. You can also do it for:
HTTP on port 80, which is what unencrypted web servers use, through
ufw allow http or
ufw allow 80
HTTPS on port 443, which is what encrypted web servers use, through
ufw allow https or
ufw allow 443
There are other ways to allow connections, other than specifying a port or service. Specific Port Ranges It’s possible to specify port ranges with UFW. Some applications use different ports, instead of an only port.
For example, to allow X11 connections, which use ports
6007, use the following commands:
ufw allow 6000:6007/tcp ufw allow 6000:6007/udp
When specifying port ranges with UFW, you must specify the protocol (
to which the rules must apply.
Specific IP addresses
When working with UFW, you can also specify IP addresses. For example, if you want to allow connections of a certain IP address, such as the IP address of your home or work
203.0.113.4, it is necessary to specify
from the IP address:
ufw allow from 203.0.113.4
You can also specify a specific port to which the IP address can connect, adding
to any port followed by the port number. For example, if you want to allow
203.0.113.4 to connect to the port
22 (SSH), use this command:
ufw allow from 203.0.113.4 to any port 22
If you want to give permission to a subnet of IP addresses, you can do it through the CIDR notation to specify a netmask. For example, if you want to allow all the IP addresses from
203.0.113.254 you can use the command:
ufw allow from 203.0.113.0/24
You can also specify the destination port to which the sub
203.0.113.0/4- network can connect. Again, we’ll use the port 22 as an example.
ufw allow 203.0.113.0/24 to any port 22
Connections to a Specific Network Interface
If you want to create a firewall rule to apply only to a specific network interface, you can do it specifying “allow in on” followed by the interface name.
You can search your interfaces before continue. For this, use the command:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
. . .
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
. . .
The highlighted output indicates the names of the network interface. They are normally called something like
Therefore, if your server has a public network interface called
eth0, you’ll be able to allow HTTP (port 80) traffic with this command:
ufw allow in on eth0 to any port 80
This would allow other servers in your network to connect to your MySQL database.
Step 6: Refusing Connections
If you have not changed the default policy for incoming connections, UFW is configured to deny all incoming connections. This typically simplifies the process of creating a secure firewall policy, requiring you to create rules that explicitly allow specific IP addresses and ports.
However, sometimes you may want to deny specific connections based on the source IP address or subnet, perhaps because you know your server is being attacked from there. Also, if you want to change your default input policy to allow (which is not recommended), you will need to create deny rules for any services or IP addresses for which you do not want to allow connections.
To write deny rules, you can use the commands described above, overriding allow with deny.
For example, to deny HTTP connections, you can use this command:
ufw deny http
Or if you want to deny all the connections from
203.0.113.4, issue the command:
ufw deny from 203.0.113.4
Step 7: Deleting Rules
Knowing how to exclude firewall rules is as important as knowing how to create them. There are two different ways to specify which rules to exclude: by rule number or by the actual rule (similar to how the rules were specified when they were created). We'll start with the delete by rule number method because it's easier.
By rule number
If you are using the rule number to exclude firewall rules, the first thing you will want to do is obtain a list of firewall rules. The UFW status command has an option to display numbers next to each rule, as shown here:
ufw status numbered
To Action From
[ 1] 22 ALLOW IN 184.108.40.206/24
[ 2] 80 ALLOW IN Anywhere
If we decide that we want to delete rule 2, which allows port 80 (HTTP) connections, we can specify it in a UFW delete command like this:
ufw delete 2
This would display a confirmation prompt and then delete rule 2, which allows HTTP connections. Note that if you have IPv6 enabled, you can also delete the corresponding IPv6 rule.
By Actual Rule
The alternative to rule numbers is to specify the actual rule to exclude. For example, if you want to remove the
allow http rule, you can type as follows:
ufw delete allow http
Step 8: Verifying UFW status and rules
At any time, you can verify the UFW status with this command:
ufw status verbose
If UFW is disabled, which is default, you will see something like this:
If UFW is active, which should happen if you followed Step 3, the output will say that it is active and will list the configured rules. For example, if the firewall is configured to allow 22 SSH (port) connections from anywhere, the output might look something like this:
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
22/tcp ALLOW IN Anywhere
Step 9: Disabling or reconfiguring UFW
If you decide that you do not want to use UFW, you can disable it with this command:
Any rules you have created with UFW will no longer be active. You can always run sudo ufw enablese to need to activate it later.
If you already have UFW rules configured, but decide that you want to start over, you can use the reset command:
This will disable UFW and will delete any rules that were previously set. Keep in mind that the default policies will not be changed to their original settings if you have modified them at any time. That should give you a fresh start with UFW.
Your firewall is now configured to allow (at least) SSH connections. Be sure to allow any other incoming connections to your server by limiting unnecessary connections, so your server is functional and secure.