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
# 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

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.

Additional Resources