A server with a public IPv4 address is being scanned within minutes of booting, and password logins on port 22 are the first thing tried. Do these four things before you install anything else.
1. Put your SSH key on it
On your own machine, if you do not already have a key:
ssh-keygen -t ed25519 -C "you@example.com"
Copy it up:
ssh-copy-id root@203.0.113.10
No ssh-copy-id available? Do it by hand:
cat ~/.ssh/id_ed25519.pub | ssh root@203.0.113.10 \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Open a second terminal and confirm the key works before continuing. Do not close the session you are in.
2. Turn password authentication off
sudo tee /etc/ssh/sshd_config.d/99-layerone.conf >/dev/null <<'EOF'
PasswordAuthentication no
PermitRootLogin prohibit-password
KbdInteractiveAuthentication no
EOF
sudo sshd -t && sudo systemctl reload ssh || sudo systemctl reload sshd
sshd -t validates the config first. Skipping it is how you end up in the
browser console.
You cannot be permanently locked out
The browser console does not use SSH, so a
bad sshd_config is a five minute inconvenience rather than a rebuild.
3. Update everything
# Debian and Ubuntu
sudo apt update && sudo apt upgrade -y
# RHEL, Rocky, Alma, Fedora
sudo dnf upgrade -y
Then turn on unattended security updates:
# Debian and Ubuntu
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
4. Close the ports you are not using
Two layers, and they are independent. Use both.
The cloud firewall runs outside the guest, so it holds even if the guest is compromised.
A host firewall inside the guest catches what you change locally. See Your first hour on a new server.
Then, if you want to go further
A non-root user. Root over SSH with a key is defensible; a normal user with
sudo is better practice.
sudo adduser deploy
sudo usermod -aG sudo deploy # or -aG wheel on RHEL family
sudo rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
fail2ban, to ban repeat offenders. With password auth off it mostly saves log noise, but noise hides real events:
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Do not move SSH to a nonstandard port and call it security. It reduces log
volume and nothing else. If you do it, add a cloud firewall rule for the new port
before you restart sshd.
Check what is actually listening. The most common real exposure is a
database or cache bound to 0.0.0.0 rather than 127.0.0.1:
sudo ss -tulpn
Anything on 0.0.0.0 that is not deliberately public should be bound to
localhost or to a private network address.