Harden Ubuntu Server to Secure Your Container and Other Deployments

Ubuntu Server is one of the more popular operating systems used for container deployments. Many admins and DevOps team members assume if they focus all of their security efforts starting with the container image on up, everything is good to go.
However, if you neglect the operating system on which everything is installed and deployed, you are neglecting one of the most important (and easiest) steps to take.
In that vein, I want to walk you through a few critical tasks you can undertake with Ubuntu Server to make sure the foundation of your deployments is as secure as possible. You’ll be surprised at how easy this is.
Are you ready?
Let’s do this.
Schedule Regular Upgrades
I cannot tell you how many servers I’ve happened upon where the admin (or team of admins) failed to run regular upgrades. This should be an absolute no-brainer but I do understand the reasoning behind the failure to do this. First off, people get busy, so upgrades tend to fall by the wayside in lieu of putting out fires.
Second, when the kernel is upgraded, the server must be rebooted. Given how downtime is frowned upon, it’s understanding why some admins hesitate to run upgrades.
Don’t.
Upgrades are the only way to ensure your server is patched against the latest threats and if you don’t upgrade those servers are vulnerable.
Because of this, find a time when a reboot won’t interrupt service and apply the upgrades then.
Of course, you could also add Ubuntu Livepatch to the system, so patches are automatically downloaded, verified, and applied to the running kernel, without having to reboot.
Do Not Enable Root
Ubuntu ships with the root account disabled. In its place is sudo and I cannot recommend enough that you do not enable and use the root account. By enabling the root account, you open your system(s) up to security risks. You can even go so far as to disable root altogether, with the command:
1 |
sudo passwd -l root |
What the above command does is expire the root password, so until you were to reset the root password, the root user is effectively inaccessible.
Disable SSH Login for the Root User
The next step you should take is to disable the root user SSH login. By default, Ubuntu Server enables root SSH login, which should be considered a security issue in the waiting. Fortunately, disabling root SSH access is very simple.
Log in to your Ubuntu Server and open the SSH daemon config file with:
1 |
sudo nano /etc/ssh/sshd_config |
In that file, look for the line:
1 |
#PermitRootLogin prohibit-password |
Change that to:
1 |
PermitRootLogin no |
Save and close the file. Restart SSH with:
1 |
sudo systemctl restart sshd |
The root user will no longer be allowed access via SSH.
Use SSH Key Authentication
Speaking of Secure Shell, you should always use key authentication, as it is much more secure than traditional password-based logins. This process takes a few steps and starts with you creating an SSH key pair on the system(s) that will be used to access the server. You’ll want to do this on any machine that will use SSH to remote into your server.
The first thing to do is generate an SSH key with the command:
1 |
ssh-keygen |
Follow the prompts and SSH will generate a key pair and save it in ~/.ssh.
Next, copy that key to the server with the command:
1 |
ssh-copy-id SERVER |
Where SERVER is the IP address of the remote server.
Once the key has been copied, make sure to attempt an SSH login from the local machine to verify it works.
Repeat the above steps on any machine that needs SSH access to the server because we’re not going to disable SSH password authentication. One thing to keep in mind is that, once you disable password authentication, you will only be able to access the server from a machine that has copied its SSH key to the server. Because of this, make sure you have local access to the server in question (just in case).
To disable SSH password authentication, open the SSH demon configuration file again and look for the following lines:
1 |
#PubkeyAuthentication yes |
and
1 |
#PasswordAuthentication yes |
Remove the # characters from both lines and change yes to no on the second. Once you’ve done that save and close the file. Restart SSH with:
1 |
sudo systemctl restart sshd |
Your server will now only accept SSH connections using key authentication.
Install Fail2ban
Speaking of SSH logins, one of the first things you should do with Ubuntu Server is install fail2ban. This system keeps tabs on specific log files to detect unwanted SSH logins. When fail2ban detects an attempt to compromise your system via SSH, it automatically bans the offending IP address.
The fail2ban application can be installed from the standard repositories, using the command:
1 |
sudo apt-get install fail2ban -y |
Once installed, you’ll need to configure an SSH jail. Create the jail file with:
1 |
sudo nano /etc/fail2ban/jail.local |
In the file, paste the following contents:
1 2 3 4 5 6 |
[sshd] enabled = true port = 22 filter = sshd logpath = /var/log/auth.log maxretry = 3 |
Restart fail2ban with:
1 |
sudo systemctl restart fail2ban |
Now, anytime someone attempts to log into your Ubuntu server and fails 3 times, their IP address will be permanently blocked.
Secure Shared Memory
By default, shared memory is mounted as read/write. That means the /run/shm space can be exploited and any application or service that has access to /run/shm. To avoid this, you simply mount /run/shm with certain privileges.
The one caveat to this is you might run into certain applications or services that require read/write access to shared memory. Fortunately, most applications that require such access are GUIs, but that’s not an absolute. So if you find certain applications start behaving improperly, you’ll have to return read/write mounting to shared memory.
To do this, open /etc/fstab for editing with the command:
1 |
sudo nano /etc/fstab |
At the bottom of the file, add the following line:
1 |
tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0 |
Save and close the file. Reboot the system with the command:
1 |
sudo reboot |
Once the system reboots, shared memory is no longer mounted with read/write access.
Enable the Firewall
Uncomplicated Firewall (UFW) is disabled by default. This is not a good idea for production machines. Fortunately, UFW is incredibly easy to use and I highly recommend you enable it immediately.
To enable UFW, issue the command:
1 |
sudo ufw enable |
The next command you’ll want to run is to allow SSH connections. That command is:
1 |
sudo ufw allow ssh |
You can then allow other services, as needed, such as HTTP an HTTPS like so:
1 2 |
sudo ufw allow http sudo ufw allow https |
For more information on UFW, make sure to read the man page with the command:
man ufw
Final Thoughts
These are the first (and often most important) steps to hardening Ubuntu Server. You can also take this a bit further with password policies and two-factor authentication but the above steps will go a long way to giving you a solid base to build on.