Learn and Implement Linux Server Security Best Practices

Learn How to Secure and Harden Your Linux Server

Post cover image displaying the Tux logo
Stay Safe Out there

Having an exposed server in the wild is scary where people try to get into our servers and start abusing them.

In this post, we will cover the must-do procedures to harden and secure our Linux servers.

Table of contents

Requirements

  • Basic understanding of Linux and the command line

Packages Updates

We all have a number of packages or apps installed and running in our systems and it's very important to update them regularly not just for the better performance and the features an update might introduce (don't be mistaken updates with upgrades, they might not be compatible with the ecosystem you have) but also for the security patches the developer's ship to us to fix vulnerabilities.

That's why regular updates are good but what if I told you they can be automated?

Great right, Automatic updates are not recommended for various reasons and what's recommended is to read the changelog for each update we would install to make sure it doesn't break our servers, however, security updates/patches are recommended to be installed, below we will see how to make them automatic.

We will be using the unattended-upgrades package, we can install it with the following command:

sudo apt install unattended-upgrades

After installing it, run the following:

sudo dpkg-reconfigure --priority=low unattended-upgrades

This will bring a dialog, Choose YES and it will create the following config file:

/etc/apt/apt.conf.d/20auto-upgrades

Having this content

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

We can further configure this tool to update and upgrade other stable packages or just security updates, just edit the following file:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

You will find something similar to this

# head /etc/apt/apt.conf.d/50unattended-upgrades

// Note that in Ubuntu security updates may pull in new dependencies
// from non-security sources (e.g. chromium). By allowing the release
// pocket these get automatically pulled in.
Unattended-Upgrade::Allowed-Origins {
	"${distro_id}:${distro_codename}";
	"${distro_id}:${distro_codename}-security";
	// Extended Security Maintenance; doesn't necessarily exist for
	// every release and this system may not have it installed, but if
	// available, the policy for updates is such that unattended-upgrades
	// should also install from here by default.
	"${distro_id}ESMApps:${distro_codename}-apps-security";
	"${distro_id}ESM:${distro_codename}-infra-security";
//	"${distro_id}:${distro_codename}-updates";
//	"${distro_id}:${distro_codename}-proposed";
//	"${distro_id}:${distro_codename}-backports";
};

It's well documented so you won't find trouble configuring it.

And like this, we are installing security updates automatically providing some peace of mind.

Users

The first thing we hear in any blog or forum is to don't use the root user or its privileges as much as possible, so it's recommended to use a non-root user.

Create a user with the following command:

sudo adduser MY_NAME

Add the user to the sudo group  to get its privileges on-demand:

sudo usermod -aG sudo MY_NAME

That's it, log out of this session and connect with this user.

Accessing The Server

There are various ways to access a Linux server, using VNC and/or SSH are common.

VNC by nature is not secure since its traffic is not encrypted but on the other hand, SSH is, and it's hard to break throw.

That's why I recommend using SSH as your only way to the server and SSH itself can be even more secure following the next steps:

Use keys to authenticate and not password, Let's create a private key (in your client/machine terminal not in the server):

ssh-keygen -t rsa -b 4096 -C "MY_NAME's server private key"

This command will generate 2 files, id_rsa and id_rsa.pub (the private and public key respectively).

Add your public key to the server (in most cases the path to the keys are in ~/.ssh directory):

ssh-copy-id -i /path/to/id_rsa.pub MY_NAME@IP_OF_SERVER

Now you can use it to authenticate and access the server:

ssh -i /path/to/id_rsa MY_NAME@IP_OF_SERVER

You will be prompted to enter your key password, when done you will get into the server safely.

More on SSH

In case you don't or won't use IPv6 for SSH you can disable it to reduce the number of ways SSH can accept communications.

Open the following file:

sudo nano /etc/ssh/sshd_config

And change the AddressFamily property to inet:

From 'AddressFamily any' to 'AddressFamily inet' # Which means IPv4 only

Root access, you can disallow SSH root access:

From 'PermitRootLogin yes' to 'PermitRootLogin no'

And since we are using keys to authenticate, disallow password authentication:

From 'PasswordAuthentication yes' to 'PasswordAuthentication no'

Finally, Restart the SSH daemon for changes to take effect:

sudo systemctl restart sshd

The Firewall

Open ports are just a nightmare it's like having a house with no locked doors, you can imagine.

A firewall is basically a set of rules to control incoming and outgoing requests in your server, now when it comes to configuring the firewall in Linux using iptables; its a pain, that's why there is a package called ufw (which stands for 'Uncomplicated Firewall'), Let's install it and configure it.

Install ufw:

sudo apt install ufw

Since we are using SSH it listens on port 22 so we will have to allow communications through that port:

# Before doing anything, Reset any rule (Make sure it wasn't used by anyone before)
sudo ufw reset

# Enable UFW
sudo ufw enable

# Allow OpenSSH server (SSH)
sudo ufw allow 22

Now before we wrap the firewall step, Again if you are not going to use IPv6, block it using ufw too, Let's do it (it's optional).

Open the following file:

sudo nano /etc/default/ufw

Change the IPv6 property:

From 'IPV6=yes' to 'IPV6=no'

Now we can disable and enable ufw again for changes to take effect:

sudo ufw disable && sudo ufw enable

Verify the changes:

sudo ufw status verbose

And remember if you are going to host a website or an API, you will need to open port 80 (HTTP) and/or 443 (HTTPS).

Conclusion

After all the steps we have taken, we can call it a day hardening our Linux server.


As always, I hope you learned something.

Found this useful? feel free to share it with your friends.

Join the newsletter from to notify you of new posts and updates.

Like the post? consider buying us a coffee ❤️.