serverserv serverserv

How to secure a Linux VPS: 10 steps after your first login

By the serverserv team · 7 min read · Updated

To secure a Linux VPS, update it, log in as a normal sudo user with an SSH key, turn off root and password logins, allow only the ports you need with ufw, ban repeat offenders with fail2ban, switch on automatic security updates and keep backups you control. This guide walks through those 10 steps with exact commands for Ubuntu and Debian, in the order to run them after your first login.

What are the 10 steps to secure a new VPS?

Run these steps in one sitting, in this order, before you install your app. Most take a minute or two, and the whole list takes about 30 minutes.

A server with a public IP address starts receiving automated login attempts soon after it goes online, often within minutes. Default settings are built to get you in, not to keep others out.

StepWhat you doMain toolWhat it protects against
1Install all updatesapt upgradeKnown bugs in old packages
2Create a sudo useradduserMistakes and break-ins as root
3Log in with an SSH keyssh-keygenPassword guessing
4Turn off root and password loginssshd_config.dBots that try root passwords
5Turn on a firewallufwPorts you opened by accident
6Ban repeat offendersfail2banRepeated login attempts
7Automatic security updatesunattended-upgradesHoles left open between logins
8Close what you do not usess -tulpnDatabases and dashboards on the internet
9Backups you controlresticData loss, mistakes and ransomware
10A monthly checkjournalctlProblems nobody noticed

The commands assume Ubuntu 22.04 or newer, or Debian 12 or newer. Replace alice with your own username and 203.0.113.10 with your server's IP address from your welcome email.

Steps 1 and 2: update the system and stop working as root

Install every pending update first, then create a normal user with sudo rights for daily work. Root can change anything without asking, so one typo or one stolen password affects the whole server.

Log in with the details from your welcome email, for example ssh [email protected], then run:

  1. Update everything: apt update && apt upgrade -y
  2. Check whether a restart is needed: ls /var/run/reboot-required. If the file exists, run reboot and log in again.
  3. On minimal Debian images, install sudo: apt install sudo -y
  4. Create your user and set a strong password: adduser alice
  5. Give it sudo rights: usermod -aG sudo alice
  6. In a second terminal window, log in as the new user and test: ssh [email protected], then sudo whoami. It should print root.

Keep the first root session open until the new login works. That habit protects you from locking yourself out at every step below.

Steps 3 and 4: switch to SSH keys and turn off password logins

Log in with an SSH key instead of a password, then tell the SSH server to refuse root logins and passwords. A key cannot realistically be guessed, so password-guessing bots stop being a risk.

Create and copy your key

On your own computer (Linux, macOS, or PowerShell on Windows 10 and 11), create a key pair and set a passphrase when asked: ssh-keygen -t ed25519 -C "alice laptop"

Copy the public key to the server from Linux or macOS with ssh-copy-id [email protected]. On Windows PowerShell, use: type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Now run ssh [email protected] again. It should log you in without asking for the account password.

Lock down the SSH server

Write your settings to a small drop-in file instead of editing the main config:

printf 'PermitRootLogin no\nPasswordAuthentication no\nKbdInteractiveAuthentication no\n' | sudo tee /etc/ssh/sshd_config.d/01-hardening.conf

The name starts with 01 on purpose. SSH keeps the first value it reads for each setting, and some cloud images add a file such as 50-cloud-init.conf that turns password logins back on.

  1. Check the syntax: sudo sshd -t. No output means it is fine.
  2. Apply it: sudo systemctl restart ssh
  3. Confirm: sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication' should show both set to no.
  4. Open a new terminal and log in again before you close the old session.

Moving SSH away from port 22 cuts log noise from bots, but it does not replace keys. If you change the port, allow the new one in the firewall before you restart SSH.

Steps 5 and 6: how to secure a Linux VPS with ufw and fail2ban

ufw blocks every incoming connection except the ports you allow, and fail2ban bans IP addresses that keep failing to log in. Allow SSH before you enable the firewall, or you will cut off your own session.

Set up ufw

  1. sudo apt install ufw -y
  2. sudo ufw default deny incoming and sudo ufw default allow outgoing
  3. sudo ufw limit OpenSSH allows SSH but blocks an address that opens 6 or more connections within 30 seconds.
  4. If the server will host a website: sudo ufw allow 80,443/tcp
  5. sudo ufw enable, then check with sudo ufw status verbose

One catch: ports published by Docker containers skip ufw rules. Our guide to installing Docker on a VPS shows how to handle that.

Set up fail2ban

  1. sudo apt install fail2ban python3-systemd -y
  2. printf '[sshd]\nenabled = true\nbackend = systemd\nmaxretry = 5\nfindtime = 10m\nbantime = 1h\n' | sudo tee /etc/fail2ban/jail.local
  3. sudo systemctl enable fail2ban and sudo systemctl restart fail2ban
  4. Check it: sudo fail2ban-client status sshd

The backend = systemd line matters on Debian 12 and newer, which log to the systemd journal instead of /var/log/auth.log by default. With key-only SSH, fail2ban mainly keeps your logs quiet. It adds more value once you protect other logins, such as a web admin page.

Steps 7 and 8: automatic security updates and fewer open ports

The unattended-upgrades package installs security fixes every day without you logging in. Then list every port that is listening and close, or move to localhost, anything the internet does not need.

Automatic updates

  1. sudo apt install unattended-upgrades -y
  2. sudo dpkg-reconfigure -plow unattended-upgrades and answer Yes.
  3. Test it: sudo unattended-upgrade --dry-run --debug

By default it installs security updates only and never restarts the server. Kernel fixes need a restart to take effect, so either reboot yourself once a week, or set Unattended-Upgrade::Automatic-Reboot "true"; and Unattended-Upgrade::Automatic-Reboot-Time "03:00"; in /etc/apt/apt.conf.d/50unattended-upgrades.

Find and close open ports

Run sudo ss -tulpn. Any line with 0.0.0.0 or [::] as the local address listens on every network interface. Databases such as MySQL (3306), PostgreSQL (5432) and Redis (6379), and admin dashboards, should listen on 127.0.0.1 only.

To reach a private dashboard, use an SSH tunnel instead of opening a port: ssh -L 8080:127.0.0.1:8080 [email protected], then browse to localhost:8080 on your own computer. OpenClaw's security documentation gives the same advice for its gateway on a VPS: keep it on loopback and reach it through an SSH tunnel or Tailscale. Remove software you no longer use with sudo apt purge package-name.

Steps 9 and 10: backups you control and a monthly check

Keep at least one copy of your data off the server, on storage you control, and test a restore. Then spend ten minutes a month on a short check, because settings drift as you install new things.

Backups

Hosts handle backups differently. At the time of writing, Hostinger lists weekly backups on its VPS plans, and Hostwinds charges $1 a month plus $0.03 per GB. serverserv's Linux VPS plan specs do not list backups, so plan your own. A copy with a different company also protects you if something goes wrong with your hosting account.

restic is a free tool that makes encrypted, deduplicated backups to another server or to object storage:

  1. sudo apt install restic -y
  2. Create a repository on a second machine you control: sudo restic -r sftp:[email protected]:/srv/restic init
  3. Dump databases first, for example sudo -u postgres pg_dump mydb | gzip > ~/mydb.sql.gz or sudo mysqldump --single-transaction mydb | gzip > ~/mydb.sql.gz
  4. Back up: sudo restic -r sftp:[email protected]:/srv/restic backup /etc /home /var/www
  5. Keep a sensible history: sudo restic -r sftp:[email protected]:/srv/restic forget --keep-daily 7 --keep-weekly 4 --prune
  6. Test a restore: sudo restic -r sftp:[email protected]:/srv/restic restore latest --target /tmp/restore-test

To run it every night from cron, store the repository password in a file only root can read and point RESTIC_PASSWORD_FILE at it. A backup you have never restored is only a hope.

The monthly check

  • sudo fail2ban-client status sshd for recent bans
  • last -a | head -20 for recent logins you should recognise
  • sudo ufw status numbered to remove rules you no longer need
  • apt list --upgradable for updates that are waiting
  • df -h to keep at least 15 to 20 percent of the disk free

Should you secure the server yourself or have it managed?

Every serverserv Linux KVM VPS is unmanaged with full root access, so you can apply all ten steps yourself. If you would rather not run servers, Managed VPS is the option where our team manages the server for you.

  • KVM Mini (1 vCPU, 2 GB RAM, 25 GB NVMe): $8.99 monthly, or $6.29 a month on a 3-year term. Enough for a bot, a VPN or a practice server.
  • KVM 1 (1 vCPU, 4 GB RAM, 50 GB NVMe): $14.99 monthly, or $10.49 a month on 3 years. A small site or app with its database.
  • KVM 2 (2 vCPU, 8 GB RAM, 100 GB NVMe): $23.99 monthly, or $16.49 a month on 3 years. A sensible default for production apps and Docker stacks.
  • Managed VPS 1 (1 vCPU, 4 GB RAM, 50 GB NVMe): $27.99 monthly plus a one-off $10 setup fee, or $19.99 a month on a 3-year term with no setup fee. To confirm exactly what is managed for your project, open a ticket before you order.

Every term renews at the price you paid. If a price ever has to change, you get at least 30 days' notice by email and can cancel before renewal. For sizing help, read how much CPU and RAM your VPS needs, and compare terms on the pricing page.

Questions

How do I connect to my VPS with SSH?

Open a terminal on Linux or macOS, or PowerShell on Windows 10 and 11, and run ssh root@your-server-ip with the details from your welcome email. After following this guide, you log in as your own user with an SSH key instead.

Are KVM-based virtual private servers safe?

KVM gives each VPS its own kernel and keeps it separate from other customers on the same host. What runs inside is your responsibility, and a server left on default settings with password logins is still an easy target until you apply steps like these.

Is the serverserv Linux VPS managed or unmanaged?

It is unmanaged: you get full root access and handle security, updates and software yourself. If you want our team to manage the server, choose Managed VPS.

Do serverserv VPS plans include backups?

The Linux VPS plan specs do not list backups, so keep your own copy off the server with a tool such as restic. If backups matter for your project, open a ticket before you order and ask about options.

Should I change the SSH port from 22?

It reduces log noise from bots but does not replace SSH keys and turning off password logins. If you change it, allow the new port in ufw before you restart SSH.

Sources

Prices from other companies are as published at the time of writing and can change.

Ready to deploy?

Pick a plan, choose a term and you are online in minutes.

See all plansTalk to sales

Need a custom server, bulk pricing or help moving from another host? Our team will build a quote for you.

Plans from $3.99/moSee plans