Linux SSH Hardening: Complete Security Guide
Introduction
SSH is one of the most critical services on Linux systems. Improper configuration can lead to unauthorized access and security breaches. This guide covers hardening SSH for your homelab and production servers.
1. Change the Default Port
While not a security measure by itself, it reduces automated attacks:
sudo nano /etc/ssh/sshd_config
Change:
Port 2222
Restart SSH:
sudo systemctl restart sshd
2. Disable Root Login
PermitRootLogin no
3. Disable Password Authentication
Use key-based authentication only:
PasswordAuthentication no
PubkeyAuthentication yes
Generate SSH Keys (if you haven’t already)
ssh-keygen -t ed25519 -C "user@homelab"
Copy to server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 [email protected]
4. Configure Key-Only Users
Restrict specific users to key-only authentication:
Match User deploy,jenkins
PasswordAuthentication no
PubkeyAuthentication yes
5. Disable Empty Passwords
PermitEmptyPasswords no
6. Limit Authentication Attempts
Prevent brute force attacks:
MaxAuthTries 3
MaxSessions 10
7. Configure Timeouts
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
8. Restrict User Access
Only allow specific users:
AllowUsers user1 user2
# OR
AllowUsers user@*.local
Deny specific users:
DenyUsers root ubuntu admin
9. Disable X11 Forwarding
Unless needed:
X11Forwarding no
10. Disable Agent Forwarding
Unless required:
AllowAgentForwarding no
11. Restrict Port Forwarding
AllowTcpForwarding no
AllowStreamLocalForwarding no
12. Use Strong Ciphers and Key Exchange Algorithms
Ciphers aes-256-ctr,aes-192-ctr,aes-128-ctr
KexAlgorithms curve25519-sha256,[email protected]
13. Increase SSH Logging
LogLevel VERBOSE
SyslogFacility AUTH
Check logs:
sudo tail -f /var/log/auth.log
14. Use SSH Config for Clients
Create ~/.ssh/config:
Host homelab
HostName 192.168.1.100
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
AddKeysToAgent yes
IdentitiesOnly yes
Now connect with: ssh homelab
15. Fail2Ban for Brute Force Protection
sudo apt-get install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Add SSH jail:
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 3600
bantime = 3600
Restart:
sudo systemctl restart fail2ban
Recommended SSH Config Example
# Logging
SyslogFacility AUTH
LogLevel VERBOSE
# Network
Port 2222
AddressFamily inet
ListenAddress 0.0.0.0
# Authentication
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
PermitRootLogin no
MaxAuthTries 3
# Authorization
AllowUsers deploy testuser
DenyUsers root ubuntu
# Security
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
MaxSessions 10
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
# Ciphers
Ciphers aes-256-ctr,aes-192-ctr,aes-128-ctr
KexAlgorithms curve25519-sha256,[email protected]
# Keys
HostKey /etc/ssh/ssh_host_ed25519_key
Security Checklist
- SSH running on non-standard port
- Root login disabled
- Password authentication disabled
- Key-based authentication configured
- Strong ciphers configured
- Fail2Ban installed and configured
- SSH logging enabled
- Firewall rules restricting SSH access
- SSH keys using Ed25519 algorithm
- SSH service hardened
Testing Your Configuration
Verify syntax before restarting:
sudo sshd -t
Monitoring
Monitor SSH activity:
# Failed login attempts
sudo grep "Failed password" /var/log/auth.log | tail -20
# Successful logins
sudo grep "Accepted publickey" /var/log/auth.log | tail -20
# Port scanning
sudo fail2ban-client status sshd
Common Issues
Locked Out After Changes
If you make SSH changes, keep your current session open and test in a new terminal before closing the original connection.
Keys Not Working
# Verify permissions (must be 600)
ls -la ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
# Check authorized_keys permissions (must be 600)
ls -la ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Conclusion
SSH security is foundational to protecting your infrastructure. Implement these hardening measures incrementally and test thoroughly.