Bots keep trying to log in to every VPS. With these steps you make your Debian or Ubuntu VPS much safer. Follow them in this order.
Don't lock yourself out. Keep your current SSH window open while you work on SSH and the firewall. Test every change in a second window and only close the first one when that works.
Install updates
Log in as root as in Connect to your Linux VPS with SSH and install all updates:
apt update && apt upgrade
Confirm with Y. Then restart with reboot and log in again after a minute.
Your own user with sudo
Don't work as root: one typo then hits your whole server. Create a normal user and use sudo for admin tasks. Replace alex with the name you want:
apt install sudo
adduser alex
adduser alex sudo
adduser asks for a password twice and then for details you skip with Enter. The first command is for Debian, where sudo is sometimes missing.
Log in with an SSH key
Create a key on your own computer, not on the VPS:
ssh-keygen -t ed25519
Press Enter for the default location and choose a passphrase. The .ssh folder in your user folder now holds id_ed25519, your private key that you never share, and id_ed25519.pub, the public key for your server.
On macOS and Linux, you put the key on your VPS like this:
ssh-copy-id [email protected]
On Windows, ssh-copy-id doesn't exist. Open the public key in Notepad with notepad $env:USERPROFILE\.ssh\id_ed25519.pub and copy the whole line. Log in as alex and run:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
nano ~/.ssh/authorized_keys
Paste the line, save with Ctrl+O and Enter and exit with Ctrl+X.
Test in a new window: ssh [email protected] now asks at most for your passphrase, not for the password of alex. Also check sudo whoami with the password of alex: it shows root.
Turn off password login
Only do this when your key and sudo both work. Create a new file:
sudo nano /etc/ssh/sshd_config.d/00-hardening.conf
Put these lines in it and save:
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
SSH reads this folder before the main file, in alphabetical order, and the first value counts. With 00 your file goes first. Check the settings and restart SSH:
sudo sshd -t
sudo systemctl restart ssh
If sshd -t gives no output, everything is fine. Test in a new window: ssh [email protected] still works, but ssh -o PubkeyAuthentication=no [email protected] and ssh [email protected] are refused.
A firewall with ufw
Allow SSH before you turn on the firewall, or you lock yourself out:
sudo apt install ufw
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose
Confirm the question with y. Incoming traffic is now blocked, except what you allow. Open the ports of your services the same way, for example sudo ufw allow 443/tcp for a website. Note: ports you publish with Docker bypass ufw.
Automatic security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Choose Yes. On Ubuntu this is already on, on Debian this turns it on. Your VPS now installs security updates every day, but doesn't restart by itself. So run sudo reboot now and then for a new kernel.
Locked out anyway?
Contact support and include the IP address of your VPS. Never send your password or private key. Background is in the Ubuntu OpenSSH guide.