My VPS Baseline Before I Host Anything

VPS Baseline checklist diagram for securing and preparing a new Ubuntu VPS

This VPS Baseline is the checklist I follow before deploying WordPress, CloudPanel, Beszel, Docker, or any other self-hosted service.

TL;DR

Before I deploy anything, I take care of the basics first:

  • provider firewall
  • SSH access with keys only
  • basic tools and resolver sanity
  • SSH tunnels for services I do not want exposed

That is the baseline. Everything else comes later.

Step 1 — Lock the Edge First

If the provider gives me firewall rules, I use them.

On OVH, that means Edge Network Firewall. On Hetzner, I use Cloud Firewalls. Same idea, different panel: keep the server quiet until I decide what should be visible.

For a typical WordPress VPS, the baseline looks like this:

  • SSH only from my IP
  • HTTP (80) if needed
  • HTTPS (443)
  • everything else closed

Example OVH-style rules:

  • Allow 22/tcp from my IP
  • Allow 80/tcp
  • Allow 443/tcp
  • Deny everything else

OVH Edge Network Firewall rules for a WordPress VPS

If Linux is the first thing seeing random internet traffic, I started too late.

Step 2 – SSH Keys Before You Touch Anything

I create a normal admin account, add my key, and stop using passwords as soon as possible.

ssh-keygen -t ed25519 -C "bootriven"
ssh-copy-id user@server-ip

If ssh-copy-id is not available, I place the key manually:

~/.ssh/authorized_keys

Then I test the login:

ssh user@server-ip

Expected output:

Welcome to Ubuntu 24.04 LTS

Once key authentication works, I disable password login.

PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes

Apply changes:

sudo systemctl restart ssh

Always test a second SSH session before closing the first one.

Step 3 — Make DNS Boring

I want predictable DNS. No random edits to /etc/resolv.conf and no guessing.

First check:

resolvectl status

Typical output:

Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub
Link 2 (ens3)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 1.1.1.1
       DNS Servers: 1.1.1.1 8.8.8.8
        DNS Domain: ~.

I usually keep Cloudflare as primary and Google as fallback.

If DNS is broken, everything above it becomes harder to troubleshoot.

Step 4 — Install the Tools I Actually Use

This is not a giant package list. Just the tools I use constantly.

sudo apt update
sudo apt install -y \
htop \
btop \
ncdu \
jq \
tmux \
ripgrep \
curl \
wget \
unzip \
iftop \
neofetch

My usual minimum:

  • btop or htop for system visibility
  • ncdu for storage usage
  • tmux for long-running sessions
  • jq for JSON output
  • ripgrep for searching configs
  • iftop for network traffic
  • curl for almost everything else
  • neofetch because I still like it

I also add neofetch to my shell startup:

echo 'neofetch' >> ~/.bashrc

Neofetch

Step 5 — Use SSH Tunnels Instead of Opening Ports

A lot of admin panels do not need a public port.

CloudPanel, Beszel, Grafana, Adminer, phpMyAdmin and internal dashboards can stay private behind SSH.

Local Forward

Use this when the service runs on the VPS.

ssh -L 8443:127.0.0.1:8443 user@server-ip

Then open:

https://127.0.0.1:8443

CloudPanel becomes available locally without exposing port 8443 publicly.

CloudPanel through SSH tunnel

Reverse Tunnel

Use this when the service lives behind your home network and you want temporary access through the VPS.

ssh -R 9000:127.0.0.1:3000 user@server-ip

Verify the listener:

ss -lntp | grep 9000

Expected output:

LISTEN 0      128        127.0.0.1:9000       0.0.0.0:*    users:(("sshd",pid=1234,fd=9))

PuTTY

  • Connection → SSH → Tunnels
  • Source port: 8443
  • Destination: 127.0.0.1:8443
  • Select Local for forward tunnels
  • Select Remote for reverse tunnels

For most admin work, this is enough. No extra ports, no extra firewall rules, no extra internet-facing services.

Step 6 — Keep a Small Admin Toolkit

These are the commands I reach for constantly:

htop
btop
ncdu
tmux
jq
rg
curl
iftop

Examples:

ncdu /
tmux new -s work
curl -I https://example.com
rg "server_name" /etc/nginx

I do not need 30 packages. I need the ones that help me understand what the server is doing.

Step 7 — Watch Backups Like You Mean It

Even if provider backups are enabled, I always verify them. A backup you have never restored is just an assumption.

My baseline:

  • know where backups go
  • know how often they run
  • know how to restore them
  • test one restore before trusting them

With Restic:

restic snapshots

Example:

ID        Time                 Host          Tags        Paths
c1a2b3d4  2026-06-20 01:15:00  bootriven     daily       /var/www /etc /home

The backup software is less important than the restore process.

Verification

This is the order I repeat on almost every VPS, whether it ends up running WordPress, Docker, or something completely different:

  1. Configure provider firewall
  2. Switch to SSH keys
  3. Verify DNS
  4. Install admin tools
  5. Create SSH tunnels where needed
  6. Verify backups

Once those six steps are done, I can start deploying WordPress, CloudPanel, Docker stacks, Beszel, or whatever the VPS was actually purchased for.

My VPS Baseline Checklist

This VPS Baseline has remained almost identical across OVHcloud and Hetzner Cloud. The provider changes. The checklist usually doesn’t.

  • Edge firewall configured
  • SSH key login working
  • Password authentication disabled
  • DNS verified
  • Admin tools installed
  • SSH tunnels tested
  • Backups verified

If all of that is yes, the VPS is ready for the next layer.

Where I Run This

At the time of writing, I mostly run servers on OVHcloud and Hetzner Cloud. The exact control panel and firewall options differ, but the baseline stays almost identical.