Blog
4 min read

How to Secure a New VPS: The First 30 Minutes

A fresh server is scanned within minutes of going online. The essential hardening steps for a new Ubuntu VPS: updates, a non-root user, SSH keys only, firewall, automatic security patches, fail2ban, safe service binding, backups and monitoring — in order, with commands.

The moment a new VPS gets a public IP, bots start trying to log in. Most of them are dumb password-guessers, and a few simple steps make your server uninteresting to them. Do these before you deploy anything.

Commands are for Ubuntu/Debian; other distributions have equivalents.

1. Update everything

apt update && apt full-upgrade -y
reboot   # if a new kernel was installed

Fresh images are often weeks behind on security patches.

2. Create a non-root user with sudo

Working as root means every typo has full power, and root is the account every bot tries.

adduser deploy
usermod -aG sudo deploy

3. SSH keys for that user

From your computer (create a key first if you don't have one — SSH keys explained):

ssh-copy-id deploy@YOUR_SERVER_IP

Or, if you only have root access with a key already, copy it across on the server:

rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

Test it in a new terminal — ssh deploy@YOUR_SERVER_IP — and confirm sudo works, before the next step.

4. Lock down SSH

Edit /etc/ssh/sshd_config (or add a file in /etc/ssh/sshd_config.d/):

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes

Then:

sudo sshd -t && sudo systemctl reload ssh

Keep your current session open and test a fresh login in another terminal. Some cloud images set PasswordAuthentication yes in a separate file under sshd_config.d/ that overrides yours — sudo sshd -T | grep -i password shows the effective value.

Changing the SSH port reduces log noise but isn't real security; keys-only is what matters. (The SSH config file makes connecting with keys painless.)

5. Firewall: deny by default

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable

Add your cloud provider's firewall in front as a second layer. (UFW firewall basics)

6. Automatic security updates

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

This installs security patches daily. Decide whether automatic reboots are acceptable (Unattended-Upgrade::Automatic-Reboot in /etc/apt/apt.conf.d/50unattended-upgrades), or reboot yourself regularly when /var/run/reboot-required exists.

7. Slow down brute-forcers

sudo apt install -y fail2ban

The default config bans IPs after repeated failed SSH logins. With password logins disabled it's mostly about log noise, but it also protects other services you configure it for.

8. Bind services to localhost

Everything that isn't a public website should listen on 127.0.0.1 only:

  • Databases (Postgres, MySQL, Redis, MongoDB) — never on 0.0.0.0. Check with sudo ss -ltnp.
  • Your app on port 3000 — reached only through the reverse proxy on 443.
  • Docker published ports — bind to 127.0.0.1:5432:5432, because Docker bypasses UFW. (Container networking internals)

To reach the database from your laptop, use an SSH tunnel. (SSH port forwarding)

9. Run apps as unprivileged users

Your app shouldn't run as root. Run it under deploy (or a dedicated app user) via systemd or PM2, and let the reverse proxy — not your app — bind ports 80/443. (PM2 vs systemd)

Keep secrets in files only that user can read (chmod 600 .env). (Linux file permissions)

10. Backups that leave the server

A backup on the same disk dies with the disk — or with whoever compromises the server. Send database dumps and uploads to object storage or another provider, encrypt them, and test a restore. (Backups for beginners, Postgres backup and restore)

Provider snapshots are a nice extra, not a substitute.

11. Know what's happening

The checklist

  • Fully updated
  • Non-root sudo user
  • SSH keys only; root login and passwords off
  • Firewall: 22, 80, 443 only
  • Automatic security updates
  • fail2ban
  • Databases and internal ports on localhost
  • Apps running as non-root
  • Off-server, tested backups
  • Uptime, certificate and disk monitoring

The ongoing part

Hardening isn't one-and-done: patch, renew, rotate keys when people leave, review what's listening, and keep the OS within its support window. That ongoing work is the real cost of running your own server. (VPS vs PaaS)


EasySpawn does this for you: managed servers with the OS, patching, firewall, SSL and backups handled, and databases never exposed to the internet — you just deploy. See how it works or join the waitlist.

Related: What Is a VPS? · UFW Firewall Basics · Deploy a Node.js App to a VPS · SSH Keys Explained

Keep reading