SSH Hardening
A hardened SSH configuration reduces the attack surface of a Linux server by disabling insecure defaults, restricting access, and enforcing key-based authentication.
Key Settings
- Disable root login — Prevents direct root access over SSH; use a sudo-enabled user instead
- Disable password authentication — Enforces key-based auth, eliminating brute-force password attacks
- Change the default port — Reduces noise from automated scanners (security through obscurity, not a substitute for other controls)
- Restrict allowed users — Limits SSH access to a specific set of users
- Disable empty passwords — Blocks accounts with no password from logging in
- Limit authentication attempts — Reduces the window for brute-force attacks
- Disable unused authentication methods — Turn off
X11Forwarding,PermitTunnel, and other features if not needed
sshd_config Changes
Edit /etc/ssh/sshd_config and apply the following:
# /etc/ssh/sshd_config
Port 9437 # Change from default 22
PermitRootLogin no # Disable direct root login
PasswordAuthentication no # Require key-based auth
PermitEmptyPasswords no # Block empty password accounts
MaxAuthTries 3 # Limit auth attempts per connection
PubkeyAuthentication yes # Enable public key auth
AuthorizedKeysFile .ssh/authorized_keys
AllowUsers sean # Whitelist specific users
X11Forwarding no # Disable X11 forwarding
PermitTunnel no # Disable tunnelling
AllowAgentForwarding no # Disable agent forwarding
AllowTcpForwarding no # Disable TCP forwarding
ClientAliveInterval 300 # Disconnect idle sessions after 5 minutes
ClientAliveCountMax 2
LoginGraceTime 20 # Reduce login window to 20 seconds
Protocol 2 # Enforce SSH protocol version 2After editing, validate the config and restart the service:
# Validate config before restarting (prevents lockout)
sshd -t
# Restart SSH
systemctl restart sshdSet Up Key-Based Authentication
# On the client — generate an ED25519 key pair
ssh-keygen -t ed25519 -C "your-comment"
# Copy the public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 sean@<server-ip>
# Or manually append to authorized_keys on the server
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "<your-public-key>" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysFail2Ban
Fail2Ban monitors auth logs and automatically bans IPs that exceed a failed login threshold.
# Install
apt install fail2ban -y
# Create a local jail config (don't edit jail.conf directly)
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.localEdit /etc/fail2ban/jail.local and configure the SSH jail:
[sshd]
enabled = true
port = 9437
logpath = %(sshd_log)s
maxretry = 3
bantime = 1h
findtime = 10m# Enable and start Fail2Ban
systemctl enable fail2ban
systemctl start fail2ban
# Check banned IPs
fail2ban-client status sshdBest Practices
- Always test SSH access in a second terminal before closing your current session after config changes
- Run
sshd -tto validate config syntax before restarting the service - Prefer ED25519 keys over RSA; if RSA is required, use at least 4096 bits
- Keep SSH keys protected with a passphrase
- Disable SSH entirely and use a bastion host or VPN for servers that don’t need direct public access
- Regularly audit
~/.ssh/authorized_keysand remove stale keys
Last updated on