How to protect Linux server from brute-force attacks
How to Protect Linux Server from Brute-Force Attacks
Brute-force attacks represent one of the most persistent and common threats facing Linux servers today. These attacks involve automated attempts to gain unauthorized access by systematically trying different combinations of usernames and passwords until the correct credentials are discovered. Understanding how to effectively protect your Linux server from these attacks is crucial for maintaining system security and preventing unauthorized access.
This comprehensive guide will walk you through multiple layers of defense against brute-force attacks, from basic SSH hardening to advanced intrusion detection systems. You'll learn practical, implementable solutions that can significantly reduce your server's vulnerability to these persistent threats.
Prerequisites and Requirements
Before implementing the security measures outlined in this guide, ensure you have:
- Root or sudo access to your Linux server
- Basic familiarity with command-line operations
- SSH access to your server (preferably from a secure location)
- A backup plan in case configuration changes lock you out
- Understanding of your server's current network configuration
Supported Linux Distributions
The techniques in this guide work across major Linux distributions including:
- Ubuntu (18.04, 20.04, 22.04)
- CentOS/RHEL (7, 8, 9)
- Debian (9, 10, 11)
- Fedora (recent versions)
- SUSE Linux Enterprise Server
Understanding Brute-Force Attacks
What Are Brute-Force Attacks?
Brute-force attacks are systematic attempts to gain access to your server by trying numerous username and password combinations. Attackers typically use automated tools that can attempt thousands of login combinations per minute, targeting common services like SSH, FTP, and web applications.
Common Attack Vectors
SSH Brute-Force Attacks: The most common type, targeting port 22 (or custom SSH ports) with automated login attempts.
Web Application Attacks: Targeting login pages of web applications, content management systems, and admin panels.
Database Attacks: Attempting to access database services like MySQL, PostgreSQL, or MongoDB.
Mail Server Attacks: Targeting SMTP, POP3, and IMAP services for email server access.
SSH Hardening: Your First Line of Defense
1. Change the Default SSH Port
The default SSH port (22) is constantly scanned by attackers. Changing it significantly reduces automated attack attempts.
```bash
Edit SSH configuration
sudo nano /etc/ssh/sshd_config
Change the port (uncomment and modify)
Port 2222
Restart SSH service
sudo systemctl restart sshd
```
Important Warning: Before restarting SSH, ensure your firewall allows the new port:
```bash
For UFW (Ubuntu)
sudo ufw allow 2222/tcp
sudo ufw delete allow 22/tcp
For firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --remove-port=22/tcp
sudo firewall-cmd --reload
```
2. Disable Root Login
Preventing direct root access forces attackers to compromise a regular user account first, then escalate privileges.
```bash
Edit SSH configuration
sudo nano /etc/ssh/sshd_config
Find and modify this line
PermitRootLogin no
Restart SSH service
sudo systemctl restart sshd
```
3. Implement Key-Based Authentication
Password authentication is inherently vulnerable to brute-force attacks. SSH keys provide much stronger security.
Generate SSH Key Pair (on your local machine):
```bash
Generate a strong SSH key pair
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Or use Ed25519 for better security and performance
ssh-keygen -t ed25519 -C "your_email@example.com"
```
Copy Public Key to Server:
```bash
Copy key to server
ssh-copy-id -i ~/.ssh/id_rsa.pub username@server_ip -p 2222
Or manually copy the key
cat ~/.ssh/id_rsa.pub | ssh username@server_ip -p 2222 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
```
Disable Password Authentication:
```bash
Edit SSH configuration
sudo nano /etc/ssh/sshd_config
Disable password authentication
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
Restart SSH service
sudo systemctl restart sshd
```
4. Configure SSH Connection Limits
Limit the number of concurrent SSH connections and authentication attempts:
```bash
Edit SSH configuration
sudo nano /etc/ssh/sshd_config
Add these configurations
MaxAuthTries 3
MaxSessions 2
MaxStartups 2:30:10
LoginGraceTime 30
Restart SSH service
sudo systemctl restart sshd
```
Implementing Fail2Ban: Automated Attack Prevention
Fail2Ban is a powerful intrusion prevention system that monitors log files and automatically blocks IP addresses showing malicious behavior.
Installation
Ubuntu/Debian:
```bash
sudo apt update
sudo apt install fail2ban
```
CentOS/RHEL:
```bash
Enable EPEL repository first
sudo yum install epel-release
sudo yum install fail2ban
For newer versions
sudo dnf install fail2ban
```
Basic Configuration
Create a local configuration file to override defaults:
```bash
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
```
Essential Fail2Ban Configuration:
```ini
[DEFAULT]
Ban time in seconds (10 minutes)
bantime = 600
Find time window (10 minutes)
findtime = 600
Maximum retry attempts
maxretry = 3
Ignore local IPs
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
Email notifications (optional)
destemail = admin@yourdomain.com
sendername = Fail2Ban
mta = sendmail
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
```
Advanced Fail2Ban Jails
Protect Web Services:
```ini
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/*error.log
maxretry = 3
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/*access.log
maxretry = 6
```
Custom Fail2Ban Filters
Create custom filters for specific attack patterns:
```bash
sudo nano /etc/fail2ban/filter.d/custom-ssh.conf
```
```ini
[Definition]
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for . from ( via \S+)?\s $
^%(__prefix_line)s(?:error: )?Received disconnect from : 3: .*: Auth fail$
^%(__prefix_line)sFailed \S+ for . from (?: port \d )?(?: ssh\d*)?$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM $
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from $
^%(__prefix_line)sUser .+ from not allowed because not listed in AllowUsers$
ignoreregex =
```
Start and Enable Fail2Ban:
```bash
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
sudo systemctl status fail2ban
```
Firewall Configuration for Enhanced Security
Using UFW (Ubuntu/Debian)
```bash
Enable UFW
sudo ufw enable
Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow specific services
sudo ufw allow 2222/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
Limit SSH connections (built-in rate limiting)
sudo ufw limit 2222/tcp
Check status
sudo ufw status verbose
```
Using firewalld (CentOS/RHEL/Fedora)
```bash
Start and enable firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
Set default zone
sudo firewall-cmd --set-default-zone=public
Add services
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
Implement rate limiting
sudo firewall-cmd --permanent --add-rich-rule="rule service name='ssh' limit value='3/m' accept"
Reload configuration
sudo firewall-cmd --reload
```
Advanced Firewall Rules
Block Specific Countries:
```bash
Example: Block traffic from specific IP ranges
sudo ufw deny from 192.168.100.0/24
sudo ufw deny from 10.0.0.0/8
```
Implement Port Knocking:
```bash
Install knockd
sudo apt install knockd # Ubuntu/Debian
sudo yum install knock-server # CentOS/RHEL
Configure port knocking
sudo nano /etc/knockd.conf
```
```ini
[options]
UseSyslog
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 2222 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 2222 -j ACCEPT
tcpflags = syn
```
Implementing Two-Factor Authentication (2FA)
Adding 2FA provides an additional security layer even if passwords are compromised.
Install Google Authenticator PAM Module:
```bash
Ubuntu/Debian
sudo apt install libpam-google-authenticator
CentOS/RHEL
sudo yum install google-authenticator
```
Configure 2FA for SSH:
```bash
Run as the user who needs 2FA
google-authenticator
Answer the prompts:
- Do you want authentication tokens to be time-based? (y)
- Do you want me to update your "/home/user/.google_authenticator" file? (y)
- Do you want to disallow multiple uses of the same authentication token? (y)
- Do you want to do so? (n) for time skew
- Do you want to enable rate-limiting? (y)
```
Configure PAM:
```bash
sudo nano /etc/pam.d/sshd
Add this line at the top
auth required pam_google_authenticator.so
```
Update SSH Configuration:
```bash
sudo nano /etc/ssh/sshd_config
Enable challenge response
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Restart SSH
sudo systemctl restart sshd
```
Advanced Monitoring and Alerting
Log Monitoring with rsyslog
Configure centralized logging for better attack visibility:
```bash
sudo nano /etc/rsyslog.conf
Add custom log rules
auth,authpriv.* /var/log/auth.log
.;auth,authpriv.none /var/log/syslog
```
Real-time Log Monitoring
Using journalctl for systemd systems:
```bash
Monitor SSH attempts in real-time
sudo journalctl -u sshd -f
Filter failed attempts
sudo journalctl -u sshd | grep "Failed password"
Show authentication failures
sudo journalctl --since "1 hour ago" | grep "authentication failure"
```
Automated Alert Scripts
Create scripts to notify you of suspicious activity:
```bash
sudo nano /usr/local/bin/ssh-alert.sh
```
```bash
#!/bin/bash
SSH Alert Script
LOGFILE="/var/log/auth.log"
THRESHOLD=5
EMAIL="admin@yourdomain.com"
Count failed attempts in last hour
FAILED_ATTEMPTS=$(grep "Failed password" $LOGFILE | grep "$(date '+%b %d %H')" | wc -l)
if [ $FAILED_ATTEMPTS -gt $THRESHOLD ]; then
echo "WARNING: $FAILED_ATTEMPTS failed SSH attempts detected in the last hour" | \
mail -s "SSH Alert - $(hostname)" $EMAIL
fi
```
```bash
Make executable
sudo chmod +x /usr/local/bin/ssh-alert.sh
Add to cron for hourly checks
echo "0 /usr/local/bin/ssh-alert.sh" | sudo crontab -
```
Network-Level Protection
Implementing Network Segmentation
Use VLANs or separate network segments for different server functions:
```bash
Example: Configure network interface for specific VLAN
sudo nano /etc/netplan/01-network-manager-all.yaml
```
```yaml
network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses: [192.168.100.10/24]
gateway4: 192.168.100.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
vlans:
vlan.100:
id: 100
link: eth0
addresses: [10.0.100.10/24]
```
DDoS Protection with iptables
Implement rate limiting at the network level:
```bash
Create iptables rules for DDoS protection
sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 2222 -j DROP
Save rules
sudo iptables-save > /etc/iptables/rules.v4
```
Troubleshooting Common Issues
Fail2Ban Not Working
Check Fail2Ban Status:
```bash
Check service status
sudo systemctl status fail2ban
Check jail status
sudo fail2ban-client status
Check specific jail
sudo fail2ban-client status sshd
View banned IPs
sudo fail2ban-client get sshd banned
```
Common Fail2Ban Issues:
Log File Permissions: Ensure Fail2Ban can read log files:
```bash
sudo chmod 644 /var/log/auth.log
sudo chown root:adm /var/log/auth.log
```
Incorrect Log Paths: Verify log file locations:
```bash
Check where SSH logs are written
sudo grep -r "Failed password" /var/log/
Update jail.local with correct path
sudo nano /etc/fail2ban/jail.local
```
SSH Connection Issues
Locked Out After Configuration Changes:
If you're locked out, use console access or recovery mode:
```bash
From console/recovery mode
sudo nano /etc/ssh/sshd_config
Temporarily enable password authentication
PasswordAuthentication yes
Restart SSH
sudo systemctl restart sshd
```
Debug SSH Connection Problems:
```bash
Test SSH connection with verbose output
ssh -v username@server_ip -p 2222
Check SSH daemon status
sudo systemctl status sshd
View SSH logs
sudo tail -f /var/log/auth.log
```
Firewall Connectivity Issues
UFW Troubleshooting:
```bash
Check UFW status and rules
sudo ufw status numbered
Reset UFW if needed
sudo ufw --force reset
Check UFW logs
sudo tail -f /var/log/ufw.log
```
firewalld Troubleshooting:
```bash
Check firewalld status
sudo firewall-cmd --state
List all rules
sudo firewall-cmd --list-all
Check logs
sudo journalctl -u firewalld -f
```
Best Practices and Professional Tips
1. Regular Security Audits
Perform monthly security reviews:
```bash
Check for failed login attempts
sudo grep "Failed password" /var/log/auth.log | tail -20
Review active fail2ban jails
sudo fail2ban-client status
Check listening services
sudo netstat -tulpn | grep LISTEN
Review user accounts
sudo cat /etc/passwd | grep -E ":[0-9]{4,}:"
```
2. Keep Systems Updated
Maintain current security patches:
```bash
Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
CentOS/RHEL
sudo yum update -y
or
sudo dnf update -y
Enable automatic security updates (Ubuntu)
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
```
3. Implement Principle of Least Privilege
- Create specific user accounts for different services
- Use sudo instead of root access
- Regularly review and remove unnecessary user accounts
- Implement proper file permissions
4. Network Monitoring
Deploy network monitoring tools:
```bash
Install and configure ntopng
sudo apt install ntopng
Configure network monitoring
sudo nano /etc/ntopng/ntopng.conf
```
5. Backup and Recovery Planning
Ensure you can recover from security incidents:
```bash
Regular configuration backups
sudo tar -czf /backup/server-config-$(date +%Y%m%d).tar.gz \
/etc/ssh/ /etc/fail2ban/ /etc/ufw/ /etc/iptables/
Test restoration procedures regularly
```
6. Documentation and Change Management
Maintain detailed documentation of:
- All security configurations
- Firewall rules and their purposes
- User access levels and responsibilities
- Incident response procedures
- Contact information for security issues
Advanced Security Measures
Intrusion Detection Systems (IDS)
Install and Configure AIDE:
```bash
Install AIDE
sudo apt install aide # Ubuntu/Debian
sudo yum install aide # CentOS/RHEL
Initialize AIDE database
sudo aide --init
Move database to production location
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Schedule regular checks
echo "0 2 * /usr/bin/aide --check" | sudo crontab -
```
Security Information and Event Management (SIEM)
Consider implementing centralized logging solutions:
- ELK Stack (Elasticsearch, Logstash, Kibana)
- Splunk for enterprise environments
- Graylog for open-source SIEM
Container Security
If using Docker or containers:
```bash
Implement container security scanning
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/Library/Caches:/root/.cache/ \
aquasec/trivy image your-image:tag
Use security-focused base images
Implement proper container networking
Regular container image updates
```
Monitoring Attack Patterns
Analyzing Attack Trends
Create scripts to analyze attack patterns:
```bash
sudo nano /usr/local/bin/analyze-attacks.sh
```
```bash
#!/bin/bash
Attack Analysis Script
echo "=== SSH Attack Analysis ==="
echo "Failed password attempts by IP:"
grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -10
echo -e "\nMost targeted usernames:"
grep "Failed password for" /var/log/auth.log | \
awk '{print $9}' | sort | uniq -c | sort -nr | head -10
echo -e "\nAttack timeline (last 24 hours):"
grep "Failed password" /var/log/auth.log | \
grep "$(date '+%b %d')" | awk '{print $3}' | \
cut -d: -f1 | sort | uniq -c
```
Compliance and Legal Considerations
Data Protection Requirements
Ensure your security measures comply with:
- GDPR for European data
- HIPAA for healthcare data
- PCI DSS for payment card data
- SOX for financial data
Logging Requirements
Maintain appropriate log retention:
```bash
Configure log rotation
sudo nano /etc/logrotate.d/auth-logs
Example configuration
/var/log/auth.log {
weekly
rotate 52
compress
delaycompress
missingok
notifempty
create 644 root adm
}
```
Conclusion and Next Steps
Protecting your Linux server from brute-force attacks requires a multi-layered approach combining preventive measures, detection systems, and responsive actions. The strategies outlined in this guide provide comprehensive protection when implemented together:
1. SSH Hardening forms your first line of defense
2. Fail2Ban provides automated attack response
3. Firewall Configuration controls network access
4. Two-Factor Authentication adds an additional security layer
5. Monitoring and Alerting ensures quick response to threats
Immediate Action Items
1. Change default SSH port and disable root login
2. Implement key-based authentication
3. Install and configure Fail2Ban
4. Set up proper firewall rules
5. Enable logging and monitoring
6. Create incident response procedures
Long-term Security Strategy
- Regular security audits and penetration testing
- Stay updated with security patches and advisories
- Implement advanced monitoring solutions
- Train team members on security best practices
- Develop and test disaster recovery procedures
Continuous Improvement
Security is an ongoing process. Regularly review and update your security measures based on:
- New threat intelligence
- Changes in your infrastructure
- Lessons learned from security incidents
- Industry best practices and standards
Remember that security is not a one-time implementation but a continuous process of monitoring, updating, and improving your defenses against evolving threats. The time invested in properly securing your Linux server will pay dividends in preventing costly security breaches and maintaining system integrity.
By following this comprehensive guide, you've established a robust defense system against brute-force attacks. Continue to monitor security advisories, update your systems regularly, and adapt your security measures as new threats emerge in the ever-evolving cybersecurity landscape.