Configure and Secure a Linux Server

Setting up a new Linux server requires careful attention to configuration and security from the very beginning. This guide walks you through the essential steps, providing concrete code examples and expected outputs to harden your server against common threats.

1. System Update

The first and most fundamental step is ensuring your system has the latest security patches and updates .

Example (Ubuntu/Debian):

sudo apt update && sudo apt upgrade -y

Output:

Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
...
Fetched 15.2 MB in 3s (5,080 kB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  libcurl4 curl
2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 450 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 libcurl4 amd64 7.81.0-1ubuntu1.10 [234 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 curl amd64 7.81.0-1ubuntu1.10 [216 kB]
Fetched 450 kB in 0s (1,125 kB/s)
(Reading database ... 65432 files and directories currently installed.)
Preparing to unpack .../libcurl4_7.81.0-1ubuntu1.10_amd64.deb ...
Unpacking libcurl4:amd64 (7.81.0-1ubuntu1.10) over (7.81.0-1ubuntu1.9) ...
Preparing to unpack .../curl_7.81.0-1ubuntu1.10_amd64.deb ...
Unpacking curl (7.81.0-1ubuntu1.10) over (7.81.0-1ubuntu1.9) ...
Setting up libcurl4:amd64 (7.81.0-1ubuntu1.10) ...
Setting up curl (7.81.0-1ubuntu1.10) ...
Processing triggers for man-db (2.10.2-1) ...

2. Create a Non-Root User with Sudo Privileges

Logging in as the root user directly poses significant security risks. Always create a dedicated user account with sudo capabilities .

Example:

# Create a new user (replace 'myuser' with your desired username)
sudo adduser myuser

# Add the user to the sudo group
sudo usermod -aG sudo myuser

Output for adduser:

Adding user `myuser' ...
Adding new group `myuser' (1001) ...
Adding new user `myuser' (1001) with group `myuser' ...
Creating home directory `/home/myuser' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for myuser
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] Y

3. Secure SSH Access

SSH is often the primary target for attackers. Hardening SSH is critical .

a. Generate SSH Key Pair (on your local machine)

# On your local computer
ssh-keygen -t ed25519 -C "your_email@example.com"

Output:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX your_email@example.com
The key's randomart image is:
+--[ED25519 256]--+
|     ...         |
|    . . .        |
|   .   . .       |
|    . . o        |
|   . + .S.       |
|  . = o.o .      |
|   + * =.o       |
|  . o.B.+E       |
|   .o=+*o.       |
+----[SHA256]-----+

b. Copy Public Key to Server

# From your local machine, copy the public key to the server
ssh-copy-id myuser@your_server_ip

c. Configure SSH Server

Edit the SSH daemon configuration file.

sudo nano /etc/ssh/sshd_config

Modify or add the following lines:

Port 2222                    # Change default SSH port 
PermitRootLogin no           # Disable root login 
PasswordAuthentication no    # Disable password login, use keys 
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
MaxSessions 2
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers myuser            # Restrict SSH access to specific users

Save the file and exit the editor.

d. Restart SSH Service

sudo systemctl restart sshd

Output (checking status):

sudo systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2024-05-18 10:30:00 UTC; 1min ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1234 (sshd)
      Tasks: 1 (limit: 9487)
     Memory: 1.2M
     CGroup: /system.slice/ssh.service
             └─1234 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

e. Test SSH Connection (from your local machine)

# Connect using the new user and port
ssh -p 2222 myuser@your_server_ip

4. Configure Firewall (UFW)

Implementing a firewall is a key step in securing your server . UFW (Uncomplicated Firewall) provides a user-friendly interface for managing iptables .

a. Install UFW (if not already installed)

sudo apt install ufw -y

b. Set Default Policies

# Deny all incoming connections by default
sudo ufw default deny incoming

# Allow all outgoing connections
sudo ufw default allow outgoing

Output:

Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
Default outgoing policy changed to 'allow'

c. Allow Essential Services

# Allow SSH on the new port
sudo ufw allow 2222/tcp

# Example: Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Example: Allow specific IP to access a port (e.g., PostgreSQL from a specific IP)
# sudo ufw allow from 192.168.1.100 to any port 5432

Output for allowing SSH:

Rule added
Rule added (v6)

d. Enable UFW

sudo ufw enable

Output:

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

e. Check Firewall Status

sudo ufw status verbose

Output:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
Rules:
ufw deny in on any
ufw allow out on any
ufw allow 2222/tcp
ufw allow 80/tcp
ufw allow 443/tcp

5. Additional Hardening Steps

a. Remove Unnecessary Software

Reduce the attack surface by removing packages you don’t need .

# List installed packages
dpkg -l

# Remove a package (example)
sudo apt remove --purge package_name
sudo apt autoremove

Configure automatic security updates.

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

c. Monitor System Logs

Regularly check logs for suspicious activity.

# View recent authentication logs
sudo tail -f /var/log/auth.log

# View recent system logs
sudo journalctl -f

Linux server security configuration SSH firewall UFW hardening sysadmin sudo update authentication