Lesson 4 · Security
A firewall decides who can knock. Identity decides who gets in. Today the door stops accepting guessed passwords.
22/tcp is deliberately still open, because you
need to get in. The audit flagged how that door works:
Finding C — PermitRootLogin yes and
password auth enabled — and Finding G — no
brute-force defence. This lesson closes both, and ticks the mission's
"SSH is least-privilege, no root password login — and I can explain why in interview terms."
A password is a secret you both know — which means it can be guessed, reused,
phished, or leaked, and a bot can try millions of them against your open port. A key is
asymmetric: the private half never leaves your machine, and nothing brute-forceable ever
crosses the wire. Switching SSH from "password allowed" to "keys only" doesn't just harden the
door — it removes the entire category of attack that automated scanners run against every exposed
22 on the internet.
sudo behind a
bastion — we'll name that ideal at the end.
What makes an SSH key fundamentally safer than a password?
Every other lesson's worst case was a service hiccup. This one's worst case is locking yourself out of your own host — disable password login when your key doesn't actually work, and the next connection is refused. So the discipline is entirely about order: prove the new way in before you remove the old one. Tap each step to see why it's where it is.
Tap a step to reveal what it protects against. Skipping one is how people get locked out.
ssh -o PasswordAuthentication=no root@host from another
machine. If it logs you in, your key is good. Skip this and you're disabling the only door
you've tested./etc/ssh/sshd_config.d/10-hardening.conf, not the main
config — it's isolated, obvious, and trivial to delete to roll back. (Your host already
Includes that directory.)sshd -t parses it without touching the running server.
Reloading a syntactically broken sshd can drop you and refuse new logins.systemctl reload ssh applies the new rules to new
connections while leaving your current session untouched. Your open shell is your
safety line.https://192.168.5.121:8006 gives you a root shell over a completely separate channel
(it survived Lesson 3's firewall, since 8006 is management-allowed) — so you can always undo the
change. (3) Rollback is deleting one file and reloading.
Before you set PasswordAuthentication no, what must you confirm?
There are two settings doing two jobs. PasswordAuthentication no turns off passwords
for everyone. PermitRootLogin prohibit-password says root may still log in — but
only with a key, never a password. On Proxmox that's the pragmatic sweet spot: the platform's
own tooling and the web UI expect root@pam, so you keep root reachable by key while
removing the password as an attack path entirely. That exactly satisfies "no root password login."
What does PermitRootLogin prohibit-password actually do?
Part A is the real win — key-only SSH, root by key only. Part B adds brute-force defence. Keep your current session open the whole time.
### SAFETY CHECK — prove key login works BEFORE removing passwords ### # from your laptop / another machine (NOT from inside the host): ssh -o PasswordAuthentication=no root@192.168.5.121 'echo key-only login OK' # it prints the message? your key works — safe to proceed. ssh root@192.168.5.121 # now log in and KEEP THIS SESSION OPEN ### PART A — key-only SSH, root by key only (Finding C) ### cat > /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF' # Identity hardening — keys only, root by key only PermitRootLogin prohibit-password PasswordAuthentication no KbdInteractiveAuthentication no EOF sshd -t && echo "config OK" # validate BEFORE applying — never reload a broken config systemctl reload ssh # reload, NOT restart: your current session survives # PROVE it in a NEW terminal before closing this one: # ssh root@192.168.5.121 -> still works (your key) # ssh -o PreferredAuthentications=password root@...121 -> "Permission denied" (good!) # ROLLBACK: rm /etc/ssh/sshd_config.d/10-hardening.conf && systemctl reload ssh ### PART B — fail2ban: brute-force defence + log hygiene (Finding G) ### apt-get update && apt-get install -y fail2ban cat > /etc/fail2ban/jail.d/sshd.local <<'EOF' [sshd] enabled = true maxretry = 4 bantime = 1h EOF systemctl enable --now fail2ban fail2ban-client status sshd # shows the active jail
When a fresh login still works by key but is refused with a password, you've removed the entire password-guessing attack surface from your most exposed port. That's the win.
prohibit-password keeps root
usable by key — fine for a single Proxmox box. The stricter ideal is: PermitRootLogin no,
log in as a named user, escalate with sudo (so every action is attributable to a
person), and reach the host only through a bastion / jump host. That's accountability + least
privilege + a single audited entry point — the model behind every serious production estate. Overkill
for one host today; exactly the vocabulary that signals you think like an infra engineer.
sudo user so we could later flip to PermitRootLogin no? Want to
tune the fail2ban jail (ban times, ignoreip for your LAN/Tailnet)? Or jump to
Lesson 5 (Blast Radius)? Just ask.
Primary source to read next: the
Mozilla OpenSSH Guidelines — a
high-trust, current baseline for key auth, root login, and ciphers. Pair it with
man sshd_config for the exact meaning of PermitRootLogin and
PasswordAuthentication.