SSHfail2banLinux6 min read

Basic Linux hardening

Secure SSH configuration, fail2ban, automatic updates and non-root user setup.


Overview

Server hardening reduces your attack surface by disabling unnecessary services, restricting access, and enabling automatic security updates. These steps should be applied to every new server.

Step 1: Secure SSH configuration

Edit the SSH daemon configuration:

bash
sudo nano /etc/ssh/sshd_config

Apply these security settings:

terminal
# Disable root login
PermitRootLogin no

# Disable password authentication (use keys only)
PasswordAuthentication no

# Change default port (optional but reduces noise)
Port 2222

# Limit login attempts
MaxAuthTries 3

# Disable empty passwords
PermitEmptyPasswords no

# Disable X11 forwarding
X11Forwarding no

# Set idle timeout (5 minutes)
ClientAliveInterval 300
ClientAliveCountMax 2

# Restrict to specific users
AllowUsers deploy

Restart SSH:

bash
sudo systemctl restart sshd

Important: Test the new configuration in a separate terminal before closing your current session.

Step 2: Install and configure fail2ban

fail2ban monitors log files and bans IPs that show malicious behavior:

bash
sudo apt install -y fail2ban

Create a local configuration:

bash
sudo nano /etc/fail2ban/jail.local
ini
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = ufw

[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 86400

[sshd-ddos]
enabled = true
port = 2222

Start and enable:

bash
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Check status:

bash
sudo fail2ban-client status
sudo fail2ban-client status sshd

Step 3: Enable automatic security updates

Install unattended-upgrades:

bash
sudo apt install -y unattended-upgrades apt-listchanges
sudo dpkg-reconfigure -plow unattended-upgrades

Configure what gets updated:

bash
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Ensure security updates are enabled:

terminal
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};

Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";

Enable automatic checks:

bash
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
terminal
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";

Step 4: Disable unnecessary services

List running services and disable what you don't need:

bash
sudo systemctl list-units --type=service --state=running

# Common services to disable if not needed
sudo systemctl disable --now cups
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now bluetooth

Step 5: Kernel hardening with sysctl

bash
sudo nano /etc/sysctl.d/99-security.conf
ini
# Prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Enable SYN flood protection
net.ipv4.tcp_syncookies = 1

# Log suspicious packets
net.ipv4.conf.all.log_martians = 1

Apply:

bash
sudo sysctl --system

Step 6: Audit with Lynis

Lynis performs a comprehensive security audit:

bash
sudo apt install -y lynis
sudo lynis audit system

Review the report and address warnings. Focus on:

  • Items marked [WARNING]
  • Suggestions with high priority
  • Hardening index score (aim for 70+)

Step 7: Set up login notifications

Get notified of successful SSH logins:

bash
sudo nano /etc/profile.d/login-notify.sh
bash
#!/bin/bash
if [ -n "$SSH_CLIENT" ]; then
  WEBHOOK="https://discord.com/api/webhooks/YOUR_WEBHOOK"
  IP=$(echo $SSH_CLIENT | awk '{print $1}')
  curl -s -H "Content-Type: application/json" \
    -d "{\"content\":\"🔐 SSH login: $(whoami)@$(hostname) from $IP at $(date)\"}" \
    $WEBHOOK
fi
bash
sudo chmod +x /etc/profile.d/login-notify.sh

Security checklist

  • SSH key-only authentication
  • Root login disabled
  • fail2ban active
  • Automatic security updates enabled
  • Firewall configured (UFW)
  • Unnecessary services disabled
  • Kernel parameters hardened
  • Regular Lynis audits scheduled

Was this guide helpful?