A well defined firewall configuration that only permits necessary traffic is essential to securing any server. In this guide we will go over the basic thought process that goes into defining a firewall configuration and apply this logic to secure our Cardano nodes.
What you will need?
For our purposes, we will be using the UFW package.
sudo apt update sudo apt install ufw
Once installed, you have everything needed to get started.
What is UFW?
UFW is a package that abstracts away a lot of the complexity that normally goes into configuring a firewall using
iptables by providing an interface through which simple language can be used to describe a desired set of firewall rules to be applied. It’s all in the name really as UFW is an acronym for Uncomplicated Firewall.
Understanding Your Requirements
The first thing that needs to happen before you start configuring your firewall is to form a solid understanding of how you need your server to be able to communicate. Once this is established, you can work your way backwards from these requirements to lock everything down except the very specific channels you need to allow.
As the scope of this guide focuses on setting up Cardano nodes, we will work with the assumption that your server topology will need to accommodate relay nodes, which are advertised to the network when setting up and registering your pool, and a core node, which handles block production and only needs to communicate directly with the relays. Beyond this, we will also assume that we will need to be able to connect remotely to our various servers via SSH, so we will need to keep that port open as well. There are likely other ports you will want to open up when setting up other features, such as active monitoring through Prometheus/Graphana, but we’ll keep things simple for now as you can always apply additional rules later as they become necessary. Configuring the ports on which nodes need to communicate with the Cardano network and access open via SSH is a good place to start.
Now that we understand what communication we need to allow, the last thing we need before we can proceed is an understanding of the IP & port combinations that we will be using in our topology. For the purposes of this guide we will use up the topology below.
We will also assume that SSH has been configured on port 2001 (the default is 22, but this can be changed, as outlined in our earlier guide).
Let’s begin by setting up UFW’s default policies.
sudo ufw default deny incoming sudo ufw default allow outgoing
This is a good place to start as now, by default, all traffic leaving the server is allowed, however, and perhaps more importantly, nothing is able to get in. It’s also worth noting that our firewall policy won’t take effect until we turn on UFW, so nothing has gone into effect yet.
Next, let’s allow communication on the port we’ve configured for SSH. We can also specify the TCP protocol in this case which SSH uses to communicate.
sudo ufw allow 2001/tcp
That’s all that’s needed. You will now be able to access your server via the configured SSH port. These rules can be applied to the relays and the core. Next we’ll look at our relay and core configurations in isolation as they differ slightly.
For this next step, we’ll assume we are working with “Relay 1” from the earlier diagram. Given that we will need other nodes on the network (our own, as well those outside our control), it will suffice to simply open up the port on which we are running our node. So let’s open up port 3001 for the TCP protocol.
sudo ufw allow 3001/tcp
For “Relay 2” we just do the same thing, but with port 3002, as per our earlier topology diagram.
Since our core is listening for network traffic on port 3000, we will open it up. However, unlike our relay nodes, we know specifically which IPs will be communicating with our core. As a result, we can further lock down our permissions to only allow our specific relay nodes to communicate with our core.
sudo ufw allow from 10.138.0.4 proto tcp to any port 3000 sudo ufw allow from 10.148.0.4 proto tcp to any port 3000
The above specifies the IP (
from xx.xx.xx.xx), protocol (
proto xxx) and the port (
to any port xxxx) since we are able to be very specific with our relay connections.
Turning It All On
Now that everything is configured, it’s just a matter of turning it all on.
sudo ufw enable
And that’s it. You now have a firewall configured on your server that only allows the incoming traffic you need to be handling. Everything else stays out.
If you want to review your firewall settings, just do the following after it’s been enabled.
sudo ufw status
Doing so will list out the current firewall configuration as long as UFW is enabled. If UFW is disabled, the command will not display the configured rules and will only report that UFW is not active.
Editing Firewall Rules
Removing rules can easily be done in one of two ways, by either specifying which numbered rule in the list you want to delete, or by writing up the rule you want to remove with a delete prefix ahead of it. For example, let’s consider the following rules table output from when using the
sudo ufw status command while UFW is enabled.
2001/tcp ALLOW Anywhere 3000/tcp ALLOW 10.138.0.4 3000/tcp ALLOW 10.148.0.4 2001/tcp (v6) ALLOW Anywhere (v6)
Let’s say we no longer wanted to keep port 2001 open, then all we need to do to remove the rule is the following.
sudo ufw delete allow 2001/tcp
Doing so would remove both rules which currently open up port 2001.
We can also remove rules by their numeric position in the list, which would be easier than writing up a delete command matching a longer rule we would like to see removed. Assuming that the initial list of rules listed above is unchanged, if we wanted to remove port 3000 access for 10.148.0.4, the following command would do the trick.
sudo ufw delete 3
Inputing a numeric deletion command will generate a prompt detailing the rule that is about to be deleted to confirm your intentions as an added safety.
The above only looks at the basics of using UFW to configure a firewall on your server. It’s also likely that the network on which your machines reside has a firewall managing traffic moving in and out the local network as well. While configuration of that particular firewall is outside the scope of this guide, it’s good to apply the same thought process to those firewall settings as well, by evaluating what network traffic is leaving from and coming into your local network. It’s simply a matter of identifying how permissive you need to be with your firewall settings so that you can do exactly what you need to be doing, and nothing more.
You now have a properly configured firewall on your server that will block any incoming traffic except for Cardano network traffic on the ports your nodes are configured to listen to, as well as the port you’ve configured for SSH. You also have the tools to you need to make additional changes to your UFW configuration as your needs change and grow. Remember, it’s always best to keep everything you don’t need locked down, and to make adjustments later as you need them.