Skip to content

Instantly share code, notes, and snippets.

@barthez-kenwou
Created June 19, 2026 14:58
Show Gist options
  • Select an option

  • Save barthez-kenwou/f0c31d0a133fa1b904f757d04fc52948 to your computer and use it in GitHub Desktop.

Select an option

Save barthez-kenwou/f0c31d0a133fa1b904f757d04fc52948 to your computer and use it in GitHub Desktop.
Enterprise SSH Hardening Script

Enterprise SSH Hardening Script

Overview

Secure Shell (SSH) is one of the most critical services exposed on Linux servers.

A poorly configured SSH server can lead to:

  • Brute-force attacks
  • Credential stuffing
  • Privilege escalation
  • Unauthorized remote access
  • Lateral movement within infrastructure

This script automates the hardening of OpenSSH servers following modern security best practices.


Objectives

This hardening script aims to:

  • Reduce attack surface
  • Enforce strong authentication
  • Disable insecure configurations
  • Improve auditability
  • Protect production servers

Security Features

  • Automatic backup
  • Disable root login
  • Disable password authentication
  • Public key authentication only
  • Limit authentication attempts
  • Disable empty passwords
  • Disable X11 forwarding
  • Disable agent forwarding
  • Disable TCP forwarding
  • Restrict login grace period
  • Configure idle session timeout
  • Validate SSH configuration
  • Safe service restart

Security Recommendations

Before running this script:

  1. Ensure your SSH public key is installed.
ssh-copy-id user@server
  1. Verify public key authentication works.
ssh user@server
  1. Open a second SSH session before applying changes.

Never harden SSH without testing key-based access first.


Script

ssh-hardening.sh

#!/usr/bin/env bash

##########################################################
# Enterprise SSH Hardening Script
#
# Author: DevSecOps Community
#
# Tested on:
# - Ubuntu
# - Debian
# - Rocky Linux
# - AlmaLinux
# - CentOS
##########################################################

set -e

SSH_CONFIG="/etc/ssh/sshd_config"

BACKUP_DIR="/etc/ssh/backups"

TIMESTAMP=$(date +%Y%m%d-%H%M%S)

BACKUP_FILE="$BACKUP_DIR/sshd_config.$TIMESTAMP"

##########################################################
# Root Check
##########################################################

if [ "$EUID" -ne 0 ]; then
    echo "Please run as root."
    exit 1
fi

##########################################################
# Create Backup
##########################################################

echo "[+] Creating backup..."

mkdir -p "$BACKUP_DIR"

cp "$SSH_CONFIG" "$BACKUP_FILE"

echo "[+] Backup created:"
echo "$BACKUP_FILE"

##########################################################
# Apply Hardening
##########################################################

echo "[+] Applying SSH hardening..."

cat > "$SSH_CONFIG" <<EOF

##########################################################
# Enterprise Hardened SSH Configuration
##########################################################

Port 22

Protocol 2

PermitRootLogin no

PubkeyAuthentication yes

PasswordAuthentication no

KbdInteractiveAuthentication no

ChallengeResponseAuthentication no

PermitEmptyPasswords no

MaxAuthTries 3

MaxSessions 2

LoginGraceTime 30

ClientAliveInterval 300

ClientAliveCountMax 2

AllowAgentForwarding no

AllowTcpForwarding no

GatewayPorts no

PermitTunnel no

X11Forwarding no

PermitUserEnvironment no

IgnoreRhosts yes

HostbasedAuthentication no

UsePAM yes

PrintMotd no

TCPKeepAlive no

Compression no

LogLevel VERBOSE

Subsystem sftp /usr/lib/openssh/sftp-server

EOF

##########################################################
# Validate Configuration
##########################################################

echo "[+] Validating configuration..."

sshd -t

echo "[+] Configuration valid."

##########################################################
# Restart SSH
##########################################################

echo "[+] Restarting SSH service..."

if systemctl is-active --quiet ssh; then
    systemctl restart ssh
elif systemctl is-active --quiet sshd; then
    systemctl restart sshd
fi

echo "[+] SSH hardening completed successfully."

Configuration Breakdown

Disable Root Login

PermitRootLogin no

Prevents direct root access.

Benefits:

  • Limits privilege escalation
  • Forces accountability
  • Improves auditing

Disable Password Authentication

PasswordAuthentication no

Only SSH keys can be used.

Benefits:

  • Stops brute-force attacks
  • Eliminates weak passwords
  • Stronger authentication

Disable Empty Passwords

PermitEmptyPasswords no

Prevents authentication without credentials.


Limit Login Attempts

MaxAuthTries 3

Reduces brute-force effectiveness.


Restrict Session Creation

MaxSessions 2

Limits concurrent sessions.


Session Timeout

ClientAliveInterval 300
ClientAliveCountMax 2

Disconnects inactive users.

Benefits:

  • Reduces hijacked sessions
  • Improves resource management

Disable TCP Forwarding

AllowTcpForwarding no

Prevents SSH tunnel abuse.


Disable Agent Forwarding

AllowAgentForwarding no

Reduces credential theft risks.


Disable X11 Forwarding

X11Forwarding no

Reduces attack surface.


Increase Logging

LogLevel VERBOSE

Provides detailed audit information.

Useful for:

  • Incident response
  • Compliance
  • Forensics

Recommended Additional Protection

Install Fail2Ban

sudo apt install fail2ban

Protects against:

  • Brute-force attacks
  • Password spraying
  • Credential stuffing

UFW Firewall

sudo ufw allow 22/tcp
sudo ufw enable

Restricts network exposure.


Change SSH Port (Optional)

Port 2222

Not a security control by itself.

Only reduces automated scans.


Restrict Users

AllowUsers devops

or

AllowGroups sshusers

Limits who can connect.


Verification

Verify configuration:

sshd -T

Check service status:

systemctl status ssh

Test connection:

ssh user@server

Security Checklist

  • Backup configuration
  • Disable root login
  • Disable password authentication
  • Public key authentication only
  • Limit authentication attempts
  • Session timeout
  • Disable forwarding
  • Increased logging
  • Validate configuration
  • Safe restart

Production Recommendations

For enterprise environments, combine this hardening with:

  • Fail2Ban
  • CrowdSec
  • MFA authentication
  • Bastion hosts
  • VPN access
  • SIEM monitoring
  • SSH certificate authorities
  • Centralized logging
  • Infrastructure as Code

Final Thoughts

SSH is often the primary administrative entry point into Linux servers.

A secure SSH configuration significantly reduces the attack surface and helps protect infrastructure from unauthorized access, brute-force attacks, and privilege escalation attempts.

Hardening SSH should be one of the first security controls applied to every production server.

#!/usr/bin/env bash
##########################################################
# Enterprise SSH Hardening Script
#
# Author: DevSecOps Community
#
# Tested on:
# - Ubuntu
# - Debian
# - Rocky Linux
# - AlmaLinux
# - CentOS
##########################################################
set -e
SSH_CONFIG="/etc/ssh/sshd_config"
BACKUP_DIR="/etc/ssh/backups"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="$BACKUP_DIR/sshd_config.$TIMESTAMP"
##########################################################
# Root Check
##########################################################
if [ "$EUID" -ne 0 ]; then
echo "Please run as root."
exit 1
fi
##########################################################
# Create Backup
##########################################################
echo "[+] Creating backup..."
mkdir -p "$BACKUP_DIR"
cp "$SSH_CONFIG" "$BACKUP_FILE"
echo "[+] Backup created:"
echo "$BACKUP_FILE"
##########################################################
# Apply Hardening
##########################################################
echo "[+] Applying SSH hardening..."
cat > "$SSH_CONFIG" <<EOF
##########################################################
# Enterprise Hardened SSH Configuration
##########################################################
Port 22
Protocol 2
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 2
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
PermitTunnel no
X11Forwarding no
PermitUserEnvironment no
IgnoreRhosts yes
HostbasedAuthentication no
UsePAM yes
PrintMotd no
TCPKeepAlive no
Compression no
LogLevel VERBOSE
Subsystem sftp /usr/lib/openssh/sftp-server
EOF
##########################################################
# Validate Configuration
##########################################################
echo "[+] Validating configuration..."
sshd -t
echo "[+] Configuration valid."
##########################################################
# Restart SSH
##########################################################
echo "[+] Restarting SSH service..."
if systemctl is-active --quiet ssh; then
systemctl restart ssh
elif systemctl is-active --quiet sshd; then
systemctl restart sshd
fi
echo "[+] SSH hardening completed successfully."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment