Latest / Linux Server Admin with Fexingo: Sysadmin, Bash, and Server Engineering / How to Secure Linux Server SSH with Key-Based Authentication and Hardening
Transcript
- Lucas: If you manage Linux servers, there's probably one thing keeping you up at night — someone cracking an SSH password and getting root access. Luna: Yeah, password-based SSH is basically an open door if you're exposed to the internet. I've seen it happen. Lucas: Exactly. And that's why today we're going deep on SSH key-based authentication and server hardening. The goal: make password-based login impossible on your server. Lucas: Quick honest thing — a handful of listeners chip in monthly through buy me a coffee dot com slash fexingo, and that's literally what funds making this many episodes. Keeps the show ad-free and focused. Luna: Yeah, appreciate those folks. It lets us cover stuff like this without any sponsor noise. Lucas: So back to SSH hardening. First step: generate a strong key pair. I recommend Ed25519 over RSA — it's faster, smaller, and considered just as secure. Luna: Why Ed25519 specifically? I know RSA is still common. Lucas: Good question. Ed25519 uses elliptic curve cryptography, which gives you equivalent security to a 4096-bit RSA key with a much smaller signature. Plus, it's less susceptible to certain side-channel attacks. To generate: ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519. Luna: The -a 100 is the number of KDF rounds, right? Harder to brute force the key file if someone gets it. Lucas: Exactly. Now you need to copy the public key to your server. Use ssh copy id -i ~/.ssh/id_ed25519.pub user@server. That adds it to ~/.ssh/authorized_keys on the server. Luna: But before you disable passwords, you should test that key-based login actually works. I've seen people lock themselves out. Lucas: Absolutely critical. Open a second terminal session, try to SSH in with your key. If it works, then you can edit /etc/ssh/sshd_config. Set PasswordAuthentication no, then also set PubkeyAuthentication yes. And while you're there, disable root login: PermitRootLogin prohibit-password or better, set it to no. Luna: What about ChallengeResponseAuthentication? I've seen that one trip people up. Lucas: Right — set that to no as well. Otherwise some systems still allow password-based authentication through PAM. So: ChallengeResponseAuthentication no. Then restart sshd: sudo systemctl restart sshd. Luna: Now what if someone tries to brute force your SSH even with keys? They'll just get rejected, but the logs fill up. Lucas: That's where fail2ban comes in. It watches auth logs and temporarily bans IPs that show repeated failures. Install it, then configure a jail for SSH. Default settings usually ban after 5 failed attempts within 10 minutes for 10 minutes. Luna: I'd also recommend changing the default SSH port from 22 to something higher. It reduces log noise dramatically. Lucas: That's a debated move — security through obscurity — but I agree it cuts down on automated scans. Just update Port 2222 in sshd_config and your firewall rules. And don't forget to allow the new port before restarting. Luna: Another thing: use AllowUsers or AllowGroups in sshd_config to restrict who can SSH in. If only three people need access, list them. Lucas: Great point. Also, consider using SSH certificates instead of manually managing authorized_keys. You set up a certificate authority, sign user keys, and the server trusts the CA. That way you can revoke access centrally. Luna: That scales well for teams. For a single server, manual authorized_keys is fine, but for a fleet, certificates are a lifesaver. Lucas: Let's talk about key permissions on the client side. Your private key should be 600, the public key 644, and the.ssh directory 700. Otherwise SSH will refuse to use the key. Luna: And on the server side, authorized_keys must be 600, and the.ssh directory 700. Same principle. Lucas: One more hardening step: set ClientAliveInterval and ClientAliveCountMax in sshd_config to drop idle connections. Say, ClientAliveInterval 300 and ClientAliveCountMax 2 — that disconnects idle sessions after 10 minutes. Luna: That's good for security and resource management. I also like to set MaxAuthTries to 2 or 3 to limit login attempts per connection. Lucas: Exactly. And finally, use a strong passphrase on your private key. If someone steals your laptop, they still can't use the key without the passphrase. You can use ssh-agent to cache it so you don't type it every time. Luna: What about using a YubiKey or similar hardware token to store SSH keys? That adds another layer. Lucas: Absolutely. OpenSSH supports FIDO/U2F keys. You can generate a key backed by a hardware token with ssh-keygen -t ed25519-sk. The private key never leaves the token. Luna: So to sum up: generate Ed25519 keys, copy them with ssh copy id, test, disable password auth, set proper permissions, use fail2ban, maybe change the port, restrict users, and consider certificates or hardware tokens. Lucas: That's the complete hardening checklist. And remember: always keep a backup console access — like iDRAC or IPMI — in case you misconfigure something and lock yourself out. Luna: Yeah, I've learned that the hard way. One wrong sshd_config line and you're scrambling for a recovery console. Lucas: If today's tech conversation gave you something usable, consider that buy me a coffee. It really helps us keep digging into topics like this. Luna: Alright, next episode we'll tackle firewall hardening with nftables. See you then.