Kannisto.org

Petri Kannisto's homepage – about software systems and research

<< Front Page of Blog

Virtualized Ubuntu Server for Internet services

23 Mar 2021 (updated 14 Apr 2021) – Petri Kannisto

DISCLAIMER. This guide comes "as is". This means that the author does not have any liability. You must consider carefully before exposing any server to the public Internet, because this is always risky. It is up to you to estimate if you know what you are doing.

This guide provides you step-by-step instructions to set up a virtualized Ubuntu Linux that:

I don't consider myself a Linux guru. However, I wanted to make a post about setting up RabbitMQ. For this, I wanted to include the instructions to set up the underlying operating system, which is Ubuntu in this case. We used a VMWare-hosted virtual machine, but this does not change anything.

I originally wrote this guide in 2017-2018 for Ubuntu Server 16.04.6 LTS. However, the content is likely still valid, although some sections have been updated without trying if they truly work.

Prerequisites

This guide assumes that you know the following. If you don't, the Internet is full of guides anyway.

Known shortcomings

This guide could improve at least the following.

Additional tools

This guide assumes that you set up an SSH server and communicate with the machine via SSH. As SSH clients, I use the following tools:

Ubuntu setup

Next, you set up the operating system.

sudo apt-get update
sudo apt-get upgrade

The operating system may ask you to reboot at this point.

Firewall

You need a firewall. Because our original system ran behind an external firewall, we did not configure one in Ubuntu. However, there should always be a firewall and even if you had an external one, it's no harm to run another one locally.

Ubuntu ships with a firewall called Iptables, which is somewhat complicated to new users. Fortunately, there's another built-in firewall called UFW (Uncomplicated Firewall), which is more user-friendly. Actually, UFW has been built on top of Iptables.

Enable the firewall as follows. By default, this blocks all incoming traffic but allows any outgoing traffic:

sudo ufw enable

To allow SSH traffic in from any IP address:

sudo ufw allow 22

For more security, consider replacing the previous rule with one that allows the traffic from only certain IP addresses. For example, to allow anything starting with "192.168.144":

sudo ufw allow proto tcp from 192.168.144.1/24 to any port 22

After enabling the firewall, you can test the rule from an IP outside of the specified range.

SSH server

I recommend you to set up an SSH server soon, because the basic command line UI sucks at least via VMWare (not sure if this depends on VMWare, some default console in Ubuntu, or both).

To install:

sudo apt-get install openssh-server

The server should be enabled by default and listening the default SSH port 22. Now, you can connect with a client, such as Putty.

SSH password cracking prevention

Now that the machine has an SSH port open to the public, you should prevent password cracking. The first thing to do is to pick a non-common username during the installation of Ubuntu (avoid "admin" or "user"). Besides, do not use a short or easy-to-guess password.

Furthermore, there is a tool called Fail2ban, which is built upon the Iptables firewall. Fail2ban recognizes if a user fails to log in multiple times in a short period and sets a temporary IP ban. This mechanism is effective at blocking brute force attacks as long as the source IP remains constant.

Because UFW and Fail2ban both build upon Iptables, they could potentially conflict. However, this is supposedly no issue (see https://askubuntu.com/questions/54771/potential-ufw-and-fail2ban-conflicts )

To install Fail2ban:

sudo apt-get install fail2ban

Next, configure a "jail" to enable blocking. Create a new config file with the following command:

sudo nano /etc/fail2ban/jail.d/fail2ban-ssh.conf

Add the following content. Instead of typing, you may want to use a file transfer application.

[sshd]
port    = ssh
logpath = %(sshd_log)s
enabled = true

[sshd-ddos]
port    = ssh
logpath = %(sshd_log)s
enabled = true

I cannot remember (too busy to check) if you must assign a value of how many login attempts Fail2ban allows and for how long it blocks after a failure. Five attempts and 10 minutes sounds like a reasonable balance between security and inconvenience if you fail to type correctly. Refer to Fail2ban documentation (discoverable with Google) for more information.

AFAIK, Fail2ban requires no reboot after activation. You can test if it blocks appropriately by attempting to log in a few times with invalid credentials. Then, if you successfully log in from another IP, you should be able to see a rule generated by Fail2ban in Iptables. Refer to some Iptables example to find out how to see a list of rules.

SSH authentication with key

You may want to authenticate with SSH keys instead of a password for more security and convenience, although this will set limitations to which clients can sign in. This guide omits key-based authentication, but you may study how it works here: https://www.ssh.com/academy/ssh/public-key-authentication

If you need more help, Google will provide you plenty of information.

Automatic updates

By default, Ubuntu does not update automatically. You must install a tool for this. We use "unattended-upgrades".

To install:

sudo apt-get install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

For more information, see https://www.howtogeek.com/204796/how-to-enable-automatic-security-updates-on-ubuntu-server/

Done!

That's it. Now you have a machine accessible via SSH but with some level of security. Security experts could suggest you more of measures. For instance, Fail2ban does not block brute force attacks if they come from multiple IPs. You could authenticate with an SSH key instead of a password. Besides, you'll need backups in case the system gets corrupted.

Please note that it's potentially a bad idea to just forget your server and assume it gets along fine with automatic updates. You should keep control over the machine and ensure all important updates get installed.