The first 15 minutes on a new VPS
A new server with a public IP gets SSH login attempts within minutes. Check /var/log/auth.log on day one if you don't believe me. Here's what I do on every fresh Debian or Ubuntu box before installing anything else.
1. Update
apt update && apt full-upgrade -y reboot
Reboot now if there's a new kernel, while nothing important is running yet.
2. Make a normal user
adduser deploy usermod -aG sudo deploy
Call it whatever you like. You'll use this account from now on instead of logging in as root.
3. SSH keys
Run this on your own machine, not the server:
ssh-copy-id deploy@YOUR_SERVER_IP
No key yet? Make one with ssh-keygen -t ed25519 first. Then log in as deploy and make sure it works without asking for a password.
4. Lock down sshd
Put your changes in a separate file instead of editing the main config, so package updates don't fight with you:
sudo nano /etc/ssh/sshd_config.d/10-hardening.conf
PermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no
sudo sshd -t && sudo systemctl reload ssh
Keep your current session open. Open a second terminal and log in again. Only close the first one once that works. If you do lock yourself out on netcup, the server control panel (SCP) has a web console you can log in through.
5. Firewall
sudo apt install ufw sudo ufw default deny incoming sudo ufw allow 22/tcp sudo ufw allow 80,443/tcp sudo ufw enable
One gotcha that bites everyone once: Docker ignores ufw. If you publish a port with -p 8080:8080, it's open to the internet no matter what ufw says. Bind to localhost instead (-p 127.0.0.1:8080:8080) and put a reverse proxy in front. More on that in the Caddy post.
6. Automatic security updates
sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades
Say yes. By default it only installs security updates, which is the right call for a box you won't log into every day.
What I skip
Moving SSH to a different port cuts down log noise, but it doesn't make you safer once passwords are off. Same for fail2ban: it's nice to have, but key-only login already does the heavy lifting. Add them later if the noise bothers you.