A brand-new VPS is under attack faster than you'd think. Point one at the internet and within minutes the SSH port is taking login attempts from bots scanning the whole address space, around the clock. So before we deploy anything onto it, we lock it down, and it's five things, not fifty: stop using root and make a normal sudo user, switch SSH to keys with passwords off, put a default-deny ufw firewall in front opening only the ports we actually serve, add fail2ban to swat the brute-force noise, and turn on automatic security updates. The one rule that saves you from a bad afternoon: set the key up and test it before you disable passwords, or you will lock yourself out of your own machine.
The short answer
Make a sudo user instead of root, move SSH to keys and turn passwords off, put
a default-deny ufw firewall in front, add fail2ban, and switch on automatic
security updates. Set up and test the key before you disable passwords.
Stop logging in as root
Working as root means every typo runs with no safety net, and it is the account every bot tries first. Make yourself a normal user with sudo and use that instead:
adduser deploy usermod -aG sudo deploy Log out, log back in as deploy, and check sudo whoami returns root. From
here on, root is something you reach through sudo, not a door you leave open.
Keys instead of passwords
A password can be guessed; an SSH key cannot, not in any timeframe that matters. If you do not have one yet, our guide to ssh-keygen covers it. Copy your public key up to the new user:
ssh-copy-id deploy@your-server-ip Now the careful part. Open sudo nano /etc/ssh/sshd_config, set
PasswordAuthentication no and PermitRootLogin no, then reload SSH:
sudo systemctl reload ssh Before you close anything, open a second terminal and confirm a key login works. That spare session is your seatbelt: if you fat-fingered the config, you can still get back in and fix it.
A default-deny firewall
ufw makes this painless. We deny everything inbound, then open only the ports
this box actually serves. Allow SSH first, before enabling, or you cut your own
connection:
sudo ufw allow OpenSSH Add 80 and 443 if it serves a site, then turn it on:
sudo ufw enable
fail2ban for the brute force
Even with passwords off, the login attempts keep coming and fill your logs.
fail2ban watches them and bans an IP after a handful of failures. On Ubuntu it
protects SSH out of the box the moment it is installed:
sudo apt install fail2ban It reads its defaults from a packaged file; to tune the ban time or threshold,
copy them into /etc/fail2ban/jail.local and edit there, never the original.
For most boxes the defaults are fine.
Automatic security updates
Patches only help if they get applied, and nobody logs in daily to run them by
hand. unattended-upgrades installs security updates on its own:
sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades Answer yes when it asks, and the box keeps itself patched against the vulnerabilities that bots weaponise within days of disclosure.
The order is the whole trick
Honestly, none of these steps is hard on its own. The way people lose an afternoon is by disabling passwords before the key works, or enabling the firewall before allowing SSH. Do it in the order above, keep that second terminal open through the SSH change, and a fresh VPS goes from wide open to quietly locked down in about ten minutes.
Frequently asked questions
Will I lock myself out doing this?
It is the real risk, and it is avoidable. Before you disable password login, open a second terminal and confirm you can log in with your key. Keep that session open while you edit sshd_config and reload SSH, so if something is wrong you still have a way back in. Only close it once a fresh key login works on its own.
Do I need to change the SSH port?
It is optional and mostly cosmetic. Moving SSH off 22 quiets your logs because most bots only probe the default, but it is security by obscurity, not real protection. Keys with passwords disabled, plus fail2ban, do the actual work. Change the port if the calmer logs are worth it to you, not because it makes the box safe.
Is fail2ban still worth it if passwords are already off?
Less critical, but still cheap and worth keeping. With key-only SSH a brute force cannot succeed anyway, so there fail2ban is mostly trimming log noise. It earns its place guarding other services you expose later, and it costs almost nothing to run, so we leave it on.
PermitRootLogin: should it be no or prohibit-password?
Use no once your sudo user works, so root cannot log in over SSH at all. prohibit-password is the middle ground: root can still log in with a key but never a password, which some automation depends on. If nothing needs direct root SSH, no is the cleaner choice.