How to Secure a New Linux VPS

When you provision a new Linux VPS, it arrives in a minimal but not fully secured state. Before deploying any applications, you should harden the server against common attack vectors. This guide covers the essential security steps that every server administrator should implement.
Step 1: Update the Operating System
The first step after connecting to a new server is updating all packages to their latest versions. This ensures you have the most recent security patches.
On Ubuntu/Debian: sudo apt update && sudo apt upgrade -y
On CentOS/AlmaLinux: sudo dnf update -y
Enable automatic security updates for unattended patching. On Ubuntu, the unattended-upgrades package handles this automatically. On CentOS, use dnf-automatic.
Step 2: Create a Non-Root User
Using the root account for daily operations is a security risk. Root has unrestricted access to the entire system, so any mistake or compromise has maximum impact.
Create a regular user with sudo privileges: sudo adduser admin sudo usermod -aG sudo admin (Ubuntu) or sudo usermod -aG wheel admin (CentOS)
Switch to the new user and verify sudo access: su - admin sudo whoami (should return root)
From this point, use this user for all server operations instead of root.
Step 3: Configure SSH Key Authentication
SSH keys are significantly more secure than passwords. They use cryptographic key pairs that cannot be brute-forced in the same way as passwords.
On your local machine, generate an SSH key pair: ssh-keygen -t ed25519 -C [email protected]
Copy the public key to the server: ssh-copy-id admin@your-server-ip
Test that key-based login works before disabling password authentication.
Step 4: Harden SSH Configuration
Edit /etc/ssh/sshd_config to apply these security settings:
- Set PermitRootLogin to no (prevents direct root login)
- Set PasswordAuthentication to no (enforces key-based authentication)
- Set PubkeyAuthentication to yes
- Change the SSH port from 22 to a non-standard port (optional, reduces automated scan noise)
- Set MaxAuthTries to 3
- Set ClientAliveInterval to 300 and ClientAliveCountMax to 2
After making changes, restart the SSH service: sudo systemctl restart sshd
IMPORTANT: Before disabling password authentication, verify that SSH key login works correctly. Getting locked out of your server is a serious operational risk.
Step 5: Configure the Firewall
A firewall controls which network ports are accessible from the internet. The principle of least privilege applies: only open ports that your applications actually need.
Using UFW (Ubuntu): sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh (or your custom SSH port) sudo ufw allow http sudo ufw allow https sudo ufw enable
Using firewalld (CentOS): sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload
Only open database ports (PostgreSQL 5432, MySQL 3306) if remote database access is required. Prefer connecting to databases through SSH tunnels or private networks.
Step 6: Install and Configure fail2ban
fail2ban monitors log files for repeated failed login attempts and automatically blocks offending IP addresses. This protects against brute-force attacks.
Install: sudo apt install fail2ban (Ubuntu) or sudo dnf install fail2ban (CentOS)
Enable and start: sudo systemctl enable fail2ban && sudo systemctl start fail2ban
The default configuration protects SSH. Customize the ban time and max retry settings in /etc/fail2ban/jail.local.
Step 7: Set Up Automatic Updates
Configure automatic security updates to ensure critical patches are applied promptly.
Ubuntu: sudo apt install unattended-upgrades && sudo dpkg-reconfigure unattended-upgrades
CentOS: sudo dnf install dnf-automatic && sudo systemctl enable --now dnf-automatic-install.timer
Automatic updates handle security patches without requiring manual intervention. Review the update logs periodically to verify patches are being applied.
Step 8: Configure Time Synchronization
Accurate system time is essential for log analysis, SSL certificate validation, and security audit trails.
Install and enable NTP: sudo apt install chrony (or verify systemd-timesyncd is active)
Verify time synchronization: timedatectl status
Step 9: Set Up Logging and Monitoring
Centralized logging helps detect security incidents and troubleshoot issues.
Verify that rsyslog is running and forwarding logs appropriately. Configure log rotation to prevent disk space exhaustion.
Consider setting up a monitoring solution that alerts you to: - High CPU or memory usage - Disk space running low - Unusual login patterns - Service failures - Network connectivity issues
Step 10: Disable Unused Services
Every running service is a potential attack surface. Disable services you do not need:
List running services: systemctl list-units --type=service --state=running
Disable unnecessary services: sudo systemctl disable --now service-name
Common services to evaluate: - cups (printing service, rarely needed on a server) - avahi (mDNS, usually not needed) - bluetooth (not relevant for servers)
Step 11: Configure File Permissions
Ensure proper file permissions on sensitive files: - SSH configuration: chmod 600 ~/.ssh/authorized_keys - Private keys: chmod 600 ~/.ssh/id_* - Web application files: owned by the appropriate service user, not root
Step 12: Set Up Backups
Configure automated backups from the start. Backups are your last line of defense against data loss from hardware failure, accidental deletion, or security incidents.
A good backup strategy includes: - Regular automated backups (daily for databases, weekly for file systems) - Offsite backup storage (not on the same server) - Regular backup restoration testing - Encrypted backup storage
Conclusion
Server security is not a one-time task but an ongoing practice. The steps above establish a strong security baseline for a new Linux VPS. Continue monitoring, updating, and reviewing your security configuration as your infrastructure evolves. A well-secured server protects both your applications and your users' data.