The NordBastion polar-bear mascot at a Nordic stone forge welding armor plating and brass padlocks onto a small server-tower on an anvil, cyan protective glyphs wrapping its base, amber forge-hearth glow and amber welding sparks
How-to · Checklist·10 min read · 60 min hands-on

VPS hardening — the first-hour OPSEC checklist.
Eight steps. Run this on every fresh server.

The universal pre-launch checklist before any workload goes on a fresh VPS. SSH key-only, custom port, firewall, auto-updates, fail2ban, snapshot, documented recovery. Tested on Debian 12 / Ubuntu 22-24 / Alpine.

The eight steps
  1. 01

    SSH key auth

  2. 02

    Disable root + change port

  3. 03

    Firewall baseline

  4. 04

    Unattended-upgrades

  5. 05

    Fail2ban

  6. 06

    Time + swap

  7. 07

    Baseline snapshot

  8. 08

    Recovery doc

Step 01-02 · SSH

Keys, not passwords. Custom port, not 22.

On your laptop, generate an ed25519 keypair (smaller, faster, modern):

ssh-keygen -t ed25519 -C "you@laptop"
ssh-copy-id -p 22 root@<vps-ip>
ssh root@<vps-ip>     # should now work without password

On the VPS, edit /etc/ssh/sshd_config:

Port 54871                  # pick a random number 1024-65535
PermitRootLogin no          # use a non-root user with sudo
PasswordAuthentication no   # keys only
PubkeyAuthentication yes

Create a non-root sudo user first (adduser bear; usermod -aG sudo bear; ssh-copy-id -p 22 bear@vps), test login, THEN restart sshd: systemctl restart sshd. If you lock yourself out, the panel console gives shell access without SSH.

Step 03 · Firewall

Default deny inbound. Allowlist what you need.

apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 54871/tcp      # custom SSH port
ufw allow 80/tcp         # if running a web service
ufw allow 443/tcp        # if running TLS
ufw enable
ufw status verbose

Replicate the same rule set in the NordBastion bastion-level firewall via the panel (Networking → Firewall). The bastion firewall blocks before the packet reaches the VPS, saving CPU on volumetric scanning. Defence in depth.

Step 04-05 · Auto-updates + fail2ban

Two packages, five minutes, real impact.

apt install -y unattended-upgrades fail2ban
dpkg-reconfigure -plow unattended-upgrades   # accept defaults
systemctl enable --now fail2ban
fail2ban-client status                       # shows sshd jail

Unattended-upgrades applies security patches automatically; fail2ban bans IPs that fail 5 auth attempts within 10 minutes for 1 hour. Neither requires further config for the baseline use case — both are aggressive defaults that work for everyone.

Step 06 · Time + swap

Set timezone UTC. Add a swapfile.

timedatectl set-timezone UTC

fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile none swap sw 0 0" >> /etc/fstab
free -h                                       # confirm swap is active

UTC on the server simplifies log correlation across bastions and clients in any timezone. A 2-4 GB swapfile protects against OOM-kill spikes; on small tiers it matters, on big tiers it is cheap insurance.

Step 07-08 · Snapshot + recovery doc

Capture the clean state. Write down the recovery path.

Snapshot. In the panel: Servers → your server → Snapshots → Create. Name it baseline-hardened-YYYY-MM-DD. NordBastion snapshots are off-host, encrypted, and take seconds. You can restore in about 90 seconds — your future self will thank you the first time an upgrade goes sideways.

Recovery doc. On paper or in a password manager, write down:

  • NordBastion account email + (password mnemonic, not the password itself)
  • Where your SSH private key lives on the laptop
  • The custom SSH port number
  • The non-root sudo username on the VPS
  • The name of the baseline snapshot to restore to
  • A note: "panel console works without SSH — use it for lock-out recovery"

OPSEC is the discipline of writing things down today so future-you can recover when current-you has forgotten. The forge is closed when the doc is complete.

FAQ · Hardening

Questions, answered.

Eight questions a first-time VPS customer asks while running the checklist.

Is SSH key auth actually safer than a strong password?

Yes, by a wide margin. A password — even a 16-character random one — is brute-forceable in some realistic threat model; an ed25519 SSH key has 256 bits of entropy and is not. A key is also bound to the device it lives on, so an attacker needs both the key file AND the passphrase that decrypts it. Disable PasswordAuthentication entirely in sshd_config and the brute-force attack surface goes to zero.

Does changing the SSH port from 22 to a random one actually help?

It does not stop a determined attacker — they will scan all 65,535 ports. It DOES reduce the volume of automated noise from bots that only try port 22, which means cleaner logs and lower-stress fail2ban. Pick a random port between 1024 and 65535, write it down somewhere you will not lose, update the firewall to allow it. Net win: about 90 percent less log noise.

UFW or nftables — which one?

UFW for someone learning or running a single VPS — it is a friendly wrapper, the syntax is human-readable, and it sits on top of either iptables or nftables underneath. nftables directly if you want stricter rule composition, anonymous sets, or run more than a handful of servers and want consistency. Both produce the same kernel-level result.

Should I run unattended-upgrades for the kernel too?

Security patches yes — they fix critical CVEs and the alternative is leaving them open. Full kernel package upgrades are riskier because they need a reboot to take effect; unattended-upgrades will not reboot for you by default. Read /etc/apt/apt.conf.d/50unattended-upgrades and decide: most NordBastion customers leave the unattended config at "security-only", and reboot manually monthly during a quiet window.

Is fail2ban necessary if I already disable password auth?

Strictly required, no — once password auth is off, brute-force on SSH cannot succeed. Fail2ban remains useful for other services (mail, web app login pages, anything that has a credential layer). Cheap insurance: apt install fail2ban, accept the defaults, move on. The 30 seconds it takes to install is worth the cleaner logs and the bonus services-protection it provides.

What about full disk encryption?

Not part of the first hour — full disk encryption with user-held key requires either a custom ISO install (mounting LUKS at boot with a passphrase someone has to type) or the upcoming NordBastion LUKS-on-provision option (panel roadmap). For now, treat the disk as readable by NordBastion (in the unlikely event of subpoena) and treat NordBastion's jurisdictional protection as the layer keeping it safe. If your threat model requires FDE before launch, install Debian via the rescue ISO into a LUKS root volume and unlock through the panel console at each boot — workable but a meaningful change in operational burden.

How often should I take snapshots?

Three useful cadences. (1) Before every meaningful change (package upgrade, config edit, OS upgrade). (2) On a schedule — once a week is a reasonable default for any production workload. (3) Before each backup-verification drill, so you can prove restoration works. NordBastion snapshots are off-host and encrypted; they do not consume your VPS disk and can be restored in about 90 seconds.

Should I monitor the VPS, and how?

For first-hour: not yet — get the hardening done, get the workload running, then add monitoring once you have something worth monitoring. Lightweight options: node_exporter + Prometheus + Grafana on a second tiny VPS, Netdata as a single-binary self-hosted dashboard, or simpler still, a free-tier external uptime checker (UptimeRobot, BetterStack) pinging the public ports. Pick one, configure it, and forget — monitoring is most useful when it stays silent.

Next

Server hardened. Now build something on it.

Last reviewed · 2026-05-20 · Tested · Debian 12 · Ubuntu 22.04 / 24.04 · Alpine 3.19+