Securing an unmanaged VPS is a critical task, as you are solely responsible for its protection. Neglecting security can lead to data breaches, website defacement, DDoS attacks, and your server being used for malicious activities. This guide provides a step-by-step approach to securing your unmanaged Linux VPS.
Disclaimer: Security is an ongoing process, not a one-time setup. This guide covers essential steps, but continuous monitoring, updates, and vigilance are crucial.
Prerequisites:
- An unmanaged Linux VPS (Ubuntu, Debian, CentOS, AlmaLinux, Rocky Linux are common).
- SSH client (PuTTY/MobaXterm for Windows, Terminal for macOS/Linux).
- Basic command-line familiarity.
- Crucially, a working internet connection.
Step 1: Initial Login and Immediate Actions
-
Login as Root (Initially): Use the IP address and root password provided by your VPS host.
Bashssh root@your_vps_ip_address
If you get a security warning about the host key, accept it.
-
Change Root Password: If your provider gave you a temporary password, change it immediately to a strong, unique one.
Bashpasswd
Enter the new password twice. Use a mix of uppercase, lowercase, numbers, and symbols.
-
Update All System Packages: This patches known vulnerabilities in the operating system and installed software.
- Ubuntu/Debian:
Bash
sudo apt update sudo apt upgrade -y
- CentOS/AlmaLinux/Rocky Linux:
Bash
sudo yum update -y # Or for newer versions: sudo dnf update -y
Reboot if the kernel was updated:
Bashsudo reboot
You’ll be disconnected; wait a minute or two and then reconnect.
- Ubuntu/Debian:
Step 2: Create a New Sudo User and Secure SSH
This is fundamental for daily operations and significantly reduces the risk of direct root compromises.
-
Create a New Standard User: Choose a strong username.
- Ubuntu/Debian:
Bash
adduser your_username
Follow the prompts to set a strong password and optional user information.
- CentOS/AlmaLinux/Rocky Linux:
Bash
useradd your_username passwd your_username # Set the password for the new user
Follow the prompts.
- Ubuntu/Debian:
-
Grant Sudo Privileges to the New User: This allows
your_username
to execute commands with administrative privileges when needed.- Ubuntu/Debian:
Bash
usermod -aG sudo your_username
- CentOS/AlmaLinux/Rocky Linux:
Bash
usermod -aG wheel your_username
- Ubuntu/Debian:
-
Test the New User Login: Crucially, open a NEW SSH session (do not close the root session yet). Log in with your new user:
Bashssh your_username@your_vps_ip_address
Verify
sudo
access by trying a simple command:Bashsudo apt update # Ubuntu/Debian sudo yum update # CentOS/AlmaLinux/Rocky Linux
It should ask for your
your_username
‘s password. If this works, you’re good. -
Disable Root SSH Login: This prevents brute-force attacks directly on the root account.
- From your new
sudo
user’s session:Bashsudo nano /etc/ssh/sshd_config
- Find the line
PermitRootLogin yes
and change it to:PermitRootLogin no
- Save and exit (Ctrl+X, Y, Enter for nano).
- Restart the SSH service to apply changes:
Bash
sudo systemctl restart sshd
- Now you can close the root SSH session. From now on, you will always log in as
your_username
.
- From your new
-
Set Up SSH Key Authentication (Highly Recommended): This is much more secure than passwords, as it uses cryptographic keys.
- Generate an SSH Key Pair (on your local machine):
- macOS/Linux:
Bash
ssh-keygen -t rsa -b 4096
Follow prompts (press Enter for default location, optionally set a passphrase for extra security).
- Windows (PuTTYgen for PuTTY users): Open PuTTYgen, click “Generate,” move your mouse randomly, then save both public (
id_rsa.pub
) and private (id_rsa.ppk
) keys.
- macOS/Linux:
- Copy Public Key to VPS:
- macOS/Linux:
Bash
ssh-copy-id your_username@your_vps_ip_address
Enter your
your_username
‘s password when prompted. - Windows (PuTTY/manual):
- Connect to your VPS with your password as
your_username
. - Create the
.ssh
directory andauthorized_keys
file if they don’t exist:Bashmkdir -p ~/.ssh chmod 700 ~/.ssh touch ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
- Open your locally saved
id_rsa.pub
file (the public key) with a text editor. Copy its entire content. - On your VPS, edit the
authorized_keys
file:Bashnano ~/.ssh/authorized_keys
- Paste your public key into this file. Save and exit.
- Connect to your VPS with your password as
- macOS/Linux:
- Disable Password Authentication (Optional but Recommended): Once you can log in using your SSH key, disable password logins for even greater security.
- Login to your VPS via SSH key.
- Edit
sshd_config
again:Bashsudo nano /etc/ssh/sshd_config
- Find
PasswordAuthentication yes
and change it to:PasswordAuthentication no
- Save and exit. Restart SSH service:
Bash
sudo systemctl restart sshd
- Crucially, test this again! Open a new SSH session and try to log in with your SSH key. If it works, try to log in with just your password (it should fail). If it doesn’t work with the key, re-enable
PasswordAuthentication yes
and troubleshoot.
- Generate an SSH Key Pair (on your local machine):
Step 3: Configure a Firewall
A firewall is your server’s first line of defense, blocking unwanted traffic.
-
For Ubuntu/Debian (UFW – Uncomplicated Firewall):
Bashsudo apt install ufw -y # Install if not present sudo ufw allow OpenSSH # Allow SSH (port 22) - ESSENTIAL, so you don't lock yourself out sudo ufw default deny incoming # Deny all other incoming by default sudo ufw default allow outgoing # Allow all outgoing sudo ufw enable # Enable the firewall sudo ufw status verbose # Check status
- Open ports for services you run:
- HTTP (web server):
sudo ufw allow http
orsudo ufw allow 80
- HTTPS (SSL web server):
sudo ufw allow https
orsudo ufw allow 443
- FTP (if used):
sudo ufw allow 21/tcp
(and possibly passive ports) – Avoid FTP if possible, use SFTP. - MySQL (if accessed remotely):
sudo ufw allow mysql
orsudo ufw allow 3306
– Only if truly necessary, restrict by IP if possible.
- HTTP (web server):
- Open ports for services you run:
-
For CentOS/AlmaLinux/Rocky Linux (firewalld):
Bashsudo systemctl enable firewalld --now # Enable and start sudo firewall-cmd --permanent --add-service=ssh # Allow SSH sudo firewall-cmd --permanent --add-service=http # Allow HTTP sudo firewall-cmd --permanent --add-service=https # Allow HTTPS sudo firewall-cmd --reload # Apply changes sudo firewall-cmd --list-all # Check status
- Open other ports as needed (e.g., MySQL if accessed remotely):
Bash
sudo firewall-cmd --permanent --add-port=3306/tcp sudo firewall-cmd --reload
- Open other ports as needed (e.g., MySQL if accessed remotely):
Step 4: Install and Configure Fail2Ban
Fail2Ban monitors logs for suspicious activity (like repeated failed login attempts) and automatically bans the offending IP addresses for a set period.
-
Install Fail2Ban:
- Ubuntu/Debian:
Bash
sudo apt install fail2ban -y
- CentOS/AlmaLinux/Rocky Linux:
Bash
sudo yum install epel-release -y sudo yum install fail2ban fail2ban-systemd -y # For CentOS 7+
- Ubuntu/Debian:
-
Configure Fail2Ban: Create a local configuration file to override defaults without directly modifying the main config.
Bashsudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo nano /etc/fail2ban/jail.local
- Find and modify the
[sshd]
section (or create it if missing for some reason):- Ensure
enabled = true
- Consider setting
bantime
(e.g.,bantime = 1h
for 1 hour ban) - Consider setting
maxretry
(e.g.,maxretry = 3
for 3 failed attempts)
- Ensure
- Add your IP address to
ignoreip
to prevent yourself from being banned (e.g.,ignoreip = 127.0.0.1 ::1 your_local_ip_address
). - Save and exit.
- Find and modify the
-
Start and Enable Fail2Ban:
Bashsudo systemctl start fail2ban sudo systemctl enable fail2ban sudo systemctl status fail2ban # Check status
You can check banned IPs with
sudo fail2ban-client status sshd
.
Step 5: Install and Configure Automated Updates (Highly Recommended)
While you’ve manually updated, setting up automatic security updates is crucial.
-
Ubuntu/Debian (Unattended Upgrades):
Bashsudo apt install unattended-upgrades -y sudo dpkg-reconfigure --priority=low unattended-upgrades
Follow the prompts. It’s usually safe to enable automatic security updates. You can also edit
/etc/apt/apt.conf.d/50unattended-upgrades
to customize. -
CentOS/AlmaLinux/Rocky Linux (dnf-automatic or yum-cron):
- For dnf-automatic (newer CentOS/AlmaLinux/Rocky Linux):
Bash
sudo dnf install dnf-automatic -y sudo nano /etc/dnf/automatic.conf
Edit
apply_updates = yes
andemit_via = email
(or other methods).Bashsudo systemctl enable dnf-automatic.timer --now
- For yum-cron (older CentOS/RHEL):
Bash
sudo yum install yum-cron -y sudo nano /etc/yum/yum-cron.conf
Set
apply_updates = yes
andemail_to
if you want email notifications.Bashsudo systemctl start yum-cron sudo systemctl enable yum-cron
- For dnf-automatic (newer CentOS/AlmaLinux/Rocky Linux):
Step 6: Regular Backups
This is not a security measure per se, but it’s your last line of defense against data loss due to successful attacks, accidental deletion, or hardware failure.
- VPS Provider Backups: Many providers offer automated backup services for an extra fee. This is often the easiest option.
- Manual Backups:
tar
for archiving files:sudo tar -czvf /backup/website_backup.tar.gz /var/www/html
mysqldump
for databases:sudo mysqldump -u root -p database_name > /backup/database_name.sql
- Automated Backup Scripts: Write a script to automate
tar
andmysqldump
, then schedule it withcron
. - Offsite Storage: Always store backups off your VPS (e.g., Google Drive, Amazon S3, Dropbox, another server). Use
rsync
orscp
to transfer.
Step 7: Basic Malware and Rootkit Scanning
Tools to periodically check for malicious software.
- ClamAV (Antivirus):
Bash
sudo apt install clamav clamav-daemon -y # Ubuntu/Debian sudo yum install epel-release -y && sudo yum install clamav clamd -y # CentOS/AlmaLinux/Rocky Linux sudo freshclam # Update virus definitions sudo clamscan -r -i / # Scan entire system (can take a long time)
- Chkrootkit (Rootkit Scanner):
Bash
sudo apt install chkrootkit -y # Ubuntu/Debian sudo yum install chkrootkit -y # CentOS/AlmaLinux/Rocky Linux (may need EPEL) sudo chkrootkit
- Rootkit Hunter (rkhunter):
Bash
sudo apt install rkhunter -y # Ubuntu/Debian sudo yum install rkhunter -y # CentOS/AlmaLinux/Rocky Linux (may need EPEL) sudo rkhunter --update sudo rkhunter --check
These tools are for scanning, not real-time protection. Run them periodically.
Step 8: Keep Services and Software Updated and Secure
- Web Server (Apache/Nginx):
- Keep it updated.
- Configure it for security (e.g., disable unused modules, set appropriate permissions for web root, disable directory listings, use
mod_security
for Apache or equivalent for Nginx).
- Database Server (MySQL/MariaDB/PostgreSQL):
- Keep it updated.
- Run
mysql_secure_installation
if using MySQL/MariaDB. - Use strong, unique passwords for database users.
- Restrict database access to
localhost
if possible (only allow your web server to connect). If remote access is needed, use firewall rules to limit by source IP.
- PHP (if used):
- Use the latest stable PHP version.
- Disable dangerous functions in
php.ini
(e.g.,disable_functions = exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source
). - Set
expose_php = Off
.
- Application Security:
- If running CMS like WordPress, keep core, themes, and plugins updated. Use strong passwords for admin accounts.
- Regularly audit code for custom applications.
Step 9: Log Monitoring
- Regularly check system logs for unusual activity.
journalctl -u sshd
(SSH logs)tail -f /var/log/auth.log
(Ubuntu/Debian authentication logs)tail -f /var/log/secure
(CentOS/AlmaLinux/Rocky Linux authentication logs)- Web server access and error logs (e.g.,
/var/log/apache2/access.log
,/var/log/nginx/error.log
).
- Consider using a log management tool (e.g., ELK Stack, Splunk, Graylog) for larger setups.
Step 10: General Best Practices
- Use Strong, Unique Passwords: For all accounts and services.
- Principle of Least Privilege: Grant users and services only the minimum permissions they need to function.
- Remove Unused Services/Software: Reduces the attack surface.
- Stay Informed: Follow security news, especially for your OS and applications.
- Perform Regular Audits: Periodically review your server’s security configurations.
Securing an unmanaged VPS is an ongoing commitment. By following these steps, you’ll establish a strong security foundation for your server, but remember to stay proactive and adapt as new threats emerge.