Post

My Homeland Is Constantly Attacked

My Homeland Is Constantly Attacked: Securing Self-Hosted Infrastructure Against Relentless Brute Force Assaults

Introduction

The moment you expose any service to the internet, your infrastructure becomes a battlefield. As the Reddit user discovered when setting up their media server, modern homelabs and self-hosted environments face constant automated attacks - thousands of brute force attempts daily targeting SSH, web applications, and exposed APIs. This isn’t theoretical security theater; it’s an active war where botnets systematically probe every public IP address for vulnerabilities.

For DevOps professionals and systems administrators, these relentless attacks present both a technical challenge and a learning opportunity. Your “homeland” - whether it’s a home lab, development environment, or production infrastructure - requires enterprise-grade security practices scaled down for personal use. This comprehensive guide explores why these attacks happen, how to defend against them, and why blocking entire countries might be less effective than you think.

Through this 4000-word technical deep dive, you’ll learn:

  • The anatomy of modern SSH brute force attacks
  • Advanced fail2ban configuration strategies
  • SSH hardening techniques beyond port changing
  • Network-layer defenses using firewalls and VPNs
  • Resource optimization for security services
  • Alternative approaches like SSH certificate authorities

Understanding Modern SSH Brute Force Attacks

The Anatomy of an Attack

Automated SSH attacks follow a predictable pattern:

  1. Scanning: Botnets scan entire IP ranges for open port 22 (or alternative ports)
  2. Fingerprinting: Systems are probed for SSH versions and supported auth methods
  3. Credential Stuffing: Automated attempts using common username/password pairs
  4. Persistence: Successful compromises lead to backdoor installation for DDoS participation

Recent data from Shadowserver Foundation shows over 15 million SSH brute force attempts per day across their honeypot network. The most common attack patterns include:

Username AttemptsPassword AttemptsFrequency
root12345623.7%
adminpassword18.2%
ubuntuubuntu12.1%
useradmin9.4%

Why Changing SSH Ports Isn’t Enough

While moving SSH to a non-standard port reduces noise, it’s not a security measure. Modern scanners:

  1. Check all ports in the 1-65535 range
  2. Use protocol detection rather than port assumptions
  3. Share target information between botnet nodes

A Shodan scan for SSH services reveals over 22 million exposed systems, with attackers constantly refining their scanning techniques.

The Geo-Blocking Dilemma

Blocking entire countries (like China or Russia) seems tempting but:

  1. False Positives: Block legitimate users/collaborators
  2. Evasion: Attackers use proxies/VPNs in allowed regions
  3. Maintenance: IP ranges change frequently (see MaxMind GeoLite2)
  4. Ethics: May conflict with open internet principles

A more effective approach combines multiple defense layers:

graph TD
    A[Network Layer] --> B[Firewall Rules]
    A --> C[VPN Access]
    B --> D[Port Knocking]
    C --> E[SSH Guard]
    D --> F[Fail2Ban]
    E --> G[SSH Key Auth]
    F --> H[Rate Limiting]

Prerequisites for Secure Self-Hosting

System Requirements

  1. Hardware: Minimum 2GB RAM (for security services), x86_64 architecture
  2. OS: Linux distribution with LTS support (Ubuntu 22.04+, Debian 11+)
  3. Network: Static IP or dynamic DNS solution (Cloudflare, DuckDNS)

Required Software Stack

ComponentMinimum VersionPurpose
OpenSSH Server8.9+Secure remote access
fail2ban0.11+Brute force protection
UFW0.36+Firewall management
WireGuard1.0.20210914+VPN alternative to Tailscale
CrowdSec1.5+Collaborative security (optional)

Security Pre-Checks

Before installation:

  1. Confirm no existing SSH keys in ~/.ssh/authorized_keys
  2. Verify system time synchronization:
    1
    
    timedatectl status | grep "System clock synchronized"
    
  3. Check for existing firewall rules:
    1
    
    sudo ufw status verbose
    
  4. Update all packages:
    1
    
    sudo apt update && sudo apt full-upgrade -y
    

Installation & Security Hardening

SSH Server Hardening

  1. Edit SSH configuration:
    1
    
    sudo nano /etc/ssh/sshd_config
    

    Critical settings:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    Port 22222  # Change from default 22
    PermitRootLogin prohibit-password
    PasswordAuthentication no
    PermitEmptyPasswords no
    MaxAuthTries 3
    LoginGraceTime 30
    ClientAliveInterval 300
    ClientAliveCountMax 2
    AllowUsers your_username
    
  2. Generate SSH keys:
    1
    
    ssh-keygen -t ed25519 -a 100 -f ~/.ssh/server_access
    
  3. Restart SSH service:
    1
    
    sudo systemctl restart sshd && sudo systemctl status sshd
    

Advanced fail2ban Configuration

  1. Install with logging support:
    1
    
    sudo apt install fail2ban -y
    
  2. Create custom jail:
    1
    
    sudo nano /etc/fail2ban/jail.d/custom.conf
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    [sshd]
    enabled = true
    port = 22222
    filter = sshd
    logpath = /var/log/auth.log
    maxretry = 3
    findtime = 1h
    bantime = 1w
    ignoreip = 192.168.1.0/24
    
  3. Memory-Optimized Filter (to reduce 500MB usage):
    1
    
    sudo nano /etc/fail2ban/filter.d/sshd.conf
    

    Add performance improvements:

    1
    2
    
    prefork = 5
    maxchildren = 20
    
  4. Enable and verify:
    1
    2
    
    sudo systemctl enable fail2ban --now
    sudo fail2ban-client status sshd
    

Firewall Configuration with UFW

  1. Basic ruleset:
    1
    2
    3
    
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw allow 22222/tcp comment 'SSH Access'
    
  2. Enable logging:
    1
    
    sudo ufw logging medium
    
  3. Activate firewall:
    1
    
    sudo ufw enable
    

Configuration & Optimization Strategies

SSH Performance Tuning

For high-connection environments:

1
2
3
4
5
# /etc/ssh/sshd_config
MaxStartups 30:50:100
MaxSessions 50
TCPKeepAlive no
Compression delayed

fail2ban Resource Management

To prevent 500MB memory usage:

  1. Reduce database cache:
    1
    2
    
    # /etc/fail2ban/fail2ban.conf
    dbmax = 5000  # Default: 10000
    
  2. Optimize logging:
    1
    
    sudo journalctl --vacuum-size=100M
    
  3. Monitor performance:
    1
    2
    
    fail2ban-client status
    fail2ban-client get sshd maxlines
    

VPN Fallback Options

When direct SSH isn’t viable (public networks blocking ports):

WireGuard Setup:

  1. Generate keys:
    1
    2
    
    wg genkey | sudo tee /etc/wireguard/private.key
    sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
    
  2. Create configuration:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # /etc/wireguard/wg0.conf
    [Interface]
    Address = 10.8.0.1/24
    ListenPort = 51820
    PrivateKey = <server_private_key>
       
    [Peer]
    PublicKey = <client_public_key>
    AllowedIPs = 10.8.0.2/32
    
  3. Enable service:
    1
    
    sudo systemctl enable wg-quick@wg0 --now
    

Usage & Operational Maintenance

Daily Security Checks

  1. Review authentication logs:
    1
    
    sudo journalctl -u sshd --since "24 hours ago" | grep "Failed"
    
  2. fail2ban management:
    1
    2
    3
    4
    5
    
    # Unban IP
    sudo fail2ban-client set sshd unbanip 192.0.2.1
       
    # Export banned list
    sudo fail2ban-client get sshd banned
    
  3. Firewall status:
    1
    
    sudo ufw status numbered
    

Automated Monitoring Script

Create /usr/local/bin/security_check:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

# Check SSH connections
ss -Hntp | grep 'ssh' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c

# Check fail2ban memory
ps -o pid,user,%mem,command ax | grep fail2ban | sort -bnr -k3

# Check UFW logs
sudo tail -20 /var/log/ufw.log | grep 'BLOCK'

Make executable:

1
sudo chmod +x /usr/local/bin/security_check

Troubleshooting Common Issues

High fail2ban Memory Usage

Symptoms: 500MB+ RAM consumption
Solutions:

  1. Reduce database size:
    1
    
    dbpurgeage = 1d
    
  2. Adjust logging verbosity:
    1
    
    loglevel = WARNING
    
  3. Limit ban time:
    1
    
    bantime = 1h
    

SSH Connection Drops

Diagnosis:

1
sudo tcpdump -i eth0 'port 22222' -w ssh.pcap

Common Fixes:

  1. Adjust keepalive settings
  2. Check for MTU mismatches
  3. Verify firewall session tracking:
    1
    
    conntrack -L | grep 22222
    

False Positive Bans

Recovery Steps:

  1. Temporarily disable fail2ban:
    1
    
    sudo fail2ban-client stop
    
  2. Whitelist your IP:
    1
    2
    
    # /etc/fail2ban/jail.local
    ignoreip = 203.0.113.5
    
  3. Use more precise filters:
    1
    
    failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>
    

Conclusion: Building a Resilient Homeland

Securing self-hosted infrastructure against relentless attacks requires depth in defense. Through this guide, we’ve implemented:

  1. SSH hardening with key-based authentication and rate limiting
  2. fail2ban optimization to reduce resource consumption
  3. Firewall configuration using UFW
  4. VPN alternatives for secure remote access

While blocking entire regions might provide temporary relief, the real solution lies in comprehensive security practices:

  1. Regular updates and patch management
  2. Log monitoring with automated alerts
  3. Defense in depth combining network and application layers

For further learning, explore:

Remember: Security isn’t a destination but a continuous process of adaptation. Your homeland’s defenses must evolve as threats do.

This post is licensed under CC BY 4.0 by the author.