Blog

Securing a freshly rented VPS: the 7 essential settings

Sudo user, SSH key, root and passwords disabled, ufw firewall, fail2ban, automatic security updates and backups: the commands for Ubuntu and Debian.

Équipe Coxios4 min read

  • Security
  • SSH
  • Ubuntu
  • Debian
All articles

A brand-new VPS is reachable from the whole Internet as soon as it boots. Within the hour, bots are already trying passwords on port 22: it is not an attack aimed at you, it is a constant sweep of every IP address. A server left with root password login will give in sooner or later.

Here are the 7 settings to apply before installing anything, in order. The commands are written for Ubuntu 22.04 / 24.04 and Debian 12. Start by updating the system, logged in as root with the credentials your provider sent you:

bash
apt update && apt upgrade -y

1. Create a non-root user with sudo

Working as root every day means a typo or a script you did not read carefully has full power. Create your own user and give it sudo (on a minimal Debian image, install sudo first with apt install sudo):

bash
adduser marie
usermod -aG sudo marie

2. Log in with an SSH key

An SSH key cannot be guessed, unlike a password. Generate it on your computer (not on the server), then copy the public part to your new user:

bash
ssh-keygen -t ed25519 -C "marie@laptop"
ssh-copy-id -i ~/.ssh/id_ed25519.pub marie@SERVER_IP

# Check that the key works before going further
ssh -i ~/.ssh/id_ed25519 marie@SERVER_IP
On Windows, ssh-copy-id does not exist: paste the content of id_ed25519.pub into the user's ~/.ssh/authorized_keys on the server.

3. Disable root login and passwords

Once the key is tested, stop SSH from accepting root and passwords. On recent Ubuntu and Debian, the cleanest way is a file in /etc/ssh/sshd_config.d/. The 00- prefix matters: SSH keeps the first value it reads, and many cloud images ship a 50-cloud-init.conf that turns passwords back on.

bash
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
EOF

sudo sshd -t && sudo systemctl restart ssh
sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication'
sshd -t checks the syntax before the restart, sshd -T prints the configuration actually applied: both lines must end with no.

From your second terminal, ssh root@SERVER_IP must now answer Permission denied (publickey). Moving SSH off port 22 reduces log noise but adds no real security: the key and fail2ban do the work.

4. Turn on a firewall with ufw

The idea: deny everything incoming, then open only what you need. Allow SSH before enabling the firewall, or you lock yourself out.

bash
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

5. Ban attackers with fail2ban

fail2ban reads the SSH logs and temporarily bans addresses that fail too often. Debian 12 no longer has a /var/log/auth.log file by default, so we read the systemd journal instead, which works on Ubuntu as well.

bash
sudo apt install fail2ban python3-systemd
sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
backend = systemd
EOF

sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Add your static IP to ignoreip in the [DEFAULT] section so you never ban yourself. Details in Fail2ban explained simply.

6. Install security updates automatically

Most hacked servers fall to a flaw that was patched long ago. unattended-upgrades installs security fixes every day, without touching major upgrades.

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

# Dry run: shows what would be installed
sudo unattended-upgrade --dry-run --debug
A kernel update only takes effect after a reboot. The file /var/run/reboot-required appears when one is needed, and the Unattended-Upgrade::Automatic-Reboot option in /etc/apt/apt.conf.d/50unattended-upgrades can handle it at night.

7. Plan backups (and test the restore)

Security also means being able to recover from a mistake, a deletion or a failing disk. Two levels work together:

  • Provider snapshots: a full image of the disk, one click away in their dashboard, often a paid option. Ideal before a big upgrade.
  • An off-server backup of your data: your files and a dump of your databases, sent somewhere else. If you lose access to the provider account, you lose the snapshots too.
bash
sudo apt install restic
restic -r sftp:backup@other-server:/backups/vps init
restic -r sftp:backup@other-server:/backups/vps backup /etc /home /srv

# The test that matters: restore
restic -r sftp:backup@other-server:/backups/vps restore latest --target /tmp/restore
For a database, back up a dump (pg_dump, mysqldump) rather than its files while they are being written. A backup you never restored is only a hope.

Checklist

Before deploying your first application, make sure everything is ticked:

  • A personal user with sudo, no more working as root.
  • SSH key login, tested from a second terminal.
  • PermitRootLogin no and PasswordAuthentication no confirmed by sshd -T.
  • ufw active, only SSH, HTTP and HTTPS open.
  • fail2ban active on sshd, your IP in ignoreip.
  • Security fixes installed every day.
  • Off-server backups, and one restore already done.