VPS First-Hour Checklist: Secure a Fresh Server Fast
You just spun up a fresh VPS and you've got a root password sitting in your inbox. Before you install anything, deploy any code, or point a domain at it, spend the first hour locking down the basics. Skip this and you're not "getting to it later" — you're leaving a default SSH port and root login open to every bot scanner on the internet, usually within minutes of boot.
Why the first hour is the one that matters
Automated scanners find new IPs fast. On a fresh VPS it's common to see SSH brute-force attempts within 5-10 minutes of the server going live, long before you've even logged in for the first time yourself. The goal of this checklist isn't to be exhaustive — it's to get the server from "wide open" to "reasonably safe to leave running overnight" as fast as possible. Deeper hardening (fail2ban tuning, full firewall rules, log auditing) can come after.
Step 1: Update the system first, before anything else
Log in as root over SSH using the password or key your provider gave you, then update packages immediately:
apt update && apt upgrade -y
On CentOS/AlmaLinux/Rocky, use dnf upgrade -y instead. This patches any known kernel or SSH vulnerabilities that shipped with the base image before you do anything else with the box.
Step 2: Create a non-root user with sudo
Never run day-to-day work as root. Create a dedicated user and give it sudo rights:
adduser deploy
usermod -aG sudo deploy
Test that it works — open a second terminal, SSH in as deploy, and confirm sudo whoami returns root — before you touch SSH settings in Step 3. If you lock yourself out of root without a working sudo user first, you'll need your provider's rescue console to fix it.
Step 3: Set up SSH keys, then disable password login
From your local machine, copy your public key to the new user:
ssh-copy-id deploy@your-server-ip
Log in once with the key to confirm it works, then edit /etc/ssh/sshd_config and set:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
Restart SSH with systemctl restart sshd. Keep your current session open until you've confirmed a fresh login works in a new window — a typo here can lock you out entirely.
Step 4: Turn on the firewall and allow only what you need
UFW is the fastest way to get a working firewall on Ubuntu/Debian:
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
Only open ports for services you're actually running. If you haven't installed a web server yet, skip the 80/443 rules and add them when you do — every open port is one more thing a scanner can probe.
Step 5: Set the hostname and timezone
Logs, cron jobs, and cert renewals all get confusing fast if the server thinks it's in a different timezone than you:
hostnamectl set-hostname web01
timedatectl set-timezone Asia/Kolkata
Swap in whatever timezone matches your business, not necessarily the datacenter's location.
Step 6: Add swap if the RAM is small
Budget VPS plans (1-2GB RAM) run out of memory fast under a MySQL + PHP-FPM stack, and without swap the kernel's OOM killer will just kill whatever process it feels like — often MySQL, mid-write. A 2GB swap file is cheap insurance:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Step 7: Install fail2ban
Even with password auth disabled, fail2ban is worth having from hour one — it also protects any web-facing login forms (WordPress, cPanel, etc.) you add later:
apt install fail2ban -y
systemctl enable --now fail2ban
The default SSH jail is enabled out of the box on most distros. You can tune ban times and retry counts later once you see real traffic patterns in the logs.
Step 8: Take a baseline snapshot
Once steps 1-7 are done and you've confirmed you can still log in as deploy, take a snapshot through your provider's control panel. This becomes your "known good, clean, hardened" restore point — if a deployment goes sideways later, you roll back to a secure base instead of a bare, unpatched image.
Quick reference: the first-hour order of operations
| # | Task | Why it comes at this point |
|---|---|---|
| 1 | apt update && upgrade | Patch known CVEs before anything else runs |
| 2 | Create sudo user | Needed before you lock down root |
| 3 | SSH keys, disable passwords | Closes the #1 attack vector |
| 4 | Enable UFW | Blocks everything except what you explicitly allow |
| 5 | Hostname + timezone | Keeps logs and cron/cert timing sane |
| 6 | Swap file | Prevents OOM kills on low-RAM plans |
| 7 | fail2ban | Automated ban for repeated failed logins |
| 8 | Snapshot | Clean restore point before you deploy anything |
Mistakes that undo all of this
- Disabling password auth before testing key login. Always open a second terminal and confirm the key works before you edit sshd_config.
- Enabling UFW without allowing SSH first. If you run
ufw enablebeforeufw allow OpenSSH, you'll cut your own session and need console access to recover. - Skipping swap on a 1GB plan. This is the single most common cause of "MySQL just stopped" reports we see from small VPS plans running WordPress.
- Leaving the default hostname. It's harmless functionally, but it makes log analysis across multiple servers painful later.
None of this takes more than 30-45 minutes once you've done it a couple of times, and it turns a bare, exposed box into a server you can actually trust with real traffic and data.
Frequently asked questions
How soon after a VPS goes live do bots start scanning it?
Often within 5-10 minutes. Automated scanners continuously sweep IP ranges for open SSH ports and default credentials, so a fresh server is a target the moment it boots, not just after you've configured it.
Do I really need swap if my VPS already has 4GB or more of RAM?
It's less critical, but still cheap insurance. A small swap file (1-2GB) gives the kernel breathing room during memory spikes - a big database import or a WordPress backup job - without triggering the OOM killer.
What if I lock myself out of SSH while following this checklist?
Every major VPS provider offers a browser-based console (sometimes called VNC console or rescue console) accessible from the control panel, separate from SSH. Use it to fix sshd_config or firewall rules even if SSH itself is unreachable.
Should I set up fail2ban before or after installing my web server?
Before. fail2ban's SSH jail is enabled by default and protects you immediately, and it's one less thing to remember once you're focused on getting a site or app running.