VPS Setup
Overview
This guide covers the initial security setup for a fresh VPS. A new VPS typically comes with password authentication enabled and no protection against attacks. We’ll secure it by:
- Setting up SSH key authentication (more secure than passwords)
- Configuring automatic security updates (keeps the system patched)
- Installing Fail2Ban (blocks brute-force attacks)
After completing this guide, your VPS will have a solid security foundation for hosting services.
Prerequisites
- A VPS running Ubuntu Server (commands should be similar on other Debian-based distributions)
- Root or sudo access
- SSH client on your local machine (Terminal on macOS/Linux, or Windows Terminal)
SSH Setup
SSH keys are more secure than passwords because they can’t be guessed or brute-forced. The key pair consists of a private key (stays on your machine) and a public key (goes on the server).
Generate a Key Pair
On your local machine, generate an ed25519 key:
ssh-keygen -t ed25519
Press Enter to accept the default location. Optionally set a passphrase for extra security.
This creates two files:
~/.ssh/id_ed25519- your private key (never share this)~/.ssh/id_ed25519.pub- your public key (safe to share)
Copy the Public Key to VPS
ssh-copy-id <username>@<vps-ip>
This appends your public key to the server’s ~/.ssh/authorized_keys file. You’ll need to enter your password one last time.
Configure SSH Client
Add this to ~/.ssh/config on your local machine to simplify connections:
Host *
AddKeysToAgent yes
IdentitiesOnly yes
ServerAliveInterval 60
IdentityFile ~/.ssh/id_ed25519
# UseKeychain yes # macOS only
Host github.com
HostName github.com
User git
Host vps
HostName <vps-ip>
User <username>
Port 22
| Setting | Purpose |
|---|---|
AddKeysToAgent yes | Automatically add keys to SSH agent |
IdentitiesOnly yes | Only use explicitly configured keys |
ServerAliveInterval 60 | Send keepalive every 60 seconds to prevent disconnection |
IdentityFile | Path to your private key |
Now you can connect with just:
ssh vps
No password needed. Root login should be disabled and key-only authentication enabled on the server.
Timezone
Set the server timezone so logs show the correct local time:
sudo timedatectl set-timezone Asia/Jakarta
Verify with:
timedatectl
Replace Asia/Jakarta with your timezone. List available timezones with timedatectl list-timezones.
Auto Security Updates
Security vulnerabilities are discovered regularly. Unattended-upgrades automatically installs security patches so you don’t have to manually update.
Install and configure:
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Select “Yes” when prompted to enable automatic updates.
The system will now:
- Check for security updates daily
- Install them automatically
- Keep your system patched without intervention
Configuration (Optional)
Config file location: /etc/apt/apt.conf.d/50unattended-upgrades
To enable automatic reboots when required (e.g., kernel updates), add:
Unattended-Upgrade::Automatic-Reboot "true";
View update logs at: /var/log/unattended-upgrades/unattended-upgrades.log
Fail2Ban
Fail2Ban monitors log files for failed login attempts. When it detects repeated failures from an IP address, it bans that IP by adding a firewall rule.
This protects against brute-force SSH attacks where attackers try thousands of password combinations.
Install and Enable
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Check Status
View all active jails:
sudo fail2ban-client status
View SSH jail specifically (shows banned IPs):
sudo fail2ban-client status sshd
Unban an IP
If you accidentally get banned (e.g., too many failed logins):
sudo fail2ban-client set sshd unbanip <ip>
Custom Settings (Optional)
The default settings work well for most cases. To customize, create a local config:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
| Setting | Default | Description |
|---|---|---|
maxretry | 5 | Number of failures before ban |
bantime | 10m | How long the ban lasts |
findtime | 10m | Time window for counting failures |
Example: With defaults, 5 failed logins within 10 minutes triggers a 10-minute ban.
SSH jail (sshd) is enabled by default - no extra configuration needed.