The Linux kernel includes a packet filtering framework called netfilter that can be configured with the iptables utility. While iptables is very powerful/flexible, it does have a significant learning curve. This is why Ubuntu uses Uncomplicated Firewall (ufw) as the default firewall configuration tool. It’s a frontend to iptables, and as the name implies, it’s simpler and better-suited for the average user. By default, ufw is disabled on Ubuntu. We’ll explain why this is the norm and how you can enable and get started with UFW in this article. Note: If you’re configuring a remote server through SSH, allow SSH traffic through the firewall before enabling UFW to prevent yourself from being locked out. sudo ufw allow ssh Enabling UFW on Ubuntu You can start by checking the current status of UFW. sudo ufw status If you’ve already enabled UFW, that’ll show the firewall rules in place. But on a fresh install, you’ll see that UFW is inactive. The idea behind this is that there are no services running on a default Ubuntu installation that require open ports, so the firewall doesn’t need to be enabled by default. However, this doesn’t make much sense practically. There are countless commonly used services that require open ports (Samba, SSH, VNC, CUPS, etc). Most people install/use at least one such service soon after the installation. If this is done without a firewall, such services could be exploited through compromised devices in your local network. On a public network, you may directly expose yourself to malicious actors. While netfilter is integrated into the kernel, the firewall isn’t activated by default. To protect your system from such threats, you must manually enable the host firewall with a tool like iptables, nftables, or ufw. sudo ufw enable Opening Ports with UFW The default behavior of UFW is to allow all outgoing connections and block all incoming connections. This allows you to handpick all inbound connections, which is simple but effective. Allowing Connections through UFW Let’s say you want to establish an SSH connection to this machine. You’ll need to add a rule to open the SSH port (default – 22) which will allow SSH traffic to pass through. You can specify the exact port like so sudo ufw allow 22 This’ll allow TCP and UDP connections on port 22. Allowing TCP/UDP Traffic Only Let’s say the SSH server is configured to listen on port 1513 and you only want to allow TCP traffic through. In that case, you can use sudo ufw allow 1513/tcp Allowing Connections with Service Names The /etc/services file maps service names to port numbers. You can use the service names defined there when configuring rules. For instance, you can use allow https instead of allow 443 to open port 443 (the default https port for encrypted web traffic). sudo ufw allow https Using UFW Application Profiles UFW also has its own similar mapping system called Application Profiles. You can list the available application profiles with the list command. sudo ufw app list Let’s say you’ve set up an NGINX web server. The above command will list multiple NGINX profiles. You can check which profile configures which ports with the info command. For instance, let’s check the NGINX Full profile. sudo ufw app info "NGINX Full" When working with a profile without a space in the name (e.g., OpenSSH), you can omit the double quotes. Anyway, you’ll see that this profile allows HTTP (port 80) and HTTPS (port 443) traffic through UFW. To enable this profile, you can use sudo ufw allow "NGINX Full" Advanced Syntax To open a range of ports, you can specify the range like so sudo ufw allow 4000:4012/tcp You can allow all connections from a specific IP address like so sudo ufw allow from 192.168.122.15 Or, you can only allow connections from this address to a specific port. sudo ufw allow from 192.168.122.15 to any port 4000 You can allow connections from all addresses in a subnet by specifying the netmask. For instance, the following command allows all IP addresses from 192.168.122.1 to 192.168.122.254. sudo ufw allow from 192.168.122.0/24 You can also do the same but allow connections to a specific port only. sudo ufw allow from 192.168.122.0/24 to any port 4005 Finally, you can also create firewall rules for specific network interfaces. You’ll want to note the logical names of your network interfaces first. nmcli c For instance, to allow incoming connections on port 4007 through my Ethernet interface (enp1s0), I would use sudo ufw allow in on enp1s0 to any port 4007 Denying Connections There are two main approaches to denying connections. You can set UFW to deny all outgoing connections by default. sudo ufw default deny outgoing However, this method is a bit impractical as individually opening ports for outgoing connections can be a real hassle. The more common approach is to close ports as needed. For instance, a basic rule to block SSH connections looks like this sudo ufw deny 22 You can deny all connections from an IP Address like so sudo ufw deny from 220.127.116.11 Or, you can deny connections from that address on specific ports only. sudo ufw deny from 18.104.22.168 to any port 80,443 proto tcp Checking the Firewall Rules Let’s check all the rules we’ve configured so far. The standard syntax for this is sudo ufw status You can get some more details with the verbose command. sudo ufw status verbose You can also list the rules in numbered format. This is useful for inserting and deleting rules. sudo ufw status numbered As an aside, if you directly edit the config files in /etc/ufw/, you must reload UFW to apply the changes. sudo ufw reload Deleting UFW Rules As mentioned above, you can list the rules in numbered format and use the rule number to delete rules. For instance, to delete rule number 4, you’d use sudo ufw delete 4 Alternatively, you can also specify the rule directly to delete it. sudo ufw delete allow 22 Disabling or Resetting UFW If you ever need to disable UFW, you can use sudo ufw disable Similarly, if you want to reset UFW to the default state, you can use sudo ufw reset Keep in mind that this will disable UFW, so you’ll need to manually re-enable it after the reset.