Content:
Firewalls are an important part of internet security. They’re a vital tool when running an internet facing server. They monitor traffic to and from a server, and either allow or deny traffic based on a set of rules.
Servers need to allow some access to them, for accessing the content they provide, but can become targets for hackers if they are not secured correctly.
In this guide, we’ll take a look at setting up a firewall, using Raspberry Pi OS. This will also work on other Linux distributions – just replace the commands with the equivalent for your distribution.
Installing UFW
The software we’ll be using is called UFW, or Uncomplicated Firewall. Some linux distributions come with UFW installed as default.
To try installing UFW, run the command for your specific Linux OS.
apt install ufw
If the software isn’t installed, allow it to install before continuing.
Enabling UFW
With UFW installed, we now need to enable it, by running the following:
systemctl enable ufw
systemctl start ufw
This will both enable the UFW service (causing it to automatically start on system boot), and start it now. Not that at this point, UFW will be blocking all traffic. Bare this in mind before starting the service on a critical system.
We can check that it is running using:
systemctl status ufw
The output should show that ufw is running.
● ufw.service - Uncomplicated firewall
Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
Active: active (exited) since Mon 2022-01-31 14:58:47 GMT; 3 months 0 days ago
Docs: man:ufw(8)
Process: 148 ExecStart=/lib/ufw/ufw-init start quiet (code=exited, status=0/SUCCESS)
Main PID: 146 (code=exited, status=0/SUCCESS)
CPU: 361ms
Jan 31 14:58:47 server-dev systemd[1]: Finished Uncomplicated firewall.
Warning: journal has been rotated since unit was started, output may be incomplete.
Adding Rules to UFW
Currently, our firewall is runnking, and will be blocking all traffic trying to reach our system.
We can see the current list of UFW rules by running
ufw status
This will return both the current firewall status, and the list of rules that it is applying.
~ $ ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW IN 192.168.0.0/24
137,138/udp ALLOW IN 192.168.0.0/24
139,445/tcp ALLOW IN 192.168.0.0/24
80/tcp ALLOW IN Anywhere
443 ALLOW IN Anywhere
9090/tcp ALLOW IN 192.168.0.0/24
Postfix ALLOW IN Anywhere
We can run this command at any point after adding or removing rules, to check the rule has been added as expected.
Allowing Connections On A Specific Port
We can enable connections to a specific port using the command below.
ufw allow {port}
Simply replace {port} with the number of the port you wish to open. For example
ufw allow 22
will allow connections to be made over port 22, which is used for SSH.
You can limit this further by specifying extra parameters, such as the connection protocol allowed and the IP(s) allowed to use the port.
ufw allow proto tcp from 192.168.0.0/24 to any port 3306
This command is a little more complex.
The proto command specifies whether to allow tcp or udp connections through the port. When using this parameter, we must add both from and to clauses.
To allow all connections, specify any as the from parameter. You can allow only a single IP address, or an entire subnet, as in the example above. This command allows parameters from any address in the 192.168.*.* subnet, which means any local machine can connect.
With this more complex command, the word port must precede the port number.
In full, this command allows any device in the 192.168.0.0/24 subnet to connect to this machine through tcp on port 3306.
Allowing Connections on a Specific Interface
As well as targeting ports, you can also target entire network interfaces. If your machine has multiple ethernet ports, you might want to allow specific traffic through each network interface.
ufw allow in on eth0 from any to any port 25
This command allows access in through port 25 to any client, provided the connection uses the eth0 network interface.
Allowing Application Specific Connections
To make management simpler, UFW includes a list of predefined rules for specific applications.
We can see the list of applications using
ufw app list
The resulting list will have entries similar to the below.
AIM
Bonjour
CIFS
DNS
Deluge
...
I won’t include the full output, due to the length.
You can replace the proto and port sections of the previously mentioned commands to make use of the application profile.
ufw allow "SSH"
ufw allow proto tcp from any to any port 22
These two commands do the same job.
Denying Specific Connections
The sections above have all focused on accepting specific connections. Generally speaking, this will make up the bulk of your rules, as connections will be denied by default without a corresponding ALLOW IN rule.
You might, however, wish to block certain traffic over a port. For example, if you are running a website which will use ports 80 (HTTP) and 443 (HTTPS) by default, you will need to open these ports to everyone to allow general internet users to access your site.
If you notice certain IP addresses attempting to find exploits on your server (an expected situation with anything internet facing), you might decide to block that specific IP address from accessing your server.
ufw deny
This can be used with the same parameters as outlined above – just replace allow with deny.
It’s important to note that UFW reads rules in the order they are entered, so the deny rule would have to be listed above any less restrictive allow rules.
Deleting Existing Rules
The easiest way of deleting a rule is to find find the rule number.
ufw status numbered
You will get an output similar to our earlier result, but this time, with numbers on the left-hand side.
~ $ ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN 192.168.0.0/24
[ 2] 137,138/udp ALLOW IN 192.168.0.0/24
[ 3] 139,445/tcp ALLOW IN 192.168.0.0/24
[ 4] 80/tcp ALLOW IN Anywhere
[ 5] 443 ALLOW IN Anywhere
[ 6] 9090/tcp ALLOW IN 192.168.0.0/24
[ 7] Postfix ALLOW IN Anywhere
[ 8] 3306/tcp ALLOW IN 127.0.0.0/24
To delete entry number 8, run
ufw delete 8
When prompted, enter ‘y’ to confirm.
~ $ ufw delete 8
Deleting:
allow from 127.0.0.0/24 to any port 3306 proto tcp
Proceed with operation (y|n)? y
Rule deleted
Checking Blocked Requests
If you’re finding that valid requests are not getting through to your system, or you just want to check what your firewall has been up to, you can check entries in the system journal.
journalctl | grep "UFW"
An entry similar to the below means a connection has been blocked.
[UFW BLOCK] IN=eth0 OUT= MAC=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77 SRC=198.91.80.251 DST=192.168.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=48 ID=63664 DF PROTO=TCP SPT=51728 DPT=25 WINDOW=29200 RES=0x00 SYN URGP=0
There’s a lot of information here, so let’s break it down:
- IN=eth0 – The network interface the request is using, in this case, ethernet 0.
- OUT= – The network interface of the outbound request. In this case, this is not an outbound request, so it is empty.
- MAC=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77 – The MAC address of the network interface.
- SRC=198.91.80.251 – The IP address of the request source.
- DST=192.168.0.1 – The IP address of the request destination.
- PROTO=TCP – The protocol the connection is using.
- DPT=25 – The port the connection is using.
The other parameters are not important.
In this case, 198.91.80.251 is attempting to access port 25 on the server, using TCP.
This log can be very useful for diagnosing connection issues through your firewall, and it logs both inbound and outbound requests that are blocked.
If I was expecting a connection over port 25, I would have to add a rule to allow connections over this port. If I wanted to, I could limit the connection to only TCP, or even the specific IP address of this request, and it would still get through the firewall.
Conclusion
This is by no means a definitive guide covering UFW commands, but should provide enough information to add even the most complex of rules.
UFW is an incredibly powerful tool, and when it is configured appropriately, forms a key part of server security.
