After deploying a website to a VPS, many people experience a sense of relief, thinking "finally, it's all done," and then leave the server unattended. It's only when they receive a warning email about full CPU usage, log in to find several unfamiliar processes running, or their website is riddled with spam pages, that they realize security isn't something they can "think about later." This article compiles a basic VPS security settings checklist. Following this order will at least keep 80% of automated scans and script attacks at bay.
SSH Security Hardening: Guarding the First Line of Defense for Your Server
SSH is the default management portal for almost all VPSs and is also the most frequently brute-forced service. If you look at your VPS's SSH logs, you'll likely find thousands of failed login attempts from around the world every day—all from automated bots scanning.
Changing the Default Port
Changing the SSH port from 22 to another port is the most basic and effective defense. Many scanners only scan port 22; changing it will filter out the vast majority of automated attacks.
sudo vim /etc/ssh/sshd_config
Port 2222 #
sudo systemctl restart sshd
Important Reminder: Before changing the port, test whether the new port can be connected normally. Never close the current SSH session; otherwise, if the port is closed, you'll be locked out.
Disable Direct Root Login
Root is an account present in every Linux system. Attackers don't need to guess the username, they only need to crack the password. Disabling root login and logging in as a regular user to escalate privileges using sudo significantly improves security.
PermitRootLogin no
sudo -i
Log in using SSH keys and disable password verification.
Browsing passwords is the primary way SSH is compromised. Key-based login uses asymmetric encryption; the private key is not on the server, making it virtually impossible to crack by brute force.
Steps to generate a key pair:
ssh-keygen -t ed25519 -C "your_email@example.com"
Send the public key to the server:
ssh-copy-id -p 2222 username@your_server_ip
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
After confirming that the key can be used to log in successfully, disable password verification:
PasswordAuthentication no
PubkeyAuthentication yes
sudo systemctl restart sshd
Install Fail2ban to defend against brute-force attacks
Fail2ban can automatically monitor failed login attempts in the logs and temporarily block abnormal IPs.
sudo apt-get install fail2ban -y # Debian/Ubuntu
sudo yum install fail2ban -y # CentOS/RHEL
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo fail2ban-client status sshd
Firewall Configuration: Controlling Inbound and Outbound Traffic
A firewall is the foundation of VPS security. Properly configured rules can prevent unauthorized ports from being exposed to the public internet. Cloudflare reports that misconfigured ports and services are one of the leading causes of data breaches, so this step is highly recommended.
UFW Basic Configuration (for Ubuntu/Debian)
sudo apt-get install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 21/tcp
sudo ufw enable
sudo ufw status numbered
Firewalld basic configuration (for CentOS/RHEL)
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Port Opening Principles
The core principle of firewall configuration is minimal exposure: only open ports necessary for business operations, and close all other ports. Web servers typically only need to open ports 22/2222 (SSH), 80 (HTTP), and 443 (HTTPS). Database ports (such as 3306 and 5432) should ideally only listen on the internal network or be accessed through a whitelisted IP address, and should not be directly exposed to the public internet.
Regular Backups: The Last Line of Defense
All the previous security measures can be breached; only backups provide a guarantee of "recovery after an incident." A complete backup plan should at least include: regular execution, off-site storage, and verifiable recovery.
Database Backups
Databases are often more important than files. Example of a MySQL backup script:
#!/bin/bash
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_USER="your_db_user"
DB_PASS="your_db_password"
mkdir -p $BACKUP_DIR
mysqldump -u$DB_USER -p$DB_PASS --all-databases > $BACKUP_DIR/all_db_$DATE.sql
gzip $BACKUP_DIR/all_db_$DATE.sql
find $BACKUP_DIR -type f -mtime +7 -delete
PostgreSQL backup commands:
pg_dumpall -U postgres | gzip > /backup/pg_all_$(date +%Y%m%d).sql.gz
Website file backup
#!/bin/bash
BACKUP_DIR="/backup/www"
DATE=$(date +%Y%m%d)
WWW_DIR="/var/www"
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/www_$DATE.tar.gz $WWW_DIR
aws s3 sync $BACKUP_DIR s3://your-bucket-name/backups/
The only true test of a backup's validity is whether it can be restored. It's recommended to conduct a full recovery drill at least once per quarter to ensure backup files are usable and the recovery process is clear. Even experienced users have encountered recovery failures due to corrupted backup files or insufficient permissions; regular verification can prevent the same problems.
EN
CN