Essential Steps for securing your Linux Server

Best practices to ensure your server is secure and up to date

Will be looking into the essentials of securing a Linux server as part of my daily write-up of creating a Newsletter Service for Engineers.

I wanted to get set up the Infrastructure first before having a working building pipeline instead of rushing my way through in the end trying to get the server up and running quickly.

I'm using Digitial Ocean's droplet running Ubuntu 22.04(LTS) here but any other Linux VPS can also be used from any provider. Just make sure you have all the privileges and you may have to do some tweaks in the commands depending on your system

Connect to the instance

You will be most likely connecting as the root user for the first time. If you have specified your password when creating a VPS then use it to SSH or add SSH key pair (recommend)

ssh root@192.168.0.1

System Updates

Let's get all packages updated and avoid any vulnerabilities and pending patches.

//Ubuntu
apt update && apt upgrade

// CentOS/RHEL Stream and Fedora
dnf upgrade

//Alpine
apk update && apk upgrade

//Arch Linux
pacman -Syu

//CentOS 7
yum update

//OpenSuse
zypper update

Adding a limited user account

The default root user has unlimited privileges on the system and we should not be using it for day-to-day operations. Using a limited user account also prevents us from accidentally breaking our system.

adduser johndoe

// CentOs / Fedora
useradd example_user && passwd example_user

Some of the tasks would still require administrative privileges which we will perform with the help of sudo granting us elevated privileges temporarily

adduser john_doe sudo

// CentOS / Fedora
usermod -aG wheel example_user

Now we can exit from the instance and re-login from the limited user account

> exit
> ssh johndoe@192.168.0.1

A nice part of having sudo is that it also logs all the commands performed by users.

Hardening SSH Access

The essentials of hardening your SSH server are

  • Using ssh-key pair for authentication

  • Restricted ssh config on server

  • Restricted firewall

Using SSH Key Pairs for authentication

SSH key pairs are secure keys cryptographically generated that help authenticate and identify a unique user. They are harder to replicate and you don't have to remember the credentials unlike your passwords

Creating a key pair

We need to generate our key pair (public and private). Most Linux systems already come with the handle utility ssh-keygen to create a key pair.

We will generate a 4096-bit RSA key pair. You can also generate using a different algorithm for encrypting. While creating a key-pair you will be asked to enter a passphrase, you can also skip this step but it's recommended to use a passphrase. A passphrase ensures the private key can't be decrypted without it and hence nobody else can use your private key if in the worse it gets leaked.

If you already have a generated a SSH Key pair, this command will overwrite it

ssh-keygen -b 4096

Upload the public key

We have to add our public in ~/.ssh/authorized_keys on our server, otherwise, it won't accept any request from any unknown user.

ssh-copy-id example_user@192.0.2.1

// Using scp to copy the file 
> mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/
> scp ~/.ssh/id_rsa.pub example_user@203.0.113.10:~/.ssh/authorized_keys

Finally, you would want to restrict access to your SSH keys if you have multiple users on the server

sudo chmod -R 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

Now when you exit and log back into the server it will automatically log in or ask for your passphrase if you haven't opted to save it in the keychain

Restricted SSH config

Open the ssh daemon config in an editor on your server

sudo nano /etc/ssh/sshd_config

Disallow root logins over SSH

Since we have created a limited user account we don't need root access over SSH anymore.

Usually sudo provides us access to almost all operations. But incase if we ever need to log-in as a root most VPS provider have a recovery console on the browser which basically is like physically connecting to the instance. If you don't have a recoverly console option you can also skip this step

# Authentication:
...
PermitRootLogin no

Disable SSH password authentication

We don't need password authentication anymore and disabling password authentication ensures nobody can attempt to log in or bruteforce into our SSH

SSH key pair identiy are limited to every system. If you use multiple devices to log-in it's better to add those SSH key pairs in the authorised keys before performing this step or you can also skip this step

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

Disable additional protocol

By default, the ssh daemon listens to both IPv4 and IPv6. If you only use one which is usually IPv4 we can update the config to disable accepting connections from IPv6 address.

It only affects the SSH dameon otherwise services will still be accessible over both protocols

# Port 22
AddressFamily inet

Changing the SSH port

Additionally, you can also update the ssh daemon to listen to a different port instead of 22 by default. I tend to leave it because the server will be secure enough till the end and usually you can use port scanning utilities to identify open ports anyway

# Port 22
AddressFamily inet

Restart the SSH service

// Systemmd (Ubuntu, Debian, CentOS, Fedora)
sudo systemctl restart sshd

// SystemV
sudo service sshd restart

Configure a Firewall

I prefer to restrict the use of a Firewall provided by the VPS provider which usually has a UI to update the Firewall config on the fly from the dashboard. It allows me to restrict SSH or certain other services ; Portainer or Postgres Database from my IP address. Since I also own and host VPN to connect to the instance the IPs don't change but in-case if I ever have to add additional IP, it's easier to log in to the dashboard and update the firewall settings.

Additional things you can do

Add a custom hostname

The compute instance usually has a specific purpose or domain that represents it and it would be better when we log in and see that in the terminal instead of localhost

hostnamectl set-hostname engg-updates

So now when you log you will see the following in the terminal

~ root@engg-updates:

Add a custom timezone

Most of us would prefer the server running in our timezone which will also help in debugging something easily

timedatectl may not be available in all distributions. So look for alternatives for updating the time-zones

timedatectl list-timezones | grep 'America'

timedatectl set-timezone 'America/New_York'

Lastly, these are just the most basic steps to secure any Linux server. Additional security layers depend on the intended use and you may need to use a monitoring system, access control, fine-tune sudo, restrict exposed services and more