SSH Security Hardening
Hardens SSH server, prevents brute-force attacks and applies security best practices.
Published: March 20, 2024
Detailed Information
This script hardens your SSH server and prevents brute-force attacks. SSH is the most common protocol used for remote server access, and its security is critical.
What Does This Script Do?
This script improves SSH security by:
- Changing SSH port (custom port instead of default 22)
- Disabling root login
- Disabling password-based authentication (optional)
- Limiting authentication attempts
- Applying security settings
- Installing and configuring fail2ban
- Creating configuration backup
Why Should You Use It?
SSH security is fundamental to server security:
- Brute-Force Protection: Prevents attacks with fail2ban
- Root Access Blocking: Closes root login
- Key-Based Auth: Uses SSH key instead of password
- Port Change: Reduces attack surface by changing default port
How to Use
Step-by-Step Usage Guide
1. Generate SSH Key (Recommended)
First, create SSH key:
ssh-keygen -t ed25519 -C "[email protected]"
2. Copy Key to Server
ssh-copy-id user@server
3. Run Script
sudo chmod +x ssh_hardening.sh
sudo ./ssh_hardening.sh
4. Answer Questions
The script will ask you:
- Change SSH port from 22? (y/n)
- Disable password authentication? (y/n)
- Apply changes and restart SSH? (y/n)
5. Test Connection
Open a new terminal and test SSH connection. Don't close current terminal!
Requirements
Requirements
- Root Privileges: Script must be run as root
- SSH Installed: OpenSSH server must be installed
- SSH Key: For disabling password auth (recommended)
Use Cases
Use Cases
1. New Server Security
When setting up a new server, one of the first things to do is improve SSH security.
2. Brute-Force Attacks
Use to prevent brute-force attacks on SSH.
3. Production Servers
Maximize SSH security on production servers.
Examples
Usage Examples
Example 1: Basic Security
sudo ./ssh_hardening.sh
# Change port: n
# Disable password: n (set up SSH key first)
Example 2: Maximum Security
sudo ./ssh_hardening.sh
# Change port: y (e.g., 2222)
# Disable password: y Code
#!/bin/bash
# SSH Hardening Script
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
SSHD_CONFIG="/etc/ssh/sshd_config"
BACKUP_FILE="${SSHD_CONFIG}.backup.$(date +%Y%m%d_%H%M%S)"
echo "======================================"
echo " SSH HARDENING SCRIPT"
echo "======================================"
echo ""
echo "1. Creating backup..."
cp "$SSHD_CONFIG" "$BACKUP_FILE"
echo "✓ Backup created: $BACKUP_FILE"
echo ""
read -p "Change SSH port from 22? (y/n): " CHANGE_PORT
if [ "$CHANGE_PORT" = "y" ]; then
read -p "Enter new SSH port (1024-65535): " NEW_PORT
sed -i "s/^#*Port .*/Port $NEW_PORT/" "$SSHD_CONFIG"
echo "✓ SSH port changed to $NEW_PORT"
echo " Remember to update your firewall!"
fi
echo ""
echo "2. Disabling root login..."
sed -i "s/^#*PermitRootLogin .*/PermitRootLogin no/" "$SSHD_CONFIG"
echo "✓ Root login disabled"
echo ""
read -p "Disable password authentication? (Requires SSH key setup) (y/n): " DISABLE_PASS
if [ "$DISABLE_PASS" = "y" ]; then
sed -i "s/^#*PasswordAuthentication .*/PasswordAuthentication no/" "$SSHD_CONFIG"
echo "✓ Password authentication disabled"
echo " ⚠️ Make sure you have SSH keys configured!"
fi
echo ""
echo "3. Applying security settings..."
sed -i "s/^#*PermitEmptyPasswords .*/PermitEmptyPasswords no/" "$SSHD_CONFIG"
sed -i "s/^#*MaxAuthTries .*/MaxAuthTries 3/" "$SSHD_CONFIG"
sed -i "s/^#*LoginGraceTime .*/LoginGraceTime 20/" "$SSHD_CONFIG"
sed -i "s/^#*X11Forwarding .*/X11Forwarding no/" "$SSHD_CONFIG"
cat >> "$SSHD_CONFIG" << EOF
# Security hardening
Protocol 2
HostbasedAuthentication no
IgnoreRhosts yes
UsePAM yes
ClientAliveInterval 300
ClientAliveCountMax 2
MaxSessions 3
EOF
echo "✓ Security settings applied"
echo ""
echo "4. Installing fail2ban..."
if command -v apt-get &> /dev/null; then
apt-get update && apt-get install -y fail2ban
elif command -v yum &> /dev/null; then
yum install -y fail2ban
fi
if [ -f /etc/fail2ban/jail.local ]; then
cp /etc/fail2ban/jail.local /etc/fail2ban/jail.local.backup
fi
cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
EOF
systemctl enable fail2ban
systemctl restart fail2ban
echo "✓ fail2ban installed and configured"
echo ""
echo "5. Testing SSH configuration..."
sshd -t
if [ $? -eq 0 ]; then
echo "✓ Configuration is valid"
echo ""
read -p "Apply changes and restart SSH? (y/n): " RESTART
if [ "$RESTART" = "y" ]; then
systemctl restart sshd
echo "✓ SSH service restarted"
fi
else
echo "✗ Configuration has errors!"
echo "Restoring backup..."
cp "$BACKUP_FILE" "$SSHD_CONFIG"
exit 1
fi
echo ""
echo "======================================"
echo " SSH HARDENING COMPLETED"
echo "======================================"
echo ""
echo "Summary of changes:"
echo "- Root login: DISABLED"
echo "- Max auth tries: 3"
echo "- Login grace time: 20 seconds"
echo "- fail2ban: ENABLED"
[ "$CHANGE_PORT" = "y" ] && echo "- SSH port: $NEW_PORT"
[ "$DISABLE_PASS" = "y" ] && echo "- Password auth: DISABLED"
echo ""
echo "⚠️ IMPORTANT:"
echo "1. Test your SSH connection in a new terminal"
echo "2. Keep this terminal open until you verify access"
echo "3. Update firewall if you changed the port"
echo "4. Make sure you have SSH keys if you disabled passwords"
Usage
# Run as root
sudo chmod +x ssh_hardening.sh
sudo ./ssh_hardening.sh
# Generate SSH key (recommended)
ssh-keygen -t ed25519 -C "[email protected]"
# Copy key to server
ssh-copy-id user@server
# Check fail2ban status
sudo fail2ban-client status sshd
Troubleshooting
Troubleshooting
Problem: Locked Myself Out
Solution: Restore backup via VPS control panel or physical access:
sudo cp /etc/ssh/sshd_config.backup.* /etc/ssh/sshd_config
sudo systemctl restart sshd
Problem: "sshd: command not found"
Solution: Install OpenSSH server:
sudo apt-get install openssh-server