Linux VPS-server, setup, protection and optimization

This guide walks through the secure setup of a Debian-based VPS server step by step. Every command is explained so you know what you're doing and why.

Before you begin

A new VPS server is visible on the network from the moment it boots. Automated bots continuously scan the entire internet and will find your server within minutes. That's why security must be configured before you install anything else.

You will need: 
  • The IP address of your VPS server
  • The root password (provided by your hosting provider)
  • A terminal on your local machine

1. Log in and update the system

Log in to the server for the first time as the root user. This is the only time you should use the root account directly.

ssh root@SERVER_IP

Update the system immediately. Many server breaches exploit known vulnerabilities that could have been prevented with a simple update.

apt update # fetch the list of available updates
apt upgrade -y # install all updates

2. Create a new user

The root user has unlimited privileges. If an attacker gains access as root, the entire server is immediately compromised. Create a regular user for daily use. The command will ask for a password and some optional details. Press Enter to skip unnecessary fields.

adduser username # replace 'username' with your desired name​

Grant the user sudo privileges so they can perform administrative tasks when needed.

usermod -aG sudo username    # add the new user to the sudo group

Switch to the new user and verify that sudo works. The command should output root.

su - username
sudo whoami # should output: root

3. SSH key pair

Password authentication is vulnerable to brute-force attacks, where bots try thousands of passwords per second. An SSH key pair is a cryptographically secure alternative without the correct key, access is not possible.
Do this on your local machine, not on the server. The command creates two files: id_ed25519 (private key, never share this) and id_ed25519.pub (public key).

ssh-keygen -t ed25519 -C "your@email.com" # -t = algorithm, -C = comment

Copy the public key to the server. After this, the server will recognize you based on the key.

ssh-copy-id username@SERVER_IP # adds the key to the server’s authorized_keys file

4. Harden SSH settings

Now that key-based login works, tighten SSH security. Open the SSH configuration file.

sudo nano /etc/ssh/sshd_config

Find these lines in the file and modify them as follows. Changing the port from the default 22 significantly reduces automated scanning attacks, as most bots only target port 22.

Port 2222 # change SSH from default port 22
PermitRootLogin no # disable root login
PasswordAuthentication no # disable password authentication
PubkeyAuthentication yes # ensure key-based authentication is enabled

Save the file (Ctrl+X, then Y, then Enter) and restart SSH.

sudo systemctl restart sshd
Important! 

Do not close your current connection before testing the new port. Open a new terminal window and try logging in.

ssh -p 2222 username@SERVER_IP # -p = port

5. Firewall

The firewall determines which network traffic is allowed to the server. First block everything, then allow only necessary ports.

sudo ufw default deny incoming # block all incoming traffic by default
sudo ufw default allow outgoing # allow all outgoing traffic by default

Open required ports. Make sure to use the same SSH port you selected in step 4.

sudo ufw allow 2222/tcp # SSH (change if using a different port)
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS

Enable the firewall and check its status.

sudo ufw enable
sudo ufw status verbose # shows all active rules

6. Fail2ban

Fail2ban monitors logs and automatically blocks IP addresses that attempt to log in too many times unsuccessfully. This is an important additional layer on top of the firewall.

sudo apt install fail2ban -y

Create a local configuration file. Use jail.local instead of editing jail.conf directly, as updates may overwrite it.

sudo nano /etc/fail2ban/jail.local

Add the following content. Remember to change the port to match your SSH port.

[DEFAULT]
bantime = 1h # banned IP is blocked for 1 hour
findtime = 10m # 10-minute window for counting attempts
maxretry = 5 # 5 failed attempts trigger a ban

[sshd]
enabled = true
port = 2222 # match your SSH port

Start Fail2ban and enable it to run automatically on boot.

sudo systemctl enable fail2ban # start on boot
sudo systemctl start fail2ban # start immediately
sudo fail2ban-client status sshd # verify SSH protection is active

7. Automatic security updates

Manual updates are easy to forget. unattended-upgrades installs security updates automatically in the background.

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades # choose Yes in the prompt

Verify that the configuration was saved correctly. Both lines should show "1".

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

8. Swap memory

VPS servers often have limited RAM. Swap is disk space used as backup memory when RAM runs out. Without it, the server may crash during traffic spikes. Create a 2GB swap file. Adjust the size as needed 1G is enough for small servers, larger ones may use 4G.

sudo fallocate -l 2G /swapfile # allocate 2G of disk space
sudo chmod 600 /swapfile # only root can read the file
sudo mkswap /swapfile # format as swap
sudo swapon /swapfile # enable immediately

Make the setting permanent by adding it to /etc/fstab, which defines what is mounted at boot.

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Adjust the swappiness value. The default (60) moves data to swap fairly aggressively. A value of 10 keeps data in RAM longer and uses swap only when necessary.

echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p # apply settings immediately without reboot

9. Backups

Security hardening won’t help if your disk fails or you accidentally delete important files. Backups are essential.

Install rsync, an efficient file synchronization tool.

sudo apt install rsync -y

Create a script that automatically backs up key directories. The script stores backups in date-based folders and deletes versions older than 30 days.

sudo nano /usr/local/bin/backup.sh

Add the following content:

#!/bin/bash
DATE=$(date +%Y-%m-%d) # get today’s date
TARGET="/backup/$DATE" # target path e.g. /backup/2025-01-30

mkdir -p $TARGET # create target directory if it doesn't exist
rsync -av /etc/ $TARGET/etc/ # copy system configuration
rsync -av /var/www/ $TARGET/www/ # copy web files
rsync -av /home/ $TARGET/home/ # copy user home directories

find /backup -maxdepth 1 -type d -mtime +30 -exec rm -rf {} ; # delete backups older than 30 days

Make the script executable and schedule it to run every night at 03:00.

sudo chmod +x /usr/local/bin/backup.sh # make executable
sudo crontab -e # open cron editor

Add this line at the end of the cron file and save:

0 3 * * * /usr/local/bin/backup.sh # run every night at 03:00

10. Checklist

sudo ufw status verbose # is firewall active and rules correct?
sudo systemctl status sshd # is SSH working?
sudo systemctl status fail2ban # is Fail2ban running?
sudo swapon --show # is swap active?
sudo unattended-upgrade --dry-run # are automatic updates working? (dry-run = test run)
Was this answer helpful? 0 Users Found This Useful (0 Votes)