SSH, Hardening & Remote Access
Remote admin without being reckless
Open interactive version (quiz + challenge)Real-world analogy
SSH is your remote door. Leaving it wide open with a password lock is like guarding a bank with a screen door. Keys + no root login + a fail2ban dog + firewall walls = a door you can sleep next to.
What is it?
SSH hardening + a default-deny firewall + brute-force defense + centralized logging is the baseline every Linux admin is expected to know and maintain. It’s table stakes in any serious operations team.
Real-world relevance
A startup exposes SSH with default settings on port 22 using passwords. Within 24 hours, bots launch 10,000+ login attempts. An attacker with a leaked password list gets in. A careful junior deploys keys-only, fail2ban, and a bastion; next 24 hours: zero successful attempts, massive drop in log noise.
Key points
- SSH key auth beats passwords — Generate a keypair (ssh-keygen -t ed25519), put the public key in ~/.ssh/authorized_keys on the server, set mode 600. Passwords are brute-forceable; keys are not (within any practical time).
- Disable password auth and root login — In /etc/ssh/sshd_config: PasswordAuthentication no, PermitRootLogin no, PubkeyAuthentication yes. Reload sshd only after testing key login in a second window to avoid locking yourself out.
- Firewalls: ufw and firewalld — ufw (Debian/Ubuntu) and firewalld (RHEL family) are simple front-ends. Allow 22 (or your chosen port), deny everything else, then open what services need. Default-deny is the default you want.
- fail2ban — brute-force throttle — fail2ban watches logs (auth.log) and temporarily bans IPs after repeated failed logins. A simple deployment drastically cuts background brute-force noise on any internet-exposed SSH.
- Bastion / jump host model — Instead of exposing SSH on every server, allow SSH only from a bastion. Admins SSH to the bastion, then ProxyJump into targets. One hardened entry point > many weak ones.
- MFA on SSH — For higher assurance, add TOTP (google-authenticator PAM) or certificate-based SSH with short TTLs. Most regulated environments now require MFA on privileged access.
- Never copy private keys around — Use ssh-agent / agent forwarding carefully, or better, short-lived SSH certificates. A stolen private key is a house key for your entire fleet.
- Log, alert, and review — Forward SSH auth logs to a central SIEM. Alert on root logins, unusual source IPs, and new key additions. Review privileged sessions periodically. This is boring until it saves your audit.
Code example
// Linux hardening checklist (first pass)
[ ] Separate standard users from root
[ ] SSH keys generated with ed25519, passphrase set
[ ] PermitRootLogin no, PasswordAuthentication no
[ ] AllowUsers only the accounts that need SSH
[ ] ufw or firewalld: default deny, allow only needed ports
[ ] fail2ban enabled for sshd
[ ] Automatic security updates (unattended-upgrades or dnf-automatic)
[ ] NTP configured; logs forwarded to central SIEM
[ ] MFA on privileged/bastion access
[ ] Documented list of who has SSH keys and why (access review)Line-by-line walkthrough
- 1. Hardening checklist
- 2. Standard user accounts separate from root
- 3. SSH keys ed25519 with passphrase
- 4. Disable root login and passwords
- 5. Restrict AllowUsers
- 6. Default-deny firewall with required ports allowed
- 7. fail2ban for SSH
- 8. Automatic security updates
- 9. Time sync and centralized log forwarding
- 10. MFA on privileged/bastion access
- 11. Documented access review
Spot the bug
Junior deploys a new internet-facing VM.
Config: default ssh on port 22, root login allowed, password auth enabled, no firewall.Need a hint?
List 4 fast, high-impact changes this server needs in the first 30 minutes.
Show answer
(1) Create a non-root user + put their ed25519 public key in authorized_keys. (2) In sshd_config: PermitRootLogin no, PasswordAuthentication no, AllowUsers that user, MaxAuthTries 3. (3) Enable ufw default-deny, allow only OpenSSH and required service ports. (4) Install fail2ban and enable the sshd jail. Test with a second session BEFORE reloading sshd.
Explain like I'm 5
Leaving SSH open with a password is like leaving your front door with only a string lock. Keys + no-root + an alarm dog + a real fence make it a house that burglars skip and attack the neighbor’s instead.
Fun fact
The first real-world worm that exploited weak SSH passwords globally started in 2005 and rapidly infected thousands of servers. Many of those servers belonged to universities — because nobody changed the default passwords. Weak SSH + default-allow firewalls = attacker playground.
Hands-on challenge
On an Ubuntu VM: generate an ed25519 key, copy the public key to the server, disable password auth + root login, enable ufw default-deny with OpenSSH allowed, install fail2ban. Confirm login still works and that password attempts are refused.
More resources
- OpenSSH server config (OpenBSD / OpenSSH)
- ufw (Ubuntu firewall) guide (Ubuntu Community)
- fail2ban docs (fail2ban (GitHub))