How to Use UFW Firewall on Debian, Ubuntu, Linux Mint
This tutorial is going to show you how to use UFW (Uncomplicated FireWall) on Debian/Ubuntu/Linux Mint with some real-world examples. Managing firewall is a basic skill that every system admin needs to master.
UFW is a front-end for iptables, to make managing a Netfilter firewall easier, hence the name “Uncomplicated Firewall”. It provides a command line interface with syntax similar to OpenBSD’s Packet Filter. It is particularly well-suited as a host-based firewall. UFW is the recommended iptables front-end on Debian based Linux Distros and is usually pre-installed on these distros. By default, UFW set firewall rules for both IPv4 and IPv6 address. Another well-known iptables front-end is firewalld, which is the default firewall application on RPM based Linux distros (RHEL, CentOS, Fedora, OpenSUSE, etc).
Disabling Other Iptables Restore Services
As you probably know, iptables firewall rules will be flushed when the OS shuts down and the iptables
program itself does not restore the firewall rules. UFW by default restores firewall rules after system reboot. Before using UFW, it’s important that you check whether there’s another iptables restore service on your system. If there are two restore services, they will conflict with each other, which often results in web applications not available after system reboot.
If you were using iptables firewall directly and now you want to switch to UFW, you just need to disable your iptables restore service. Iptables-persistent is a well-known iptables restore service on Debian/Ubuntu. You can check whether it’s running with the following command.
systemctl status iptables-persistent
If it’s running, you can stop and disable it.
sudo systemctl stop iptables-persistent sudo systemctl disable iptables-persistent
Or you can remove it from your system.
sudo apt remove iptables-persistent
If you have set up your mail server using iRedMail, be sure to run the following command to check whether the iptables
service is running.
systemctl status iptables
This iptables service is shipped with iRedMail to restore iptables firewall rules. If it’s running, you can stop and disable it.
sudo systemctl stop iptables sudo systemctl disable iptables
Now let’s learn how to use UFW.
Getting Started with UFW on Debian/Ubuntu/Linux Mint Server
UFW is usually pre-installed on Debian/Ubuntu/Linux Mint, although you can always run the following command to install it.
sudo apt install ufw
Note: You can install UFW on Arch Linux with sudo pacman -S ufw
, but you also need to enable the UFW systemd service with sudo systemctl enable ufw
.
On installation, ufw is disabled. You can check UFW status with:
sudo ufw status
UFW comes with a default incoming policy of deny
, a default forward policy of deny
, and a default outgoing policy of allow
, with stateful tracking for new connections for incoming and forwarded connections. Before enabling UFW, you need to know what ports are opened on the public IP address of your server, which can be obtained with the help of nmap
(Network Mapper).
Install nmap
on your Debian/Ubuntu/Linux Mint server and scan opened ports on the public IP address.
sudo apt install nmap sudo nmap 12.34.56.78
Replace 12.34.56.78 with the actual public IP address of your server. As you can see from the screenshot below, there are several opened ports on my server.
There are also opened ports that listen on localhost only, which can be obtained by running sudo nmap localhost
, but we don’t need to worry about them.
Nmap by default only scans TCP ports. We can use the following command to scan UDP ports.
sudo nmap -sU 12.34.56.78
However, UDP scan is terribly slow. If you can’t wait that long, you can use netstat
to list UDP ports.
sudo netstat -lnpu
After obtaining the opened TCP and UDP ports on your server, you need to decide which ports should be allowed to accept inbound connections. If there’s an openSSH server running, then you should always allow TCP port 22 before activating UFW. This is achieved via the following command.
sudo ufw allow 22/tcp
or
sudo ufw allow ssh
You probably want to allow HTTP and HTTPS traffic, so run the following command to allow inbound connection on TCP port 80 and 443.
sudo ufw allow 80/tcp sudo ufw allow 443/tcp
If you run an email server, you need to allow TCP port 25 (SMTP), 587(submission), 143(imap) and 993 (imaps).
sudo ufw allow 25/tcp sudo ufw allow 587/tcp sudo ufw allow 143/tcp sudo ufw allow 993/tcp
If you want your user to be able to use POP3 protocol, you need to allow TCP port 110 (POP3) and 995 (POP3S).
sudo ufw allow 110/tcp sudo ufw allow 995/tcp
If you run a BIND DNS server, then you need to open TCP and UDP port 53.
sudo ufw allow 53
The above command will allow both the TCP and UDP port. If you want to allow the UDP port only, then
sudo ufw allow 53/udp
Opening Multiple Ports at Once
You can allow multiple ports like below.
sudo ufw allow 80,443,25,587,465,143,993/tcp
Enabling UFW
After you have set allowed ports in UFW, you need to enable UFW. But before doing that, it’s recommended to enable logging with the following command so that you can better understand if your firewall is working correctly.
sudo ufw logging on
The default log level is ‘low’. The log file is /var/log/ufw.log
. I usually use the “medium” log level.
sudo ufw logging medium
Now enable UFW.
sudo ufw enable
Note: If you have previously used iptables firewall directly, those iptables firewall rules will be undone once UFW is enabled.
Check status
sudo ufw status
To show more information, run
sudo ufw status verbose
Now you can re-scan your server to find out which ports are still opened.
sudo nmap 12.34.56.78
Also, enable the UFW systemd service, so it will automatically start at system boot time.
sudo systemctl enable ufw
How to Delete A Firewall Rule
First, you need to get the reference number of the firewall rule you want to delete with the following command.
sudo ufw status numbered
Then you can delete a rule, for example, the 8th rule.
sudo ufw delete 8
Note that the reference number will change after you delete a rule, so you need to run sudo ufw status numbered
again to delete another rule.
Reset UFW
If you made a mistake, you can disable and reset firewall to installation defaults.
sudo ufw reset
This is particularly useful for beginners.
UFW Application Profile
Many server programs ship with UFW profiles. You can list all application profiles with:
sudo ufw app list
We can show information on a specific application profile, for example, the “Apache Full” profile.
sudo ufw app info "Apache Full"
We can see that the port used by this profile are TCP port 80 and 443. If we enable this application profile with the following command, TCP port 80 and 443 will be allowed.
sudo ufw allow "Apache Full"
Creating IP Address Blacklist with UFW
Let’s say there’s a spammer who is constantly trying to send spam to your mail server. You can use UFW to block the spammer’s IP address from accessing TCP port 25 of your mail server, with the following command. Replace 12.34.56.78 with the spammer’s IP address.
sudo ufw insert 1 deny in from 12.34.56.78 to any port 25 proto tcp
Note that newly added firewall rules are put in the bottom by default. If you previously allowed access to port 25 from anywhere, then you need to insert the deny rule as the first rule, just like above, so the deny rule will be applied first. You can always insert new deny rule as the first rule.
sudo ufw insert 1 deny in from 78.56.34.12 to any port 25 proto tcp
You can also block an IP address range like below.
sudo ufw insert 1 deny in from 192.168.0.0/24 to any port 25 proto tcp
To block an IP address from accessing all ports on your server, run
sudo ufw insert 1 deny in from 12.34.56.78
Creating IP Address Whitelist with UFW
Now let’s say you run a OpenSSH server and you only want to allow certain IP address to log in to your server through SSH. You can use UFW to create an IP address whitelist. For example, I don’t have static IP address in my home, but I have set up several VPN servers on the cloud, so now I can configure UFW to allow inbound connection to port 22 from the IP address of my VPN server only.
First, add the IP address to the allow list.
sudo ufw insert 1 allow in from 12.34.56.78 to any port 22 proto tcp
Then you need to get the reference number of the allow SSH from anywhere rule and delete that rule.
sudo ufw status numbered
sudo ufw delete reference-number
Note that you need to delete both the IPv4 and IPv6 rule. Also notice that if you delete the upper rule first, the reference number of the lower rule will change.
From here on out, only your IP address can access TCP port 22.
How to Use IPv6 Address in UFW
First, make sure the IPV6=yes
is set in /etc/default/ufw
file. If it’s not set, then add it in that file and restart UFW (sudo systemctl restart ufw).
Then you can just replace IPv4 with IPv6 address in ufw commands like below.
sudo ufw allow in from 2607:f8b0:4005:804::200e to any port 587
Note that you can’t insert an IPv6 rule between IPv4 rules. IPv6 rules should always be placed after IPv4 rules.
How to Set Up IP Masquerading with UFW
Sometimes you want to set up your own VPN server, then you will need to set up IP masquerading on your VPN server so that it becomes a virtual router for VPN clients. Unfortunately, UFW doesn’t provide a convenient way to do this. We have to add iptables command in a UFW configuration file.
sudo nano /etc/ufw/before.rules
By default, there are some rules for the filter
table. Add the following lines at the end of this file.
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Forward traffic through eth0 - Change eth0 to match your network interface
-A POSTROUTING -o eth0 -j MASQUERADE
# End each table with the 'COMMIT' line or these rules won't be processed
COMMIT
Notice that if your main network interface isn’t eth0
, you need to change eth0
to your network interface name, which can be obtained with the ip addr
command. And because we are adding firewall rules to a new table, namely the nat
table, we need to add the ‘COMMIT’ line.
By default, UFW forbids packet forwarding, which is great because it prevents random people on the Internet to use your box to do malicious stuff. But we need to allow forwarding for our private network. Find the ufw-before-forward
chain in this file and add the following 3 lines, which will accept packet forwarding if the source IP or destination IP is in the 10.10.10.0/24
range.
# allow forwarding for trusted network -A ufw-before-forward -s 10.10.10.0/24 -j ACCEPT -A ufw-before-forward -d 10.10.10.0/24 -j ACCEPT
Save and close the file. Then restart UFW.
sudo ufw disable sudo ufw enable
or simply
sudo systemctl restart ufw
Although this is not related to UFW configuration, but in order to route packets, you also need to set up IP forwarding. This can be done by setting the following at the end of /etc/sysctl.conf
file.
net.ipv4.ip_forward = 1
Then apply the changes with the following command.
sudo sysctl -p
How to Set Up Port Forwarding in UFW
What if you use UFW on your router, and you want to route packets such as HTTP requests to internal LAN hosts? In this case, you need to set up port forwarding. Edit the /etc/ufw/before.rules
file.
sudo nano /etc/ufw/before.rules
Then add the following lines in the NAT table, above the COMMIT line. Replace 12.34.56.78 with your router’s public IP address.
:PREROUTING ACCEPT [0:0] # forward 12.34.56.78 port 80 to 192.168.1.100:80 # forward 12.34.56.78 port 443 to 192.168.1.100:443 -A PREROUTING -i eth0 -d 12.34.56.78 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80 -A PREROUTING -i eth0 -d 12.34.56.78 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.100:443
This tells UFW to use the DNAT target to forward HTTP and HTTPS requests to the 192.168.100 host in the local network.
Hint: DNAT (Destination NAT) changes the destination IP address. A typical example is port forwarding. SNAT (Source NAT) changes the source IP address. A typical example is when a host behind a Wifi router wants to browse the Internet.
Flush the NAT table rules.
sudo iptables -F -t nat
Restart UFW to process all of the NAT rules.
sudo systemctl restart ufw
You also need to enable IP forwarding in /etc/sysctl.conf
file as mentioned above.
If the 192.168.1.100 host is also running UFW, then you need to allow port 80 and 443 in UFW.
sudo ufw allow 80/tcp sudo ufw allow 443/tcp
Note that the 192.168.1.100 LAN host must use the UFW router as the gateway. If it’s using another IP address as the gateway, port forwarding won’t work.
How to Block BitTorrent Traffic on Cloud Servers
If you run a server on the cloud, you probably want to block BitTorrent traffic on the server, because if you or someone else accidentally download illegal content (Movies, TV Shows) via BitTorrent and you are caught, your hosting provider will likely suspend your account.
Modern BitTorrent clients encrypt traffic between peers, so it’s not easy to differentiate BitTorrent traffic from other types of traffic. While there is no perfect way to block BitTorrent traffic, here is a simple solution.
Block outgoing traffic by default.
sudo ufw default deny outgoing
Then allow specific outgoing ports. For example, you need to allow the DNS port.
sudo ufw allow out 53
And you need to allow port 80 and 443 to update your software packages from the repository.
sudo ufw allow out 80/tcp sudo ufw allow out 443/tcp
If this is your mail server, you need to allow port 25.
sudo ufw allow out 25/tcp
Restart UFW for the changes to take effect.
sudo systemctl restart ufw
Although this is not a perfect solution, because some users might configure their BitTorrent clients to use port 80 or 443, in reality, this situation is quite rare. Most users just use the default settings and my BitTorrent client on the server immediately stopped all downloading and uploading when I enforce the above rules in the firewall. If it doesn’t stop, restart your BitTorrent client or your server.
Blocking Outgoing Connections to a Specific IP Address
First, you need to allow outgoing traffic.
sudo ufw default allow outgoing
Then block a specific IP address with:
sudo ufw insert 1 deny out to 12.34.56.78
Restart UFW.
sudo systemctl restart ufw
UFW and fail2ban
Fail2ban is a program that uses iptables firewall to prevent servers from brute-force attacks. UFW and Fail2ban won’t interfere with each other.
UFW Error
If you check ufw status
and get the following error, it’s probably because you have installed a new Linux kenel.
modprobe: ERROR: ../libkmod/libkmod-module.c:191 kmod_module_parse_depline() ctx=0x564bf80c82a0 path=/lib/modules/5.4.0-89-generic/kernel/net/netfilter/x_tables.ko error=No such file or directory modprobe: ERROR: could not insert 'ip_tables': Unknown symbol in module, or unknown parameter (see dmesg) iptables v1.8.4 (legacy): can't initialize iptables table `filter': Table does not exist (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded.
Check which kernel you are using.
uname -r
sample output:
5.4.0-89-generic
Check installed Linux kernels.
sudo update-grub
Sample output:
Sourcing file `/etc/default/grub' Sourcing file `/etc/default/grub.d/init-select.cfg' Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.4.0-121-generic Found initrd image: /boot/initrd.img-5.4.0-121-generic Found linux image: /boot/vmlinuz-5.4.0-120-generic Found initrd image: /boot/initrd.img-5.4.0-120-generic done
As you can see, the 5.4.0-89-generic
kernel has been deleted by an update. You can reboot the server to use the new Linux kernel. If you don’t want to reboot now, you can install the old kernel back like so:
sudo apt install linux-modules-5.4.0-89-generic linux-modules-extra-5.4.0-89-generic
Now you should be able to use UFW again.
Hint: If you still want to use the old Linux kernel, be sure to use Canonical Livepatch Service to patch Linux kernel on Ubuntu without reboot.
Gufw
Gufw is a graphical user interface for ufw.
Wrapping Up
That’s it! I hope this article helped you use UFW on Debian, Ubuntu and Linux Mint. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂
Another excellent tutorial, thank you
Thanks Xiao, always great to read your posts !
Good starting point for UFW.
Thanks for this article. Much better than the usual “introduction to”-type post!
Thank you all for your encouragement 🙂
To add a comment to the rule as a reminder, add this to the end of the rule…
sudo ufw allow #### comment “Comment”
Thanks for the tutorial. Like all exps here clearly and gives the needed Backgroundinformations. Greetings from Germany
This is a good discussion. So why are “those that know” pushing nftables and firewalld which is so much more complex?
And how do you simply prevent DDOS and port scanning?
Thank you LinuxBabe!
Another excellent tutorial!
A+