Skip to Content
Bash & LinuxSSH Hardening

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 2

After editing, validate the config and restart the service:

# Validate config before restarting (prevents lockout) sshd -t # Restart SSH systemctl restart sshd

Set 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_keys

Fail2Ban

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.local

Edit /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 sshd

Best Practices

  • Always test SSH access in a second terminal before closing your current session after config changes
  • Run sshd -t to 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_keys and remove stale keys
Last updated on