A firewall is a security system for networks that monitors all incoming and outgoing traffic. It permits or blocks data packets based on predefined security rules.
If you are running a production system, it is vital for you to understand how to configure a firewall. Firewall-protected systems are less likely to get infected by harmful information, because they are less exposed to the Internet, as incoming and outgoing traffic is strictly filtered according to the security rules.
What is UFW?
UFW, also called the Uncomplicated Firewall, is a front-end framework that provides a simple interface for using iptables utility to manage netfilter - a default Linux kernel packet filtering system. It is a built-in firewall system for Ubuntu 20.04 that simplifies complicated iptables commands and allows you to create basic firewall configurations more easily.
UFW uses a command-line interface with a small number of simple commands. It supports all the basic firewall rules, various network protocols, logging, and many more features. You may check an extensive list of features in the official UFW documentation.
To configure UFW, you need to have the following things beforehand:
- Ubuntu 20.04 system with root privileges
- Basic knowledge of command-line interface (CLI)
NOTE: This tutorial is not only applicable to Ubuntu 20.04, but other LTS versions as well. Early versions of UFW had been available since Ubuntu 12.04.
Install UFW Firewall
UFW comes pre-installed with Ubuntu operating system. However, you can make sure that you have the latest version of UFW by trying to install it using the following command:
apt install ufw
Now that you have the latest version of UFW installed, let’s check its status by using the following command:
As you can see, UFW is inactive by default. We are going to enable it after making some important changes first.
UFW Default Firewall Policies
If you're getting started with UFW for the first time, it is a good idea to double-check the default firewall policies. To do so check the default configuration file of UFW:
By default, UFW is configured to deny all incoming traffic and allow all outgoing traffic. This means that nobody is able to reach your system, while you can make outgoing requests from any application or service.
The default UFW policies can be changed with the following command pattern:
ufw default <policy> <chain>
For instance, if you want to allow all incoming traffic use the following command:
ufw default allow incoming
While the following command will deny all outgoing traffic:
ufw default deny outgoing
A confirmation message will be shown after each policy change, for instance:
Allow SSH Connections
By default UFW will block all incoming traffic including SSH and HTTP. If you enable the firewall before setting an exception, your current remote session will be terminated and you won’t be able to connect to your server anymore.
To avoid this you need to allow incoming SSH connections by using the following command:
ufw allow ssh
It will open port 22 which is the default port. As you can see, two new firewall rules have been added for IPv4 and IPv6 protocols respectively:
If you have configured SSH to use another port, please use a more specific command to create an allow rule for SSH connections. For instance, if you have ssh service listening to port 4422, use the following command:
ufw allow 4422/tcp
This firewall rule allows TCP connections to port 4422.
Enable UFW Firewall
Now that your UFW has been configured, you need to enable it by using the following command:
This is going to immediately start UFW daemon and enable it on system startup. Accept the given prompt by typing y and press ENTER to continue.
You may double check that it is running using the systemctl service manager:
systemctl status ufw
Add UFW Firewall Rules
There are various firewall rules that you can apply to your system through UFW:
allow– allow traffic
deny– silently discard traffic
reject– reject traffic and send back an error packet to the sender
limit– limit connections from a specific IP address that has attempted to initiate 6 or more connections in the last 30 seconds
You may apply these firewall rules in a generic or a more specific scope. The generic scope applies the UFW rule to both incoming and outgoing traffic. You may use it with the following command pattern:
ufw [rule] [target]
On the other hand, you may want to apply the rule to either incoming, or outgoing traffic specifically. In such case you should use the following command patterns accordingly:
ufw [rule] in [target]
ufw [rule] out [target]
We will go through some practical examples later, so you could see some real life applications.
UFW firewall rules can operate on many different targets. You may target service names, ip addresses, ports and even network interfaces. Let’s now get through each of these targeting patterns to see what is possible.
Target Application Profiles
When ufw is installed, most applications that rely on the network for communication register their profile with ufw, allowing the users to quickly allow or deny external access to that application.
You can check which applications are registered at UFW with the following command:
ufw app list
Here's how your output may look like:
To allow incoming and outgoing access to any of these applications use the following command pattern:
ufw allow [App name]
For instance, you may allow OpenSSH connections with the following command:
ufw allow OpenSSH
This firewall rule allows all incoming and outgoing traffic for OpenSSH application. You can be more specific and only allow incoming SSH traffic with the following command:
ufw allow in OpenSSH
Nevertheless, the best practice for enabling SSH access in a remote server is to use the limit ruleset. It allows only 6 connections from the same IP address within 30 second window, saving you from a potential brute-force attack. Use limit rather than allow ruleset for OpenSSH application in production environment:
ufw limit OpenSSH
Target IP Addresses
In UFW you can allow or deny a specific IP address with the following command pattern:
ufw [rule] from [ip_address]
For instance, if you saw some malicious activity from IP address 192.168.100.20, you may block all traffic from it by using the following command:
ufw deny from 192.168.100.20
Although you have blocked all incoming traffic from this malicious IP address, it may still reach your server in some cases. This may happen because UFW applies its rules from top to buttom. For instance, your first rule may
allow all incoming traffic to port 22 and your
deny from 192.168.100.20 rule may be one step blow.
In order to avoid such situations use the
prepend option to add the most specific firewall rules to the very top of your rules list. The final command would look like this:
ufw prepend deny from 192.168.100.20
You can also target specific ports or port ranges with UFW. For instance, you may allow connections to port 8080 using any protocol:
ufw allow 8080
Usually, you may want to be more specific and only allow connections to a specific port using a particular network protocol. Forn instance, you may allow TCP connections to port 8080 only with the following command:
ufw allow 8080/tcp
However, sometimes your application may use a range of ports for different activities. In such case, you may use the following command to whitelist a port range:
ufw allow 8080:9090/tcp
Remember a possibility to target IP addresses? If you do not want to block all traffic from an IP address whatsoever, you may be a bit more specific and only block traffic to a specific port:
ufw deny from 192.168.100.20 to any port 53 proto udp
This way you will block all traffic from 192.168.100.20 to port 53 using the UDP protocol, which is usually reserved for a DNS service.
Here's how your output would look like:
Target Network Interfaces
Some systems have multiple network interfaces configured that may require distinct firewall rules. Forutnatelly, UFW allows you to target a specific network interface and only apply the firewall rule to it. Let’s try it out.
First, list your system’s network interfaces with the following command:
As you can see, there are currently three network interfaces on configured on a Ubuntu 20.04 system. Let’s target the second one named
eth0. To do so you should use the
on eth0 option in your UFW command:
ufw allow in on eth0 from 192.168.100.255
Now all traffic from 192.168.100.255 is only allowed to the eth0 network interface:
Check UFW Firewall Rules
Now that you have finished adding your firewall rules it is a good idea to double check the rules table to see the results. You can check your active UFW rules by using the following command:
To see a more detailed version of the UFW firewall rules, use the
ufw status verbose
And if you want to simply see a list of rules in a way that you first typed them, use the following command:
ufw show added
In contrast to
ufw show command displays firewall rules even when UFW is disabled.
Delete UFW Firewall Rules
Now that you have finished adding firewall rules, what if you wanted to remove some of them? For that purpose we have two methods available: you may either deleted a rule by its number, or delete it by its name. Let’s go through each of them.
Delete by Number
You can delete UFW rules by numbering your rules table and then deleting a specific rule by using its associated number.
First, check a numbered list of UFW rules by using the following command:
ufw status numbered
As you can see, your firewall rules now have numbers aassociated with them which you can use to target them. For example, let’s now remove rule number 6 by using the following command:
ufw delete 6
Just press y to accept the confirmation prompt and rule 3 will be deleted.
Delete by Rule Name
The second method to delete an UFW rule is to specify it by its name. First list the rules in a way you first typed them:
ufw show added
Let’s say you want to remove the rule that denies all traffic from 192.168.100.20 IP address. To do so you must use the
delete command with a rule name
deny from 192.168.100.20. The final command would look like this:
ufw delete deny from 192.168.100.20
Manage UFW Logs
UFW supports multiple logging levels, so you could have a close look at your networking activity. By default UFW logs all blocked packets not matching the defined policy, as well as packets matching your defined rules. This is a
low logging level that you can modify if needed.
You can double check your logging activity with the following command:
ufw status verbose
The second line of the output shows that logging is on with logging level set to low.
Set UFW Logging Level
There are five UFW logging levels. Each of them has a different logging policy and collects increasingly more data. Please note that log levels above medium may generate a lot of logging output, and may quickly fill up a disk on a busy system, so use them carefully.
off- disables UFW managed logging.
low- logs all blocked packets not matching the default policy, as well as packets matching pre-set rules.
medium- same as above, plus all allowed packets not matching the defined policy, all invalid packets, and all new connections.
high- same as above, just without rate limiting, plus all packets with rate limiting.
full- same as above, just without rate limiting.
You may change the default low logging level with the following command pattern:
ufw logging [level]
For instance, use the following command to change logging level to medium:
ufw logging medium
This way you have enabled medium logging level with an increased logging scope.
Understand UFW Logs
Log files are stored in the /var/log/ directory. You may use the ls command to list all the log files created by the UFW:
You may now inspect your log files to find relevant information about UFW activity, for instance:
As you can see, there is an extensive amount of information available for you to understand UFW activity. A single line may look like this:
Jan 2 00:00:14 ubuntu-sandbox kernel: [142705.160851] [UFW BLOCK] IN=eth0 OUT= MAC=52:54:21:9a:ca:d7:fe:54:21:9a:ca:d7:08:00 SRC=184.108.40.206 DST=220.127.116.11 LEN=40 TOS=0x00 PREC=0x00 TTL=239 ID=61187 PROTO=TCP SPT=49194 DPT=10164 WINDOW=1024 RES=0x00 SYN URGP=0
Let’s now issect this line of UFW logs to better understand its meaning. The most informative variables are probably SRC and DST IP addresses with their associated port numbers SPT and DPT, but it is useful to understand them all:
[UFW BLOCK]: indicated that the packet was blocked
IN=eth0: Incoming traffic device.
OUT=: Outgoing traffic device is empty, since the traffic was incoming.
MAC=52:54:21:9a:ca:d7:fe:54:21:9a:ca:d7:08:00: The device’s MAC address.
SRC=18.104.22.168: Source IP address of a packet sender.
DST=22.214.171.124: Destination IP address that is meant to receive a packet. In this case it was my IP address.
LEN=40: Packet length.
PREC=0x00: Deprecated variables that are not relevant and set to 0.
TTL=239: Time to live for a packet. Each packet can only bounce through the given number of routers before it is terminated.
ID=61187: Unique ID for the IP datagram, shared by fragments of the same packet.
PROTO=TCP: Protocol used.
SPT=49194: Source port of a connection. This port may indicated what service has initiated the connection attempt.
DPT=10164: Destination port of a connection. This port may indicated what service was meant to receive the connection attempt.
WINDOW=1024: The size of packet the sender is willing to receive.
RES=0x00: This bit is reserved for future use. It is currently irrelevant and set to 0.
SYN URGP=0: SYN indicated that this connection requires a three-way handshake, URGP stands for urgent pointer relevancy that is irrelevant and set to 0.
Reset UFW Configuration
There are times when you need to start your configuration from scratch. In case you want to reset your UFW configuration to default settings there is a command for that purpose:
y when prompted and press
ENTER to reset all active firewall rules and turn off the UFW daemon. As you can see, UFW automatically creates backup files for the rules you have just reset, in case you change your mind or want to review them in the future.
Now you know how to set up and manage the UFW firewall system on Ubuntu 20.04. For future reference feel free to use the official Ubuntu documentation to refresh your memory on the basic features and learn about advanced UFW functionality: https://wiki.ubuntu.com/UncomplicatedFirewall