SSH is the most attacked service on the internet. Bots constantly scan for weak passwords and default keys. In 2021, the FritzFrog botnet exploited weak SSH credentials on thousands of hosts. Hardening SSH is a non-negotiable first step. This lesson covers disabling root login, enforcing public key authentication, deploying fail2ban, and advanced measures like port knocking and certificate-based authentication.
The file /etc/ssh/sshd_config controls the SSH daemon. Critical directives: PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes, PermitEmptyPasswords no, MaxAuthTries 3, ClientAliveInterval 300, ClientAliveCountMax 0. Also limit which users can connect with AllowUsers or AllowGroups. After editing, test the configuration with sshd -t before restarting.
# Secure sshd_config snippet
sudo sed -i -E 's/^#?(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|PermitEmptyPasswords|MaxAuthTries|ClientAliveInterval).*/\1 yes/' /etc/ssh/sshd_config
# Then manually set PermitRootLogin no, PasswordAuthentication no, etc.
sudo sshd -t && sudo systemctl reload sshdThe output confirms the settings are active. Always run sshd -T to see the effective configuration, as it merges included files.
fail2ban monitors log files and temporarily bans IPs that show malicious signs—too many password failures, scanning, etc. For SSH, a default jail is included. Customize /etc/fail2ban/jail.local to set bantime, findtime, maxretry, and enable the sshd jail. Integrate with firewalld or iptables for the ban action. fail2ban turns SSH from a static target into a moving one.
# Install fail2ban and create jail.local for SSH
sudo apt install fail2ban
sudo tee /etc/fail2ban/jail.local << EOF
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
EOF
sudo systemctl restart fail2ban💡 Use fail2ban-client status sshd to see currently banned IPs. If you get locked out, you can unban yourself from the console.
| Hardening Measure | Config Directive | Security Gain |
|---|---|---|
| Disable root login | PermitRootLogin no | Eliminates direct root brute-force |
| Key-only auth | PasswordAuthentication no | Resistant to password guessing/phishing |
| Brute-force protection | MaxAuthTries 3 + fail2ban | Auto-ban after failed attempts |
| Idle session timeout | ClientAliveInterval + ClientAliveCountMax | Kills stale sessions |
For larger environments, use SSH certificates signed by a trusted CA, enabling short-lived credentials and revocation. Port knocking (knockd) adds an extra layer: a specific sequence of connection attempts to closed ports temporarily opens port 22. This hides SSH from scanners entirely. While not foolproof, it significantly reduces attack surface.
⚠️ If you change sshd_config remotely and make a mistake, you could lock yourself out. Always keep an active session open while testing, and use 'sshd -t' to validate syntax.
Verify exercises to earn ★ 150 XP and unlock next lab level.