Lesson 1 of 1 in The First Box
Close The Easy Doors
A key instead of a password, a normal user instead of root, and an SSH config that refuses the two things every bot on the internet is trying. Three changes, and the noise that fills a new box's log stops finding anything.
3 min read
Not yet reviewed
The app is deployed and the site loads. I can SSH in as root with my password. Am I done?
You are on my list. I did not pick you — a scanner found an address answering on port 22 and started guessing. root / 123456, root / password, a thousand a minute. I do this to the whole internet at once.
Which is exactly why the first hour is not about your app. It is about taking away the two things that guessing needs: a password to guess, and root to guess it against.
A key is not a password
A password is something a bot can try. An SSH key is a pair of very large numbers: a private half you keep, and a public half you put on the server. Logging in proves you hold the private half without ever sending it, and there is nothing to guess — the numbers are far too big to try. So the first move is to make a key, put its public half on the box, and then turn passwords off entirely.
# Ed25519 — small, fast, modern. Do this on your own machine, not the server.
$ ssh-keygen -t ed25519 -C "me@laptop"
Your identification has been saved in ~/.ssh/id_ed25519
Your public key has been saved in ~/.ssh/id_ed25519.pub
# Copy the *public* half to the server. The private half never leaves your laptop.
$ ssh-copy-id you@your-box
Number of key(s) added: 1
Stop logging in as root
Root can do anything, which means a guessed root password is the whole machine. So you make an ordinary user, give it the ability to become root *deliberately* with sudo, and then forbid logging in as root over SSH altogether. Now an attacker has to guess a username as well as everything else — and the account with all the power cannot be reached from outside at all.
adduser deploy # a normal user to be, day to day
usermod -aG sudo deploy # allowed to become root, on purpose
# then, in the SSH daemon's config:
PermitRootLogin no # root cannot log in over SSH at all
PasswordAuthentication no # keys only — there is no password to guess
- Line 2
sudois the difference between *being* root and *becoming* root for one command. You work asdeploy, and a mistake is a mistake in one account, not in the whole system. - Line 4The two lines that end the brute force. With no password accepted and root unreachable, the thousand-a-minute guessing has nothing to hit.
Note
Moving SSH off port 22 is the one piece of folklore worth naming honestly: it does not stop attackers, who scan every port anyway. It stops the *log noise*, which can make a real attempt easier to see. Do it for quiet if you like, but never mistake a quieter log for a safer box — the key and the disabled password are the security; the port is housekeeping.
You disabled password authentication and turned off root login. A friend says "but my password was strong — 16 random characters." Why is the change still right?
Do it yourself
Here is a fresh box's SSH config. Turn off the two things the bots need: make PasswordAuthentication and PermitRootLogin both no. Append the corrected lines — the daemon reads the last setting for each — then check your work.
Harden this sshd_config: it must end with password authentication and root login both off. Append the two lines that do it.