Linux SSH Security: Unhackable Server Configuration 2025 | SistemDC

Linux Server Security: A Guide to Making SSH Unhackable

Linux Server Security: A Guide to Making SSH Unhackable

Linux Server Security: A Guide to Making SSH Unhackable

In 2023 someone tried to break into one of our customers' servers: 12,400 failed SSH logins within 48 hours. Not one succeeded. Why? Because we had configured SSH security correctly. In this article we explain how to harden a Linux server, which SSH settings you need to make and which tools to use. Spoiler: disabling root login is not enough.

Why Is SSH Security So Important?

SSH (Secure Shell) is the standard way to connect to Linux servers remotely. But an SSH service running with default settings is an open door for attackers.

A Real Statistic: In our SistemDC data center we detect an average of 8,500 SSH brute-force attacks a day. An unprotected server becomes a target within the first 24 hours.

SSH Hardening in 10 Steps

Step 1: Disable Root Login

Allowing direct SSH connections as the root user is the biggest security hole. First create a user with sudo privileges:

# Create a new user
adduser sistemadmin

# Grant sudo privileges
usermod -aG sudo sistemadmin

# Edit the SSH config
nano /etc/ssh/sshd_config

# Find and change this line:
PermitRootLogin no

# Restart SSH
systemctl restart sshd

Step 2: Change the SSH Port

The default port 22 is the first target for bots. Using a different port blocks 95% of automated attacks.

# /etc/ssh/sshd_config
Port 49222

# Open the new port in the firewall
ufw allow 49222/tcp
ufw delete allow 22/tcp

# Restart SSH
systemctl restart sshd
Important: Do not close your current connection until you are sure you can connect on the new port! Open a new terminal to test.

Step 3: SSH Key Authentication (Passwordless Login)

Using an SSH key instead of a password renders brute-force attacks 100% ineffective.

# On your local computer (Mac/Linux)
ssh-keygen -t ed25519 -C "admin@sistemdc.com"

# Copy the public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub sistemadmin@server_ip -p 49222

# Disable password login on the server
# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes

systemctl restart sshd

Step 4: Installing Fail2Ban

Fail2Ban monitors failed login attempts and blocks the attacker automatically.

# Installation
apt install fail2ban

# Configuration
nano /etc/fail2ban/jail.local

[sshd]
enabled = true
port = 49222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

# Start
systemctl enable fail2ban
systemctl start fail2ban

# To see banned IPs
fail2ban-client status sshd

Meaning: 3 failed attempts within 10 minutes (600 seconds) = a 1-hour ban.

Step 5: Two-Factor Authentication (2FA)

In addition to the SSH key, add 2FA with Google Authenticator.

# Install the Google Authenticator PAM module
apt install libpam-google-authenticator

# Run as the user (not root!)
su - sistemadmin
google-authenticator

# Answers to the questions:
# - Time-based tokens? y
# - Update .google_authenticator? y
# - Disallow multiple uses? y
# - Increase time skew? n
# - Rate limiting? y

# PAM setting
nano /etc/pam.d/sshd
# Add:
auth required pam_google_authenticator.so

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

systemctl restart sshd

Step 6: IP Whitelist (Specific IPs Only)

If you have a static IP, allow SSH connections only from that IP.

# IP restriction with UFW
ufw allow from 85.34.12.45 to any port 49222 proto tcp

# Deny all other connections
ufw deny 49222/tcp

# Alternative: /etc/ssh/sshd_config
AllowUsers sistemadmin@85.34.12.45

Step 7: SSH Banner and Timeout Settings

# /etc/ssh/sshd_config

# Show a banner (warning message)
Banner /etc/ssh/banner.txt

# Idle connection timeout (5 minutes)
ClientAliveInterval 300
ClientAliveCountMax 2

# Login timeout (1 minute)
LoginGraceTime 60

# Maximum auth attempts
MaxAuthTries 3

# Maximum concurrent sessions
MaxSessions 2

Step 8: SSH Protocol and Encryption

# /etc/ssh/sshd_config

# SSH Protocol 2 only (1 is insecure)
Protocol 2

# Strong encryption algorithms
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com

# Strong MAC algorithms
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# Strong Key Exchange
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org

Step 9: Log Monitoring

Monitor SSH connections continuously.

# View recent SSH logins
last -a | head -20

# Failed login attempts
grep "Failed password" /var/log/auth.log | tail -50

# Live log tracking
tail -f /var/log/auth.log

# Get a daily report by installing Logwatch
apt install logwatch
logwatch --detail High --mailto admin@sistemdc.com --service sshd

Step 10: Port Knocking (Advanced)

Keep the SSH port closed by default and knock on the "secret door" before connecting.

# knockd installation
apt install knockd

# Configuration: /etc/knockd.conf
[options]
logfile = /var/log/knockd.log

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 49222 -j ACCEPT
tcpflags = syn

[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 49222 -j ACCEPT
tcpflags = syn

# Usage (from the local computer)
knock server_ip 7000 8000 9000
ssh sistemadmin@server_ip -p 49222

Security Testing: Attack Yourself

To test your configuration, simulate an attack on your own server:

# Install the SSH audit tool
pip3 install ssh-audit

# Scan the server
ssh-audit server_ip:49222

# Port scan with Nmap
nmap -p 1-65535 server_ip

# Lynis security audit
apt install lynis
lynis audit system

Default Security at SistemDC

On SistemDC servers, basic security measures are active from the initial setup:

  • Root login disabled (delivered with a sudo user)
  • Fail2Ban pre-installed and configured
  • UFW firewall active
  • Daily security updates (unattended-upgrades)
  • SSH port change (optional)
  • DDoS protection (at network level)
Additional Service: With the Managed Security package we offer 24/7 security monitoring, log analysis and emergency response. Prices start from 500 TL a month.

Backups and Disaster Recovery

Security measures do not provide 100% protection. Backups are a must:

# Automatic backup script
nano /usr/local/bin/backup.sh

#!/bin/bash
BACKUP_DIR="/backup/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR

# Database backup
mysqldump --all-databases > $BACKUP_DIR/databases.sql

# Web files
tar -czf $BACKUP_DIR/web.tar.gz /var/www

# SSH config
cp -r /etc/ssh $BACKUP_DIR/

# Delete backups older than 7 days
find /backup -type d -mtime +7 -exec rm -rf {} \;

# Run daily with cron
crontab -e
0 2 * * * /usr/local/bin/backup.sh

Would You Like a Server Security Analysis?

Let us analyse the security status of your current server free of charge. We will identify the vulnerabilities and report them.

Contact:
satis@sistemdc.com
Corporate WhatsApp: +90 224 334 02 42

Conclusion: Layers of Security

SSH security is not a single setting; it requires a layered approach:

  1. Root login disabled
  2. SSH key authentication
  3. Port change
  4. Fail2Ban
  5. 2FA (Two-factor)
  6. IP whitelist (if possible)
  7. Log monitoring
  8. Regular security updates

A server that applies these 10 steps is 99.98% protected against brute-force attacks. In our 14 years of experience, none of our properly configured servers has been hacked over SSH.


Note: The commands in this article have been tested on Ubuntu 24.04, Debian 12 and derivatives. Always take a backup before making changes on a production server. The security configuration should be tailored to the system and use case.

Server packages covered in this article

+902243340242