Securing an Internet accessible server – Part 2

In part 1 we made it significantly harder to gain access to our server once it is opened up to the Internet – but we’re not quite ready for that yet. In this post we’re exploring a firewall in Ubuntu, ufw, which stands for “uncomplicated firewall”, and we’ll set up some additional hardening using Fail2Ban to protect ourselves from some common repeated attacks.


In a professional setting, you’re likely to have several layers of protection in front of your Internet facing servers. A web server is likely not only to have a corporate firewall protecting it, but also load balancing and/or caching proxies. A side effect of such proxies is that even if there would be something wrong with the firewall rules, only traffic you expect to reach a server is likely to arrive at it; in other words such services function as additional filters in front of the server.

In a home setting, it’s likely that only a rather simple firewall appliance will stand between a web-facing server and the bad guys on the Internet. This poses a couple of issues:
1) Do you trust your own rule-making?
2) Do you trust the firewall manufacturer?

In short: By configuring and enabling the local firewall on a web-facing server, we’re protecting ourselves from configuration mistakes in our main firewall.

Let’s get going.

The first thing we want to do is to make sure ufw is installed:

$ sudo apt update && sudo apt install ufw

Next we must ensure we’ll be able to reconnect after ufw has been started. The most basic set of rules we can set which fulfills sane criteria is this:

$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
$ sudo ufw allow ssh

What we do here is that we stop all incoming traffic that doesn’t fit an explicit allow rule, we allow outgoing traffic pretty much no matter what (be aware that this may not be a good thing in all circumstances, so this may need to be adjusted accordingly depending on our level of paranoia), and finally we allow secure shell traffic.

In all probability, these rules are already set, but it’s nice to see just how uncomplicated ufw really is in its most basic function. To have a look at the actual enabled rules, edit /etc/ufw/user.rules, or /etc/ufw/user6.rules if you’re running an IPv6 network. In all likelihood there will be a couple of rules opening up port 22 already. Only one set of such rules is required.

All done?

$ sudo ufw enable

This starts the firewall and tells the operating system to also restart it after a computer reboot.


The next step in securing our server once we have a working firewall in place is to add a system to tell the firewall to block originating addresses that make too many unsuccessful login attempts. A good tool to achieve this is called fail2ban. Let’s get it.

$ sudo apt install fail2ban

Once the necessary packages have been installed, we’ll want to create the file  /etc/fail2ban/jail.d/customizations.local with the following content:

bantime = 3600

enabled = true

As we add services to the server, we’ll need to add them to this file as “enabled”. The list of pre-built configurations for various services exists in /etc/fail2ban/jail.conf. In case you don’t agree with some of the defaults in jail.conf, feel free to override them in your customizations.local file.


By now our server is starting to feel pretty secured: It requires public key authentication for remote access, it’s blocking network requests it doesn’t recognize, and it puts up temporary bans for IP addresses from which suspected malicious activity is detected.

In the next part we’ll add some web services.