How to Secure Your Linux VPS — Clear, Safe Steps

How to Secure Your Linux VPS — Clear, Safe Steps

1. Why logging in as root is unsafe

The root account has full control. If its password is guessed via bruteforce, the attacker owns the server. Do not log in directly as root over SSH. Create a separate user and use sudo for admin tasks.

2. Create a non-root user

Create the user and grant admin privileges. Don’t disable password auth yet; you’ll switch to keys after confirming access works.

# Debian/Ubuntu
sudo adduser username
sudo usermod -aG sudo username

# AlmaLinux/Rocky
sudo useradd -m -s /bin/bash username
sudo passwd username
sudo usermod -aG wheel username

Log in with the new user (temporarily on port 22) to verify access:

ssh username@SERVER_IP -p 22

3. SSH key authentication (recommended)

Generate a key on your computer, copy it to the server, and test key-based login before disabling passwords.

# On your computer (client)
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/mh-vps-ed25519
ssh-copy-id -i ~/.ssh/mh-vps-ed25519.pub username@SERVER_IP

# Test key login (still on port 22)
ssh -i ~/.ssh/mh-vps-ed25519 username@SERVER_IP -p 22

If ssh-copy-id is unavailable, add the key manually:

# On the server (as username)
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo 'PUBLIC_KEY_CONTENT' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

4. Prepare the firewall (don’t change the SSH port yet)

Allow both the old port (22) and the new one (e.g., 2222), then enable the firewall. This prevents locking yourself out when you switch ports.

# Debian/Ubuntu — UFW
sudo apt update && sudo apt install -y ufw
sudo ufw allow 22/tcp comment 'SSH old'
sudo ufw allow 2222/tcp comment 'SSH new'
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw status verbose
# AlmaLinux/Rocky — firewalld (and SELinux)
sudo dnf install -y firewalld policycoreutils-python-utils
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh      # 22
sudo firewall-cmd --permanent --add-port=2222/tcp    # 2222
sudo firewall-cmd --reload

# If SELinux is Enforcing, register the new port for sshd
sudo semanage port -a -t ssh_port_t -p tcp 2222 2>/dev/null || sudo semanage port -m -t ssh_port_t -p tcp 2222
sestatus  # check SELinux state

5. Configure sshd — keep both ports temporarily

Edit OpenSSH. Keep Port 22 and add Port 2222 until you confirm access on the new port. Disable root login and passwords only after key login works.

sudoedit /etc/ssh/sshd_config   # or: sudo nano /etc/ssh/sshd_config

Add or update the following:

# Keep both ports until access on 2222 is confirmed
Port 22
Port 2222

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
# (optional) Restrict to your user only
# AllowUsers username

Validate syntax and apply without dropping active sessions (reload, not restart):

# Syntax check
sudo sshd -t && echo "OK"

# Debian/Ubuntu
sudo systemctl reload ssh
# AlmaLinux/Rocky
sudo systemctl reload sshd

Test the new port from a separate terminal:

ssh -i ~/.ssh/mh-vps-ed25519 username@SERVER_IP -p 2222

6. After 2222 works, disable 22

Once key login on 2222 works, remove port 22 from sshd and the firewall, then reload.

# In sshd_config: keep ONLY the new port
sudo sed -i 's/^Port 22/# Port 22 (disabled)/' /etc/ssh/sshd_config
# or edit manually and keep only: Port 2222

# Apply safely
# Debian/Ubuntu
sudo systemctl reload ssh
# AlmaLinux/Rocky
sudo systemctl reload sshd
# Debian/Ubuntu — close 22 in UFW
sudo ufw delete allow 22/tcp

# AlmaLinux/Rocky — close 22 in firewalld
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload

7. Verify listening ports

Confirm only the new port is open and SSH is listening on it.

sudo ss -tulpen | grep :2222

8. Bruteforce protection and automatic updates

Install fail2ban to block repeated attempts and enable automatic OS updates.

# Debian/Ubuntu — fail2ban + unattended upgrades
sudo apt install -y fail2ban unattended-upgrades

sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[sshd]
enabled = true
port    = 2222
maxretry = 5
findtime = 10m
bantime  = 1h
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

# Enable automatic security updates
sudo dpkg-reconfigure --priority=low unattended-upgrades
# AlmaLinux/Rocky — fail2ban + dnf-automatic
sudo dnf install -y epel-release
sudo dnf install -y fail2ban dnf-automatic

sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[sshd]
enabled = true
port    = 2222
maxretry = 5
findtime = 10m
bantime  = 1h
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

# Automatic updates
sudo sed -i 's/^apply_updates = .*/apply_updates = yes/' /etc/dnf/automatic.conf
sudo systemctl enable --now dnf-automatic.timer

9. More quick hardening tips

Disable or remove unused services (Telnet, FTP). Examples: sudo systemctl disable --now vsftpd, sudo apt remove -y telnetd / sudo dnf remove -y telnet-server.

Do not expose databases to the internet; bind to 127.0.0.1 or a private network only.

Schedule regular backups (files + databases) and test restores.

Use unique passwords + a password manager for non-SSH accounts (e.g., web apps).

10. Conclusion

Solid security means: a non-root user, SSH keys, a properly configured firewall, and a careful port migration (test first, then disable the old port). With fail2ban and automatic updates, you significantly reduce risk on any distro.

VPS How to

Recent posts