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_addressIf 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.
BashpasswdEnter 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 rebootYou’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_usernameFollow 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 userFollow the prompts.
- Ubuntu/Debian:
-
Grant Sudo Privileges to the New User: This allows
your_usernameto 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_addressVerify
sudoaccess by trying a simple command:Bashsudo apt update # Ubuntu/Debian sudo yum update # CentOS/AlmaLinux/Rocky LinuxIt 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
sudouser’s session:Bashsudo nano /etc/ssh/sshd_config - Find the line
PermitRootLogin yesand 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 4096Follow 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_addressEnter your
your_username‘s password when prompted. - Windows (PuTTY/manual):
- Connect to your VPS with your password as
your_username. - Create the
.sshdirectory andauthorized_keysfile 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.pubfile (the public key) with a text editor. Copy its entire content. - On your VPS, edit the
authorized_keysfile: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_configagain:Bashsudo nano /etc/ssh/sshd_config - Find
PasswordAuthentication yesand 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 yesand 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 httporsudo ufw allow 80 - HTTPS (SSL web server):
sudo ufw allow httpsorsudo 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 mysqlorsudo 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 = 1hfor 1 hour ban) - Consider setting
maxretry(e.g.,maxretry = 3for 3 failed attempts)
- Ensure
- Add your IP address to
ignoreipto 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 statusYou 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-upgradesFollow the prompts. It’s usually safe to enable automatic security updates. You can also edit
/etc/apt/apt.conf.d/50unattended-upgradesto 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.confEdit
apply_updates = yesandemit_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.confSet
apply_updates = yesandemail_toif 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:
tarfor archiving files:sudo tar -czvf /backup/website_backup.tar.gz /var/www/htmlmysqldumpfor databases:sudo mysqldump -u root -p database_name > /backup/database_name.sql
- Automated Backup Scripts: Write a script to automate
tarandmysqldump, then schedule it withcron. - Offsite Storage: Always store backups off your VPS (e.g., Google Drive, Amazon S3, Dropbox, another server). Use
rsyncorscpto 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 --checkThese 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_securityfor Apache or equivalent for Nginx).
- Database Server (MySQL/MariaDB/PostgreSQL):
- Keep it updated.
- Run
mysql_secure_installationif using MySQL/MariaDB. - Use strong, unique passwords for database users.
- Restrict database access to
localhostif 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.







