Super Pi Part 7: Firewall

Posted on April 28, 2021

I thought of another configuration component to add to my Super Pi: a firewall. I will be using UncomplicatedFirewall, commonly known as UFW. It's an abstraction over IP-Tables, which came up in my research for my post on Wireguard a couple of times. Even though UFW is easier to use, IP-Tables has a lot more examples for my use case. I experimented with it and got a configuration working, and at the end of it all I found out that there's some extra stuff to install to make the rules persist between reboots, which I didn't want to do so I switched. Anyhow, UFW it's available in most Linux repositories:

sudo apt install ufw

Now to configure it. UFW by default will create rules for IPv4 and IPv6. I don't need IPv6 and I don't want to clutter my settings, so I'm going to make it so UFW only generates IPv4 rules by modifying /etc/default/ufw:

In my previous posts, I've been using SSH, HTTP, HTTPS, and UDP. I don't think I mentioned it in the post, but Wireguard manages its connections over UDP. UFW accomplishes its goal of ease of use pretty well in my opinion. It has a GUI which I've never used before but should make things even easier. It's in the repositories as gufw. I'm just going to use plain old command line, though. To get the ball rolling, I want to start with a clean slate, deny all incoming requests by default and allow all outgoing requests:

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

Pretty straightforward. The keywords and syntax can take some time to get used to, but it's nothing terribly surprising. The first thing I want to do is allow SSH which happens on port 22:

sudo ufw allow 22/tcp

Now I can enable UFW:

sudo ufw enable

I got notified that connections could be interrupted, but I went ahead anyway and my SSH connection remained. Success! Now I can start incrementally adding and testing things.

So right now, I can't use the internet; I have to open up the port for Pi-Hole's DNS resolution, port 53. For those who don't know, DNS packets smaller than 512B are sent over UDP, anything bigger goes over TCP:

sudo ufw allow 53/tcp
sudo ufw allow 53/udp

With this update, I can now visit websites external to my network. The internal sites for Pi-Hole and Node-RED, however, are still inaccessible. To remedy this I need to open the HTTPS port, or port 443:

sudo ufw allow 443/tcp

Now I can navigate directly to the services I have set up on my Pi, but the HTTP redirects to HTTPS are broken, which means I have to open the default HTTP port, port 80:

sudo ufw allow 80/tcp

Now, as long as I'm within my network, everything I've been built up previously works. When I put my phone on mobile data and connect to my Wireguard VPN, though, I can't visit any websites. By default, the interface configured for Wireguard is wg0, and it's plugged into my router, so the interface between my Pi and the router is eth0. Allowing traffic in on wg0 and allowing it to be shuffled between wg0 and eth0 should fix my problem:

sudo ufw allow 51820/udp
sudo ufw allow in on wg0 to any
sudo ufw route allow in on eth0 out on wg0
sudo ufw route allow in on wg0 out on eth0

Now, when I type sudo ufw status I see this:

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
53/udp                     ALLOW       Anywhere                  
53/tcp                     ALLOW       Anywhere                  
443/tcp                    ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
51820/udp                  Allow       Anywhere
Anywhere on wg0            ALLOW       Anywhere                  

Anywhere on wg0            ALLOW FWD   Anywhere on eth0          
Anywhere on eth0           ALLOW FWD   Anywhere on wg0           

This can be refined, however! I don't necessarily want any subnet to access any of the ports on my Pi. Also, allowing in on wg0 to anywhere effectively gives devices on my network via VPN more access than devices on my local network, which is something I would never want. I'm still understanding exactly how UFW works, so I'll have to update this once I figure out how to configure access exactly how I want it.