A fresh VPS comes with root access open to the internet. These six steps take about ten minutes and apply to both families we run: Ubuntu and Debian use apt and ufw; AlmaLinux, Rocky, and other RHEL-based distros use dnf and firewalld.
1. Log in and update all packages
Your OS image was built before today's security patches existed, so update first.
$ ssh [email protected]
$ apt update && apt -y upgrade$ dnf -y upgradeIf the upgrade installed a new kernel, run reboot now and log in again.
2. Create a non-root user with sudo
When you work as root all the time, every mistake has full system access. A sudo user limits the damage and keeps a record of the commands you run.
$ adduser deploy $ usermod -aG sudo deploy
$ useradd -m deploy $ passwd deploy $ usermod -aG wheel deploy
3. Add your SSH key and disable password and root login
Keys cannot be guessed the way passwords can, and root should never be a remote login target.
# skip ssh-keygen if you already have a key $ ssh-keygen -t ed25519 $ ssh-copy-id [email protected] $ ssh [email protected]
When key login works, edit the SSH config and set:
PermitRootLogin no PasswordAuthentication no
Cloud images often override this file
Check /etc/ssh/sshd_config.d/ for extra config files (such as 50-cloud-init.conf) that set PasswordAuthentication. These files override the main file, so fix those lines too.
Do not lock yourself out before restarting SSH
Keep your current session open, restart SSH, then check that key-only login works from a second terminal. If it fails, you still have an open session to undo the change.
$ sudo systemctl restart ssh$ sudo systemctl restart sshdWork as your new user from here on.
4. Turn on the firewall
With default deny, a service you forgot about is not reachable from the internet.
$ sudo apt install -y ufw $ sudo ufw allow OpenSSH $ sudo ufw enable
$ sudo systemctl enable --now firewalld $ sudo firewall-cmd --permanent --add-service=ssh $ sudo firewall-cmd --reload
When you set up a web stack later, open ports 80 and 443 the same way. Our firewall guide covers the details.
5. Add fail2ban
fail2ban bans IPs that fail SSH logins again and again. This stops most brute force attempts and keeps your auth logs readable.
$ sudo apt install -y fail2ban$ sudo dnf install -y epel-release $ sudo dnf install -y fail2ban
Enable the SSH jail, then start the service:
[sshd] enabled = true
$ sudo systemctl enable --now fail2ban $ sudo fail2ban-client status sshd
6. Enable automatic security updates
Security patches should install even when you are not logging in to the server.
$ sudo apt install -y unattended-upgrades $ sudo dpkg-reconfigure -plow unattended-upgrades
$ sudo dnf install -y dnf-automaticOn RHEL-based systems, set these two lines, then enable the timer:
upgrade_type = security apply_updates = yes
$ sudo systemctl enable --now dnf-automatic.timerQuick reference
| Step | Ubuntu and Debian | RHEL-based |
|---|---|---|
| Update packages | apt update && apt -y upgrade | dnf -y upgrade |
| Sudo user | adduser + usermod -aG sudo | useradd + passwd + usermod -aG wheel |
| SSH service name | ssh | sshd |
| Firewall | ufw | firewalld |
| fail2ban | apt install fail2ban | epel-release first, then dnf install fail2ban |
| Auto updates | unattended-upgrades | dnf-automatic |
Where to go next
With this base done, point your DNS at the server, install your stack, and set up off-site backups. Take a snapshot before any big change. You can find stack-specific guides in the rest of the Resources section, and if you get stuck, open a ticket.