vps-dedicated

Securing a Fresh VPS — Day-One Hardening Checklist

The first-hour security checklist for any new VPS — SSH hardening, firewall, fail2ban, automatic updates, and the basics that prevent most attacks.

5 min read

A fresh VPS is a clean slate — and a target. Within minutes of an IP being assigned, bots are probing it for default credentials, known vulnerabilities, and exposed services. The first hour of work on a new VPS should be hardening it, not deploying apps. This checklist covers what to do, in what order, and why each step matters.

Before you start: what you’ve got

iWebVault VPS provisioning gives you:

  • Server IP (or multiple IPs).
  • Root password (in your welcome email or client area).
  • SSH access on port 22 by default.
  • OS pre-installed (Ubuntu, AlmaLinux, Debian, CentOS variants).
  • Optional: cPanel/WHM or DirectAdmin if you ordered a managed control panel.

If your VPS came with cPanel/WHM, the control panel handles most of this hardening for you (CSF firewall pre-installed, Imunify360 etc.). If it’s a plain VPS, the rest of this guide applies.

Step 1: Change the root password (immediately)

The password in your welcome email has likely sat in your inbox. Even if your inbox is secure, change it on first login:

passwd

Use a strong unique password from your password manager. Better still, the next step makes the password less critical anyway.

Step 2: Set up SSH key authentication, disable password login

Eliminates the entire brute-force attack class. Full guide at SSH key authentication; condensed version:

  1. On your local machine: ssh-keygen -t ed25519 -C "your@email.com"
  2. Copy your public key to the VPS: ssh-copy-id root@your-vps-ip (Or manually paste it into ~/.ssh/authorized_keys on the server.)
  3. Test key login in a NEW terminal: ssh root@your-vps-ip — should connect without password prompt.
  4. Edit /etc/ssh/sshd_config:
    • PasswordAuthentication no
    • PermitRootLogin prohibit-password
  5. systemctl reload sshd

Keep your original SSH session open until you’ve verified the new config from a second terminal. If something breaks, the original session is your lifeline.

Step 3: Update the system

Fresh OS images often lag behind current patches.

Ubuntu / Debian:

apt update && apt upgrade -y

AlmaLinux / CentOS / Rocky:

dnf update -y
# or on older versions:
yum update -y

Reboot if kernel updated: reboot.

Step 4: Enable automatic security updates

Servers attacked through old vulnerabilities are servers nobody updated. Auto-updates close that window.

Ubuntu:

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

AlmaLinux/Rocky:

dnf install dnf-automatic -y
systemctl enable --now dnf-automatic.timer

Edit /etc/dnf/automatic.conf to set apply_updates = yes if you want unattended application of security updates (recommended for security-only).

Step 5: Install and configure a firewall

Default policy: deny everything inbound, allow specific ports. The lighter-weight option is UFW; the comprehensive option is CSF.

UFW (Ubuntu/Debian, simpler)

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp        # SSH
ufw allow 80/tcp        # HTTP
ufw allow 443/tcp       # HTTPS
ufw enable
ufw status verbose

CSF (RHEL family or where you want more features)

cd /usr/src
wget https://download.configserver.com/csf.tgz
tar -xzf csf.tgz
cd csf
sh install.sh

Then edit /etc/csf/csf.conf:

  • Set TESTING = "0" when ready (testing mode flushes rules every 5 min).
  • Verify TCP_IN includes your ports (80, 443, 22, mail ports if used).
  • Verify TCP_OUT is permissive enough for outbound (default usually OK).
csf -r

Open only the ports you actually need. SSH (22 or custom), HTTP (80), HTTPS (443). Mail ports if running mail (25, 465, 587, 993, 995). Database ports (3306, 5432) should stay closed unless specifically needed remotely.

Step 6: Install fail2ban

Auto-bans IPs after failed login attempts.

apt install fail2ban -y   # or dnf install fail2ban -y
systemctl enable --now fail2ban

Default config protects SSH out of the box. To extend to other services, copy /etc/fail2ban/jail.conf to jail.local and enable relevant sections (nginx-http-auth, postfix-sasl, etc.).

Step 7: Disable unused services

Default OS images run services you don’t need. Audit:

systemctl list-unit-files --state=enabled --type=service
ss -tlnp        # See what's listening on what port

For each service you don’t need (rpcbind, cups, avahi-daemon often unused on servers):

systemctl disable --now <service-name>

Less attack surface = fewer things to keep patched and secure.

Step 8: Create a non-root user for daily work

Don’t operate as root for everything. Create a regular user, give sudo:

adduser yourname
usermod -aG sudo yourname        # Ubuntu/Debian
# OR
usermod -aG wheel yourname        # RHEL family

Copy your SSH public key to the new user:

mkdir -p /home/yourname/.ssh
cp ~/.ssh/authorized_keys /home/yourname/.ssh/
chown -R yourname:yourname /home/yourname/.ssh
chmod 700 /home/yourname/.ssh
chmod 600 /home/yourname/.ssh/authorized_keys

Test: ssh yourname@your-vps-ip. Once working, you can disable root SSH entirely in sshd_config by setting PermitRootLogin no.

Step 9: Set up basic monitoring

You can’t fix what you can’t see. Minimum:

  • uptime monitoring — UptimeRobot (free) pings your server every 5 minutes, alerts on down.
  • resource monitoring — installed Netdata (free) or paid services like New Relic, DataDog for ongoing CPU/memory/disk graphs.
  • log review — at minimum, periodically check /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL) for unusual access patterns.

Step 10: Document what you did

Write down: SSH port, firewall rules, users created, anything custom. In 6 months you’ll thank yourself for this two-minute investment. A simple /root/setup-notes.txt is fine.

Optional but useful

  • Change SSH port from 22. Reduces bot noise dramatically (most scanners check 22 only). Use any port 1024-65535. Update firewall rules accordingly.
  • Set up Snort or Suricata for intrusion detection (advanced).
  • Configure log rotation via logrotate if your apps generate large logs.
  • Set system locale and timezone: timedatectl set-timezone Region/City.
  • Set hostname properly: hostnamectl set-hostname server01.yourdomain.com.

Common issues during hardening

“Locked myself out via SSH config change.” Use the VPS provider’s web console / VNC to log in directly, fix sshd_config, restart SSH. Always test from a second terminal before closing the working session.

“Firewall blocking my own access after enabling.” If you ran ufw enable without first allowing SSH, you’re locked out. Use web console to fix.

“fail2ban banned my own IP.” Happens when configuring services. Use the VPS web console to log in and unban: fail2ban-client set sshd unbanip your-ip. Or add your home IP to the ignore list in fail2ban config.

“Updates broke a service.” Rare for security updates. Rollback if needed: apt install package-name=specific-version. Document which versions you reverted.

What’s next

An hour of hardening at the start beats a week of recovery later. Run through this checklist once on every new VPS — by the time you deploy your application, the attack surface is already minimized and the basic defenses are in place.

Was this helpful?