Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsStudyTraining
ProjectsChecklistsAI RankingsNewsletterStatusTagsAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Study
Training
Projects
Checklists
AI Rankings
Newsletter
Status
Tags
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

429+ Articles
114+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. SSH Hardening Best Practices
SSH Hardening Best Practices
HOWTOBeginner

SSH Hardening Best Practices

Secure your SSH servers with essential hardening techniques including key-based authentication, fail2ban configuration, and advanced security measures.

Security Team

Security Engineering

January 28, 2026
6 min read

Prerequisites

  • Basic Linux command line
  • Access to a Linux server

Overview

SSH is the backbone of secure remote administration. A default installation leaves significant security gaps that attackers actively exploit. This guide covers essential hardening steps for production SSH servers.

Who Should Use This Guide

  • System administrators managing Linux servers
  • Security engineers auditing infrastructure
  • DevOps teams securing remote access

Why SSH Hardening Matters

Every internet-facing SSH server is constantly probed by automated bots. Without proper hardening:

  • Brute force attacks can eventually succeed
  • Default configurations expose unnecessary attack surface
  • Weak authentication methods create entry points for attackers

Requirements

System Requirements

ComponentRequirement
Operating SystemLinux (Debian/Ubuntu, RHEL/Rocky/Alma)
SSH ServerOpenSSH 8.0 or later
PrivilegesRoot/sudo access

Prerequisites

  • SSH server installed (openssh-server)
  • Network access to server (console access recommended as backup)
  • Basic understanding of public key cryptography

Process

Step 1: Generate SSH Key Pair

Create a strong key pair on your local machine (not the server).

Generate Ed25519 Key (Recommended):

ssh-keygen -t ed25519 -C "<identifier>"

Alternative - RSA 4096-bit:

ssh-keygen -t rsa -b 4096 -C "<identifier>"

Expected Output:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/<user>/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/<user>/.ssh/id_ed25519
Your public key has been saved in /home/<user>/.ssh/id_ed25519.pub

Important: Use a strong passphrase to protect the private key.


Step 2: Copy Public Key to Server

Transfer your public key to the target server.

Method 1 - Using ssh-copy-id:

ssh-copy-id -i ~/.ssh/id_ed25519.pub <username>@<server-ip>

Method 2 - Manual Copy:

cat ~/.ssh/id_ed25519.pub | ssh <username>@<server-ip> "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Verification:

# Test key-based login
ssh -i ~/.ssh/id_ed25519 <username>@<server-ip>

Expected Result: Login succeeds without password prompt (only passphrase if set).


Step 3: Configure SSH Daemon

Edit the SSH server configuration on the target server.

Open Configuration File:

sudo nano /etc/ssh/sshd_config

Essential Security Settings:

# Disable password authentication
PasswordAuthentication no
PubkeyAuthentication yes
 
# Disable root login
PermitRootLogin no
 
# Use Protocol 2 only
Protocol 2
 
# Limit authentication attempts
MaxAuthTries 3
 
# Set idle timeout (seconds)
ClientAliveInterval 300
ClientAliveCountMax 2
 
# Disable empty passwords
PermitEmptyPasswords no
 
# Disable X11 forwarding (if not needed)
X11Forwarding no
 
# Restrict to specific users
AllowUsers <your-admin-user>
 
# Use strong ciphers only
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org

Validate Configuration:

sudo sshd -t

Expected Output: No output indicates valid configuration.

Apply Changes:

sudo systemctl restart sshd

Warning: Keep an existing session open while testing to avoid lockout.


Step 4: Change Default Port (Optional)

Reduces automated scan noise. Security through obscurity alone is insufficient.

Edit Configuration:

# In /etc/ssh/sshd_config
Port <custom-port>  # Choose unused port above 1024

Update Firewall Before Restarting SSH:

# UFW
sudo ufw allow <custom-port>/tcp
 
# firewalld
sudo firewall-cmd --permanent --add-port=<custom-port>/tcp
sudo firewall-cmd --reload

Restart SSH:

sudo systemctl restart sshd

Verification:

ssh -p <custom-port> <username>@<server-ip>

Step 5: Install and Configure Fail2Ban

Automatically blocks IPs with excessive failed login attempts.

Installation:

# Debian/Ubuntu
sudo apt install fail2ban -y
 
# RHEL/Rocky/Alma
sudo dnf install fail2ban -y

Create Local Configuration:

sudo nano /etc/fail2ban/jail.local

Configuration Content:

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
banaction = iptables-multiport
 
[sshd]
enabled = true
port = ssh,<custom-port>
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h

Enable and Start:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Verification:

sudo fail2ban-client status sshd

Expected Output:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed: 0
|  `- File list: /var/log/auth.log
`- Actions
   |- Currently banned: 0
   |- Total banned: 0
   `- Banned IP list:

Step 6: Enable Two-Factor Authentication (Optional)

Adds TOTP-based second factor to SSH authentication.

Install Google Authenticator PAM:

sudo apt install libpam-google-authenticator -y

Configure for Your User:

google-authenticator

Follow prompts to configure TOTP. Save backup codes securely.

Update PAM Configuration:

# Add to /etc/pam.d/sshd
auth required pam_google_authenticator.so

Update SSH Configuration:

# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

Restart SSH:

sudo systemctl restart sshd

Step 7: Monitor SSH Access

Regular log review detects unauthorized access attempts.

View Recent Successful Logins:

grep "Accepted" /var/log/auth.log | tail -20

View Failed Attempts:

grep "Failed password" /var/log/auth.log | tail -20

View Invalid User Attempts:

grep "Invalid user" /var/log/auth.log | tail -20

Check Currently Banned IPs:

sudo fail2ban-client status sshd

Troubleshooting

SymptomPossible CauseSolution
Permission denied (publickey)Key not copied correctlyVerify ~/.ssh/authorized_keys contains your public key
Connection refused after config changeSSH service not running or wrong portCheck systemctl status sshd and firewall rules
Locked out of serverPassword auth disabled before key setupUse console access to fix configuration
Fail2ban not banningWrong log path or filterVerify logpath matches system auth log location
2FA not promptingPAM not configured correctlyCheck /etc/pam.d/sshd configuration order

Verification Checklist

Before considering SSH hardened, verify:

  • Password authentication disabled
  • Root login disabled
  • Key-based authentication working
  • Fail2ban installed and running
  • Strong ciphers configured
  • Firewall rules allow SSH port only
  • Authentication logs being monitored
  • Backup access method available (console)

Common Mistakes to Avoid

MistakeConsequencePrevention
Disabling password auth before testing keysLockoutAlways test key login in separate session first
Weak key passphrasesPrivate key compromiseUse strong, unique passphrases
Forgetting firewall rulesLockout after port changeUpdate firewall before changing SSH port
Not backing up keysLost accessSecure backup of private keys
Ignoring logsMissed intrusion attemptsAutomate log review and alerting

References

  • OpenSSH Security Best Practices
  • CIS Benchmarks for Linux
  • Fail2ban Documentation

Last Updated: January 2026

Related Reading

  • Server Hardening Security Checklist
  • Domain Controller Hardening: Securing Active Directory
  • Windows Server Hardening: Complete Security Guide for
#SSH#Security#Linux#Hardening#Server Administration

Related Articles

Domain Controller Hardening: Securing Active Directory

Comprehensive DC hardening guide covering tier model implementation, LDAP signing, NTLM restrictions, Kerberos hardening, AdminSDHolder, DSRM security,...

46 min read

Windows Server Hardening: Complete Security Guide for

Step-by-step Windows Server hardening covering CIS benchmarks, attack surface reduction, service hardening, firewall rules, credential protection, and...

43 min read

Linux Server Hardening: Complete Security Checklist

Comprehensive guide to hardening Linux servers covering user management, service configuration, kernel security, and ongoing maintenance for production systems.

8 min read
Back to all HOWTOs