SSH is the backbone of remote server administration, but misconfigured SSH can create significant security vulnerabilities. This practical guide identifies the most common SSH configuration mistakes and provides the exact commands needed to fix them, helping you secure your infrastructure against unauthorized access and potential breaches.
1. Still Allowing Password Authentication
The Problem: Password-based authentication remains the most common entry point for SSH breaches. Passwords can be brute-forced, phished, or stolen through various means.
The Fix: Disable password authentication and enforce SSH key-based authentication:
# Edit the SSH configuration file
sudo nano /etc/ssh/sshd_config
# Find and modify these settings
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes # Keep this as yes for other authentication needs
# Apply changes
sudo systemctl restart sshd
Important: Before disabling password authentication, ensure you’ve already:
- Generated SSH keys (
ssh-keygen -t ed25519
) - Copied your public key to the server (
ssh-copy-id user@server
) - Verified key-based login works
2. Allowing Root Login Over SSH
The Problem: Enabling direct root login via SSH creates a single point of failure. If an attacker guesses or cracks the root password, they immediately have full system access.
The Fix: Disable root login and use sudo for privileged operations:
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# Find and change this line
PermitRootLogin no
# Apply changes
sudo systemctl restart sshd
Alternative approach for emergencies: If you absolutely need root SSH access for specific situations, allow only key-based authentication:
PermitRootLogin prohibit-password
3. Running SSH on the Default Port
The Problem: While not a strong security measure by itself, running SSH on the default port 22 makes your server an easy target for automated scanning and brute force attacks.
The Fix: Change the SSH port to a non-standard port (under 1024 is recommended):
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# Change the port number
Port 2222 # Choose any unused port
# Apply changes
sudo systemctl restart sshd
# Update firewall rules (if using UFW)
sudo ufw allow 2222/tcp
sudo ufw deny 22/tcp
# For systems with SELinux
sudo semanage port -a -t ssh_port_t -p tcp 2222
Remember: Update your SSH client configuration or use the -p
flag when connecting: ssh user@server -p 2222
4. Using Outdated Cryptographic Algorithms
The Problem: Older SSH configurations often allow weak encryption algorithms and ciphers that can be compromised.
The Fix: Restrict SSH to use only strong, modern algorithms:
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# Add or update these lines
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected]
# Apply changes
sudo systemctl restart sshd
Verify your configuration: Use the ssh -Q
command to check supported algorithms:
ssh -Q cipher # Lists supported ciphers
ssh -Q mac # Lists supported MACs
ssh -Q kex # Lists supported key exchange algorithms
5. Not Implementing Connection Rate Limiting
The Problem: Without rate limiting, attackers can perform unlimited login attempts, enabling brute force attacks.
The Fix: Implement rate limiting with fail2ban:
# Install fail2ban
sudo apt install fail2ban # Debian/Ubuntu
sudo yum install fail2ban # RHEL/CentOS
# Create a custom SSH jail configuration
sudo nano /etc/fail2ban/jail.d/ssh-custom.conf
# Add the following configuration
[sshd]
enabled = true
port = ssh # Update if using a custom port
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600
# Start and enable the service
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Check status: Verify fail2ban is working with:
sudo fail2ban-client status sshd
6. Not Restricting SSH Access by IP or User
The Problem: Allowing SSH access from any IP address and for all users increases your attack surface unnecessarily.
The Fix: Limit SSH access to specific users and/or IP addresses:
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# To restrict by user
AllowUsers admin devops operations
# To restrict by group (alternative approach)
AllowGroups ssh-users admins
# Apply changes
sudo systemctl restart sshd
For IP-based restrictions, use one of these methods:
Method 1: Using sshd_config (OpenSSH 7.0+):
# Add to sshd_config
Match Address 192.168.1.0/24,10.0.0.0/8
PasswordAuthentication yes
Match Address *
PasswordAuthentication no
Method 2: Using TCP wrappers:
# Edit /etc/hosts.allow
sudo nano /etc/hosts.allow
# Add allowed IPs
sshd: 192.168.1.0/24 10.0.0.0/8
# Edit /etc/hosts.deny
sudo nano /etc/hosts.deny
# Deny all other connections
sshd: ALL
7. Not Setting an Idle Timeout
The Problem: Without timeouts, idle SSH sessions can remain active indefinitely, creating security risks if a user leaves their computer unattended.
The Fix: Configure automatic timeout for idle sessions:
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# Add or modify these lines
ClientAliveInterval 300 # Send packet every 5 minutes
ClientAliveCountMax 3 # Disconnect after 3 missed responses (15 minutes total)
# Apply changes
sudo systemctl restart sshd
User-level alternative: Users can also set this in their client configuration:
# In ~/.ssh/config
Host *
ServerAliveInterval 300
ServerAliveCountMax 3
8. Using Weak SSH Keys
The Problem: RSA keys with less than 3072 bits or older key types like DSA provide insufficient security against modern attacks.
The Fix: Generate and use strong SSH key pairs:
# Generate Ed25519 keys (recommended modern approach)
ssh-keygen -t ed25519 -a 100
# Or, for RSA with strong security
ssh-keygen -t rsa -b 4096 -a 100
To restrict key types on the server:
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config
# Add or update this line
PubkeyAcceptedKeyTypes ssh-ed25519,[email protected],rsa-sha2-512,rsa-sha2-256
# Apply changes
sudo systemctl restart sshd
Audit existing keys: Check for weak keys:
sudo grep -r "ssh-dss\|ssh-rsa" /home/*/.ssh/authorized_keys
9. Forgetting to Monitor SSH Activities
The Problem: Without monitoring, you won’t know when suspicious SSH activities occur until it’s too late.
The Fix: Implement comprehensive SSH logging and monitoring:
# Edit SSH configuration for verbose logging
sudo nano /etc/ssh/sshd_config
# Set appropriate log level
LogLevel VERBOSE
# Apply changes
sudo systemctl restart sshd
For active monitoring, implement a specialized tool like SSHwatch:
# Install the SSHwatch agent
curl -s https://install.sshwatch.com/install.sh | sudo bash -s -- --api-key YOUR_API_KEY
Quick SSH log check: Review recent SSH activities:
# Check authentication logs on Debian/Ubuntu
sudo grep sshd /var/log/auth.log | tail -100
# On RHEL/CentOS systems
sudo grep sshd /var/log/secure | tail -100
10. Not Keeping SSH Software Updated
The Problem: Outdated SSH implementations often contain known vulnerabilities that attackers can exploit.
The Fix: Regularly update your SSH server and client software:
# Debian/Ubuntu
sudo apt update
sudo apt install openssh-server openssh-client
# RHEL/CentOS
sudo yum update openssh-server openssh-clients
# Check your current OpenSSH version
ssh -V
Create a simple automated update reminder:
# Create a simple monthly update check script
cat <<EOF > /etc/cron.monthly/ssh-update-check
#!/bin/bash
current_version=\$(ssh -V 2>&1 | cut -d" " -f1 | cut -d"_" -f2)
echo "Current SSH version is \$current_version. Please check for updates." | mail -s "SSH Version Reminder" [email protected]
EOF
# Make it executable
chmod +x /etc/cron.monthly/ssh-update-check
Real-World Implementation: Securing a Production Server in 10 Minutes
Here’s how to implement all the above fixes quickly for a typical production server:
- Create a backup of your current configuration:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
- Create and apply a secure configuration:
sudo tee /etc/ssh/sshd_config.d/10-security.conf > /dev/null <<EOF # SSH Security Hardening Port 2222 PermitRootLogin no PasswordAuthentication no ChallengeResponseAuthentication no AllowUsers admin devops # Replace with your actual users KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512 Ciphers [email protected],[email protected] MACs [email protected],[email protected] ClientAliveInterval 300 ClientAliveCountMax 3 LogLevel VERBOSE X11Forwarding no MaxAuthTries 3 PubkeyAcceptedKeyTypes ssh-ed25519,[email protected],rsa-sha2-512,rsa-sha2-256 EOF
- Update firewall rules:
# For UFW sudo ufw allow 2222/tcp sudo ufw deny 22/tcp # For firewalld sudo firewall-cmd --permanent --add-port=2222/tcp sudo firewall-cmd --permanent --remove-service=ssh sudo firewall-cmd --reload
- Install fail2ban for rate limiting:
sudo apt install fail2ban sudo tee /etc/fail2ban/jail.d/ssh-custom.conf > /dev/null <<EOF [sshd] enabled = true port = 2222 filter = sshd logpath = /var/log/auth.log maxretry = 5 bantime = 3600 findtime = 600 EOF sudo systemctl enable fail2ban sudo systemctl start fail2ban
- Test and apply the configuration:
# Test configuration syntax sudo sshd -t # If no errors, apply changes sudo systemctl restart sshd
- IMPORTANT: Keep your current SSH session open and verify you can login with the new settings from another terminal:
ssh -p 2222 user@server
Conclusion: Beyond Configuration
While fixing these configuration mistakes will significantly improve your SSH security, remember that security is an ongoing process. Consider these additional measures:
- Implement SSH certificate authentication for large-scale deployments
- Set up a centralized SSH key management system for your organization
- Consider using SSH jump hosts for access to sensitive infrastructure
- Implement regular security audits of your SSH configuration
- Integrate SSH logs with your SIEM system for comprehensive security monitoring
By addressing these common configuration mistakes and implementing proper monitoring, you can dramatically improve your SSH security posture with minimal effort. Most of these fixes require just a few minutes to implement but provide long-lasting protection against the most common attack vectors.
Want to ensure your SSH configuration is secure? Get a free SSH security scan to identify potential vulnerabilities and receive a detailed remediation plan.