Basic VPS Security Setup You Must Do Immediately After Launching Your Server for the First Time
You've purchased a VPS, logged in for the first time, and installed a web server. Many people stop there, but that's a critical mistake. This article covers the fundamental security steps you should perform before anything else.
1. Change SSH Port from 22
Port 22 is SSH's default, and bots worldwide scan and attempt password guesses 24/7. Changing the port won't make your server 100% secure, but it significantly reduces noise from automated attacks.
nano /etc/ssh/sshd_config
# Change line: Port 22 → Port 2222
systemctl restart sshd
Then open the new port in your firewall before logging out, or you'll be locked out of the server.
2. Disable Direct Root Login
Create a new user and give them sudo privileges instead.
adduser myuser
usermod -aG sudo myuser
Then edit sshd_config:
PermitRootLogin no
3. Use SSH Keys Instead of Passwords
Passwords, even if complex, can be brute-forced. SSH keys are more secure because they use cryptographic key pairs.
On your local machine:
ssh-keygen -t ed25519 -C "my-vps-key"
ssh-copy-id -p 2222 myuser@your-server-ip
After testing login with the key, disable password authentication:
PasswordAuthentication no
4. Set Up Firewall with UFW
apt install ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 2222/tcp # New SSH port
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable
5. Install Fail2ban
Fail2ban automatically bans IP addresses that fail login attempts repeatedly.
apt install fail2ban
systemctl enable fail2ban
systemctl start fail2ban
Check status:
fail2ban-client status sshd
6. Update Packages Regularly
apt update && apt upgrade -y
Set up unattended-upgrades to apply security patches automatically:
apt install unattended-upgrades
dpkg-reconfigure unattended-upgrades
Things You Should Not Do
- Use the provider's default password (usually weak or easily brute-forced)
- Open port 3306 (MySQL) or 5432 (PostgreSQL) directly to the internet
- Install PhpMyAdmin at the default path
/phpmyadmin— bots will find it immediately - Leave the root password as provided by the provider — change it immediately
- Open all ports in UFW with "allow all" and disable later (reverse the approach: deny all first, then allow only what's needed)
7. Monitor Logs for Suspicious Activity
Even after hardening, you should periodically check logs for anomalies:
# View recent failed login attempts
journalctl -u sshd | grep "Failed\|Invalid\|error" | tail -20
# View IPs banned by Fail2ban
fail2ban-client status sshd
# View auth log
tail -50 /var/log/auth.log | grep -i "fail\|invalid\|error"
# View all running processes, look for anything unusual
ps aux --sort=-%cpu | head -20
logwatch to receive a daily log summary via email automatically. You won't need to SSH in and check logs manually every day.8. Security Headers for Web Server
If you're running a web service, add security headers to Nginx or Apache:
# In Nginx server block
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
Check security headers using dnsxray.com — free, single page scan.
Common Issues & Troubleshooting
SSH Won't Accept Key and Still Asks for Password
The issue is usually incorrect file permissions:
# Check permissions
ls -la ~/.ssh/
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Check SSH log for errors
journalctl -u sshd -n 30
After Enabling UFW, SSH is Unreachable and I Can't Connect
You must allow SSH port before enabling UFW. If this happens, use your provider's console (KVM console, VNC, SolusVM) to access the server and fix it:
ufw allow 2222/tcp # Or your SSH port
ufw status # Check before enabling
ufw enable # Enable last
Fail2ban Isn't Banning IPs Even After Multiple Failed Logins
Check the log path and jail backend:
fail2ban-client status
# If jail appears greyed out (not active), investigate
tail -50 /var/log/fail2ban.log
# Restart
systemctl restart fail2ban
fail2ban-client status sshd
Unattended-upgrades Reboots Services in the Middle of the Night
This is normal behavior, but if you don't want automatic reboots, modify the config:
nano /etc/apt/apt.conf.d/50unattended-upgrades
# Change Unattended-Upgrade::Automatic-Reboot "true" to "false"
Frequently Asked Questions
Should I Always Change SSH Port from 22?
It's a good practice, but not strictly necessary if you have Fail2ban and key-based authentication already enabled. Changing the port reduces noise from bot scans but doesn't significantly increase security against determined attackers who can scan all ports. Focus more on key-based authentication and Fail2ban.
Do I Need 2FA for SSH?
Recommended if you want an extra security layer. Install Google Authenticator PAM, then set ChallengeResponseAuthentication yes and AuthenticationMethods publickey,keyboard-interactive in sshd_config to require both key and TOTP code.
My VPS Provider Offers Snapshots — Do I Still Need to Back Up?
Yes, back up separately. Provider snapshots are stored in the same datacenter. If the datacenter has an outage, both your VPS and snapshot may be lost. A good backup should be offsite — use rclone to sync to Cloudflare R2 or Backblaze B2.
Should I Disable IPv6?
Not necessary. UFW can manage IPv6. Verify IPV6=yes in /etc/default/ufw so rules apply to IPv6 as well. Disabling IPv6 entirely may break some applications.
Summary
VPS security isn't complicated, but you must do it from day one. Bots begin scanning within minutes of your server going online. These steps take less than 30 minutes but significantly reduce your attack surface.