Locking down SSH, and locking myself out
Key-only SSH is the right setting. I proved it by accidentally locking myself out of my own Pi.
- Goal
- Make sure the only way into the Pi is with my SSH key
- Result
- Password logins refused
- Tools
- OpenSSH, Fail2ban, Lynis, Kali Linux
The goal
Passwords can be guessed. SSH keys effectively can't. So the plan was simple: log in with a key only, and turn password logins off completely.
Locked out (twice)
First boot: SSH said Permission denied (publickey) even though my key was in the setup file. ssh -v showed my Mac offering the right key, but the Pi rejecting it. I reflashed, logged in with a password first, copied my key over with ssh-copy-id, checked key login worked, and only then turned passwords off.
The next day, locked out again: I'd run ssh-copy-id before making a new key, so the Pi only had my old one. ssh-keygen -lf showed the fingerprints didn't match. With passwords off there was no way back in, which is the security setting doing its job. I reflashed and did it in the right order.
Proving passwords are refused
$ ssh -o PubkeyAuthentication=no haydn@<the pi> haydn@<the pi>: Permission denied (publickey).
Hardening it further
A Lynis security audit scored the Pi 63. I hardened SSH (no root login, only my user, three login tries, no forwarding, idle timeouts), added a login banner, tightened file permissions and kernel network settings, and the score went to 75. Two of its warnings turned out to be false positives, which I checked rather than "fixed".
Fail2ban
If an IP gets the SSH login wrong 5 times in 10 minutes, Fail2ban bans it in the firewall for an hour, longer each time it comes back. I tested it from my Kali Linux VM by trying a fake user. After 5 tries the VM was banned, then I lifted the ban with fail2ban-client.
What I learned
- Order matters: copy the key, test it, then turn passwords off.
- Getting locked out by your own security settings means they work. Have a recovery plan.
- Don't blindly fix every audit warning. Understand it first.
How I used AI: Claude guided me through each step and explained the errors. I ran every command, reflashed the card and did the Fail2ban test. The full, unedited notes are in my build log.