Complete Guide to Setting Up and Hardening SSH on Ubuntu and CentOS

SSH is the primary gateway to your ServerRaja cloud server, which makes it the number one target for attackers. Automated bots constantly scan for SSH servers on the default port, attempting brute-force attacks with common usernames and passwords. Hardening SSH is not optional — it is a fundamental security requirement for any production server. This guide walks through every step, from initial setup to advanced hardening, on both Ubuntu and CentOS.
Initial SSH Setup
When you first provision a ServerRaja Cloud VPS, SSH is typically enabled with password authentication. Your first task is to switch to key-based authentication and disable passwords entirely.
Generate an SSH Key Pair
On your local machine (not the server), generate a strong key pair:
# Generate an Ed25519 key (recommended, fast and secure)
ssh-keygen -t ed25519 -C "yourname@serverraja"# Or RSA 4096-bit if Ed25519 is not supported ssh-keygen -t rsa -b 4096 -C "yourname@serverraja" ```
This creates `~/.ssh/id_ed25519` (private) and `~/.ssh/id_ed25519.pub` (public). Never share the private key. Copy the public key to your server:
# Using ssh-copy-id (easiest method)
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@your-server-ip# Or manually cat ~/.ssh/id_ed25519.pub | ssh root@your-server-ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" ```
Test Key-Based Login
Before disabling password authentication, verify key-based login works:
ssh -i ~/.ssh/id_ed25519 root@your-server-ip
If you can log in without entering a password, you are ready to harden the configuration.
Hardening the SSH Daemon Configuration
The SSH server configuration lives at `/etc/ssh/sshd_config`. Open it in your preferred editor and apply these changes:
# /etc/ssh/sshd_config - Recommended hardened configuration# Change default port (reduces automated attacks by 99%) Port 2222
# Disable root login (create a sudo user first) PermitRootLogin no
# Disable password authentication entirely PasswordAuthentication no PubkeyAuthentication yes
# Disable empty passwords PermitEmptyPasswords no
# Limit authentication attempts MaxAuthTries 3
# Set login grace time LoginGraceTime 30
# Restrict to specific users (replace with your username) AllowUsers deployer admin
# Disable X11 forwarding (not needed on servers) X11Forwarding no
# Disable TCP forwarding unless specifically needed AllowTcpForwarding no
# Disable agent forwarding AllowAgentForwarding no
# Use only SSH protocol 2 Protocol 2
# Set idle timeout (disconnect after 5 min inactivity) ClientAliveInterval 300 ClientAliveCountMax 2
# Disable host-based authentication HostbasedAuthentication no
# Restrict to IPv4 or IPv6 if needed AddressFamily inet ```
Modern Cipher Configuration
Restrict SSH to strong ciphers, removing weak or deprecated algorithms:
# Strong ciphers only
Ciphers [email protected],[email protected],[email protected]# Strong MACs MACs [email protected],[email protected]
# Strong key exchange KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512
# Strong host key algorithms HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256 ```
After making changes, validate and restart SSH:
# Validate configuration (Ubuntu and CentOS)
sshd -t# Restart SSH - IMPORTANT: keep your current session open while testing! systemctl restart sshd
# On older CentOS, the service name might be 'ssh' systemctl restart ssh ```
**Critical Warning**: Always keep your current SSH session open when restarting the SSH daemon. Open a second terminal to test the new configuration before closing the original session. A syntax error in sshd_config can lock you out.
Configuring fail2ban
fail2ban monitors log files and bans IPs that show malicious patterns, such as repeated failed login attempts.
Ubuntu Installation
apt update && apt install -y fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
CentOS Installation
yum install -y epel-release
yum install -y fail2ban
Configuration
Edit `/etc/fail2ban/jail.local`:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
banaction = iptables-multiport[sshd] enabled = true port = 2222 filter = sshd logpath = /var/log/auth.log # Ubuntu # logpath = /var/log/secure # CentOS maxretry = 3 bantime = 86400 ```
Start and enable fail2ban:
systemctl enable fail2ban
systemctl start fail2ban# Check status fail2ban-client status sshd fail2ban-client set sshd banip 192.168.1.100 ```
Firewall Configuration for the New SSH Port
After changing the SSH port, update your firewall:
Ubuntu (UFW)
ufw allow 2222/tcp comment 'SSH'
ufw deny 22/tcp
ufw enable
ufw status verbose
CentOS (firewalld)
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --permanent --remove-service=ssh
firewall-cmd --reload
firewall-cmd --list-all
Two-Factor Authentication (Optional)
Add Google Authenticator for an extra layer of security:
# Ubuntu
apt install -y libpam-google-authenticator# CentOS yum install -y google-authenticator
# Run setup for your user google-authenticator ```
Edit `/etc/pam.d/sshd` and add at the top:
auth required pam_google_authenticator.so
In `/etc/ssh/sshd_config`, add:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Monitoring SSH Access
Regularly audit SSH access on your ServerRaja server:
# View recent SSH logins
last -20# View failed login attempts journalctl -u sshd --since "24 hours ago" | grep "Failed"
# Count failed attempts by IP grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# On CentOS, check /var/log/secure instead ```
These hardening steps significantly reduce the attack surface of your ServerRaja cloud server. Combined with regular security updates and monitoring, your SSH configuration will be robust against the vast majority of automated and targeted attacks.
Key Takeaways
- **Disable password authentication entirely** and use Ed25519 key pairs — this eliminates brute-force attacks that account for the vast majority of SSH compromise attempts.
- **Change the default SSH port** from 22 — this single change reduces automated scanning hits by roughly 99%, though it's not a substitute for key-based auth.
- **Configure `fail2ban`** with aggressive ban times to automatically block IPs after repeated failed attempts, and review its logs regularly.
- **Restrict SSH to specific users** via `AllowUsers` in `sshd_config` and disable root login — create a named sudo user for all administrative access.
- **After every `sshd_config` change**, keep your current session open and test the new configuration in a separate terminal to avoid locking yourself out.