How to monitor failed login attempts in Linux
How to Monitor Failed Login Attempts in Linux
Monitoring failed login attempts is a critical security practice for any Linux system administrator. Failed login attempts often indicate potential security threats, brute force attacks, or unauthorized access attempts. This comprehensive guide will walk you through various methods to effectively monitor, analyze, and respond to failed login attempts on Linux systems.
Table of Contents
- [Introduction](#introduction)
- [Prerequisites](#prerequisites)
- [Understanding Linux Authentication Logs](#understanding-linux-authentication-logs)
- [Method 1: Using System Log Files](#method-1-using-system-log-files)
- [Method 2: Command-Line Tools for Monitoring](#method-2-command-line-tools-for-monitoring)
- [Method 3: Real-Time Monitoring](#method-3-real-time-monitoring)
- [Method 4: Automated Monitoring with Scripts](#method-4-automated-monitoring-with-scripts)
- [Method 5: Using Fail2ban for Active Protection](#method-5-using-fail2ban-for-active-protection)
- [Advanced Monitoring Techniques](#advanced-monitoring-techniques)
- [Setting Up Alerts and Notifications](#setting-up-alerts-and-notifications)
- [Common Issues and Troubleshooting](#common-issues-and-troubleshooting)
- [Best Practices and Security Recommendations](#best-practices-and-security-recommendations)
- [Conclusion](#conclusion)
Introduction
Failed login attempts on Linux systems can indicate various scenarios, from simple user errors to sophisticated attack attempts. By implementing proper monitoring mechanisms, system administrators can:
- Detect potential security breaches early
- Identify patterns in attack attempts
- Implement proactive security measures
- Maintain audit trails for compliance requirements
- Optimize system security configurations
This guide covers multiple approaches to monitoring failed login attempts, from basic log analysis to advanced automated monitoring solutions suitable for both single servers and enterprise environments.
Prerequisites
Before implementing failed login monitoring, ensure you have:
- Root or sudo access to the Linux system
- Basic understanding of Linux command line
- Familiarity with log file locations and formats
- Text editor knowledge (vim, nano, or similar)
- Network access for installing additional tools if needed
System Requirements
- Any modern Linux distribution (Ubuntu, CentOS, RHEL, Debian, etc.)
- Minimum 1GB RAM for monitoring tools
- Sufficient disk space for log retention
- SSH access for remote monitoring
Understanding Linux Authentication Logs
Linux systems maintain detailed logs of authentication events, including successful and failed login attempts. Understanding these logs is fundamental to effective monitoring.
Primary Log Locations
Different Linux distributions store authentication logs in various locations:
Ubuntu/Debian Systems:
```bash
/var/log/auth.log # Primary authentication log
/var/log/syslog # System-wide log including auth events
```
CentOS/RHEL/Fedora Systems:
```bash
/var/log/secure # Authentication and security events
/var/log/messages # General system messages
```
General Locations:
```bash
/var/log/wtmp # Login records (binary format)
/var/log/btmp # Failed login attempts (binary format)
/var/log/lastlog # Last login information
```
Log Entry Format
A typical failed login entry appears as:
```
Mar 15 10:30:45 server sshd[12345]: Failed password for invalid user admin from 192.168.1.100 port 22 ssh2
Mar 15 10:30:47 server sshd[12345]: Connection closed by invalid user admin 192.168.1.100 port 22 [preauth]
```
Key components include:
- Timestamp: When the event occurred
- Hostname: System where event happened
- Service: Authentication service (sshd, login, etc.)
- PID: Process ID of the service
- Event details: Specific failure information
Method 1: Using System Log Files
Basic Log Analysis
The most straightforward approach involves directly examining log files using standard Linux commands.
Viewing Recent Failed SSH Attempts
```bash
For Ubuntu/Debian systems
sudo grep "Failed password" /var/log/auth.log
For CentOS/RHEL systems
sudo grep "Failed password" /var/log/secure
Show last 50 failed attempts with timestamps
sudo grep "Failed password" /var/log/auth.log | tail -50
```
Analyzing Failed Login Patterns
```bash
Count failed attempts by IP address
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr
Show failed attempts for specific user
sudo grep "Failed password for root" /var/log/auth.log
Display failed attempts from last 24 hours
sudo grep "Failed password" /var/log/auth.log | grep "$(date '+%b %d')"
```
Using journalctl for Systemd Systems
Modern Linux distributions using systemd provide the `journalctl` command:
```bash
Show all authentication failures
sudo journalctl -u ssh -g "Failed"
Display failures from last hour
sudo journalctl -u ssh -g "Failed" --since "1 hour ago"
Follow authentication logs in real-time
sudo journalctl -u ssh -f
```
Advanced Log Analysis
Creating Custom Log Filters
```bash
Create a script to show detailed failed login summary
cat << 'EOF' > failed_login_summary.sh
#!/bin/bash
LOG_FILE="/var/log/auth.log"
if [ -f "/var/log/secure" ]; then
LOG_FILE="/var/log/secure"
fi
echo "=== Failed Login Summary ==="
echo "Total failed attempts: $(grep -c "Failed password" $LOG_FILE)"
echo ""
echo "Top 10 attacking IP addresses:"
grep "Failed password" $LOG_FILE | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -10
echo ""
echo "Most targeted users:"
grep "Failed password" $LOG_FILE | awk '{print $9}' | sort | uniq -c | sort -nr | head -10
EOF
chmod +x failed_login_summary.sh
./failed_login_summary.sh
```
Method 2: Command-Line Tools for Monitoring
Using the `last` and `lastb` Commands
These commands provide formatted access to login records:
```bash
Show successful logins
last
Show failed login attempts (requires root privileges)
sudo lastb
Show last 20 failed attempts
sudo lastb -20
Show failed attempts for specific user
sudo lastb username
Show failed attempts from specific IP
sudo lastb | grep "192.168.1.100"
```
Using `faillog` Command
The `faillog` command displays and manages failure counts:
```bash
Display failure counts for all users
sudo faillog
Show failures for specific user
sudo faillog -u username
Reset failure count for user
sudo faillog -r -u username
```
Creating Monitoring Aliases
Add these aliases to your `.bashrc` for quick access:
```bash
Add to ~/.bashrc
alias failed-ssh='sudo grep "Failed password" /var/log/auth.log | tail -20'
alias failed-ips='sudo grep "Failed password" /var/log/auth.log | awk "{print \$(NF-3)}" | sort | uniq -c | sort -nr'
alias watch-auth='sudo tail -f /var/log/auth.log | grep --color=auto "Failed\|Accepted"'
```
Method 3: Real-Time Monitoring
Using `tail` for Live Monitoring
```bash
Monitor authentication log in real-time
sudo tail -f /var/log/auth.log | grep --color=auto "Failed"
Monitor multiple logs simultaneously
sudo tail -f /var/log/auth.log /var/log/secure 2>/dev/null | grep --color=auto "Failed"
```
Advanced Real-Time Monitoring Script
```bash
cat << 'EOF' > realtime_monitor.sh
#!/bin/bash
Colors for output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
Determine log file location
if [ -f "/var/log/auth.log" ]; then
LOG_FILE="/var/log/auth.log"
elif [ -f "/var/log/secure" ]; then
LOG_FILE="/var/log/secure"
else
echo "Authentication log file not found!"
exit 1
fi
echo -e "${GREEN}Starting real-time failed login monitor...${NC}"
echo -e "${YELLOW}Monitoring: $LOG_FILE${NC}"
echo "Press Ctrl+C to stop"
echo ""
Monitor log file for failed attempts
tail -f "$LOG_FILE" | while read line; do
if echo "$line" | grep -q "Failed password"; then
timestamp=$(echo "$line" | awk '{print $1, $2, $3}')
ip=$(echo "$line" | awk '{print $(NF-3)}')
user=$(echo "$line" | awk '{print $9}')
echo -e "${RED}[$timestamp] FAILED LOGIN${NC} - User: ${YELLOW}$user${NC} from IP: ${YELLOW}$ip${NC}"
elif echo "$line" | grep -q "Accepted password"; then
timestamp=$(echo "$line" | awk '{print $1, $2, $3}')
ip=$(echo "$line" | awk '{print $(NF-3)}')
user=$(echo "$line" | awk '{print $9}')
echo -e "${GREEN}[$timestamp] SUCCESSFUL LOGIN${NC} - User: ${YELLOW}$user${NC} from IP: ${YELLOW}$ip${NC}"
fi
done
EOF
chmod +x realtime_monitor.sh
sudo ./realtime_monitor.sh
```
Method 4: Automated Monitoring with Scripts
Daily Failed Login Report Script
```bash
cat << 'EOF' > daily_failed_login_report.sh
#!/bin/bash
Configuration
REPORT_FILE="/tmp/failed_login_report_$(date +%Y%m%d).txt"
EMAIL_RECIPIENT="admin@example.com"
THRESHOLD=10
Determine log file
if [ -f "/var/log/auth.log" ]; then
LOG_FILE="/var/log/auth.log"
else
LOG_FILE="/var/log/secure"
fi
Generate report
{
echo "Failed Login Report for $(hostname) - $(date)"
echo "================================================"
echo ""
# Total failed attempts today
TODAY=$(date '+%b %d')
FAILED_COUNT=$(grep "Failed password" "$LOG_FILE" | grep "$TODAY" | wc -l)
echo "Total failed login attempts today: $FAILED_COUNT"
echo ""
if [ $FAILED_COUNT -gt 0 ]; then
echo "Top 10 Source IP Addresses:"
echo "---------------------------"
grep "Failed password" "$LOG_FILE" | grep "$TODAY" | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -10
echo ""
echo "Most Targeted Users:"
echo "-------------------"
grep "Failed password" "$LOG_FILE" | grep "$TODAY" | awk '{print $9}' | sort | uniq -c | sort -nr | head -10
echo ""
echo "Detailed Log Entries:"
echo "--------------------"
grep "Failed password" "$LOG_FILE" | grep "$TODAY" | tail -20
fi
} > "$REPORT_FILE"
Send alert if threshold exceeded
if [ $FAILED_COUNT -gt $THRESHOLD ]; then
if command -v mail >/dev/null 2>&1; then
mail -s "ALERT: High Failed Login Activity on $(hostname)" "$EMAIL_RECIPIENT" < "$REPORT_FILE"
fi
echo "ALERT: $FAILED_COUNT failed login attempts detected (threshold: $THRESHOLD)"
fi
echo "Report generated: $REPORT_FILE"
cat "$REPORT_FILE"
EOF
chmod +x daily_failed_login_report.sh
```
Setting Up Cron Jobs
Add automated monitoring to crontab:
```bash
Edit crontab
crontab -e
Add these entries:
Run daily report at 8 AM
0 8 * /path/to/daily_failed_login_report.sh
Check for suspicious activity every hour
0 /path/to/hourly_security_check.sh
Real-time monitoring (optional, for critical systems)
@reboot /path/to/realtime_monitor.sh > /var/log/security_monitor.log 2>&1 &
```
Method 5: Using Fail2ban for Active Protection
Fail2ban is a powerful intrusion prevention tool that automatically blocks IP addresses showing suspicious behavior.
Installing Fail2ban
```bash
Ubuntu/Debian
sudo apt update
sudo apt install fail2ban
CentOS/RHEL
sudo yum install epel-release
sudo yum install fail2ban
Fedora
sudo dnf install fail2ban
```
Basic Fail2ban Configuration
```bash
Create local configuration file
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit configuration
sudo nano /etc/fail2ban/jail.local
```
Basic jail configuration:
```ini
[DEFAULT]
Ban IP for 1 hour
bantime = 3600
Check for failures in last 10 minutes
findtime = 600
Ban after 5 failed attempts
maxretry = 5
Email notifications
destemail = admin@example.com
sendername = Fail2ban
mta = sendmail
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
```
Managing Fail2ban
```bash
Start and enable fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
Check status
sudo fail2ban-client status
Check specific jail status
sudo fail2ban-client status sshd
Unban an IP address
sudo fail2ban-client set sshd unbanip 192.168.1.100
View banned IPs
sudo fail2ban-client get sshd banip
```
Advanced Monitoring Techniques
Using Logwatch for Comprehensive Reports
Logwatch provides detailed system log analysis:
```bash
Install logwatch
sudo apt install logwatch # Ubuntu/Debian
sudo yum install logwatch # CentOS/RHEL
Generate immediate report
sudo logwatch --detail Med --service sshd --range today
Configure automatic daily reports
sudo nano /etc/logwatch/conf/logwatch.conf
```
Custom Log Analysis with AWK
Advanced pattern analysis using AWK:
```bash
Analyze attack patterns by hour
sudo awk '/Failed password/ {
split($3, time, ":");
hour = time[1];
attacks[hour]++;
}
END {
for (h in attacks) {
printf "Hour %s: %d failed attempts\n", h, attacks[h];
}
}' /var/log/auth.log | sort -k2 -n
Geographic analysis (requires GeoIP database)
sudo awk '/Failed password/ {
ip = $(NF-3);
cmd = "geoiplookup " ip " | head -1";
cmd | getline country;
close(cmd);
countries[country]++;
}
END {
for (c in countries) {
printf "%s: %d attempts\n", c, countries[c];
}
}' /var/log/auth.log | sort -k2 -nr
```
Integration with SIEM Systems
For enterprise environments, integrate with Security Information and Event Management (SIEM) systems:
```bash
Configure rsyslog to forward auth events
sudo nano /etc/rsyslog.d/50-security.conf
Add configuration:
Forward authentication events to SIEM
auth.* @@siem-server.example.com:514
```
Setting Up Alerts and Notifications
Email Alerts Script
```bash
cat << 'EOF' > security_alert.sh
#!/bin/bash
THRESHOLD=5
TIME_WINDOW=300 # 5 minutes
LOG_FILE="/var/log/auth.log"
TEMP_FILE="/tmp/recent_failures.tmp"
EMAIL="admin@example.com"
Get recent failed attempts
since_time=$(date -d "5 minutes ago" "+%b %d %H:%M")
grep "Failed password" "$LOG_FILE" | awk -v since="$since_time" '
$0 >= since {print}' > "$TEMP_FILE"
RECENT_FAILURES=$(wc -l < "$TEMP_FILE")
if [ $RECENT_FAILURES -gt $THRESHOLD ]; then
{
echo "SECURITY ALERT: $(hostname)"
echo "Time: $(date)"
echo "Failed login attempts in last 5 minutes: $RECENT_FAILURES"
echo ""
echo "Details:"
cat "$TEMP_FILE"
} | mail -s "SECURITY ALERT: High Failed Login Activity" "$EMAIL"
fi
rm -f "$TEMP_FILE"
EOF
chmod +x security_alert.sh
```
Slack Integration
```bash
cat << 'EOF' > slack_security_alert.sh
#!/bin/bash
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
THRESHOLD=10
Count recent failed attempts
FAILED_COUNT=$(grep "Failed password" /var/log/auth.log | grep "$(date '+%b %d')" | wc -l)
if [ $FAILED_COUNT -gt $THRESHOLD ]; then
MESSAGE="🚨 Security Alert: $FAILED_COUNT failed login attempts detected on $(hostname) today"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}" \
"$WEBHOOK_URL"
fi
EOF
chmod +x slack_security_alert.sh
```
Common Issues and Troubleshooting
Log File Permissions
Issue: Cannot access log files
Solution:
```bash
Check log file permissions
ls -la /var/log/auth.log /var/log/secure
Fix permissions if needed
sudo chmod 640 /var/log/auth.log
sudo chown root:adm /var/log/auth.log
```
Log Rotation Issues
Issue: Old logs not accessible
Solution:
```bash
Check logrotate configuration
sudo cat /etc/logrotate.d/rsyslog
View rotated logs
sudo zcat /var/log/auth.log.1.gz | grep "Failed password"
Search across all rotated logs
sudo zgrep "Failed password" /var/log/auth.log*
```
High Log Volume
Issue: Too many log entries to process
Solution:
```bash
Use time-based filtering
sudo grep "Failed password" /var/log/auth.log | grep "$(date '+%b %d')"
Limit output
sudo grep "Failed password" /var/log/auth.log | tail -100
Use more specific patterns
sudo grep "Failed password for root" /var/log/auth.log
```
Service-Specific Monitoring
Issue: Need to monitor specific services
Solution:
```bash
SSH failures only
sudo grep "sshd.*Failed" /var/log/auth.log
FTP failures
sudo grep "vsftpd.*FAIL" /var/log/vsftpd.log
Web server authentication failures
sudo grep "authentication failure" /var/log/apache2/error.log
```
False Positives
Issue: Legitimate failures triggering alerts
Solution:
```bash
Whitelist trusted IP ranges
cat << 'EOF' > smart_monitor.sh
#!/bin/bash
TRUSTED_NETWORKS="192.168.1.0/24 10.0.0.0/8"
Function to check if IP is in trusted network
is_trusted_ip() {
local ip=$1
for network in $TRUSTED_NETWORKS; do
if ipcalc -c "$network" 2>/dev/null | grep -q "$ip"; then
return 0
fi
done
return 1
}
Monitor only untrusted IPs
grep "Failed password" /var/log/auth.log | while read line; do
ip=$(echo "$line" | awk '{print $(NF-3)}')
if ! is_trusted_ip "$ip"; then
echo "$line"
fi
done
EOF
```
Best Practices and Security Recommendations
1. Implement Multi-Layered Security
- Use key-based authentication instead of passwords when possible
- Configure fail2ban or similar intrusion prevention systems
- Implement network-level filtering with firewalls
- Use VPN for remote access when feasible
2. Optimize Monitoring Configuration
```bash
Set appropriate log retention periods
sudo nano /etc/logrotate.d/rsyslog
Example configuration:
/var/log/auth.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 root adm
}
```
3. Regular Security Audits
```bash
Weekly security audit script
cat << 'EOF' > weekly_security_audit.sh
#!/bin/bash
echo "Weekly Security Audit - $(date)"
echo "=================================="
Check for unusual login patterns
echo "1. Login Pattern Analysis:"
last | head -20
Review failed login attempts
echo -e "\n2. Failed Login Summary:"
sudo grep "Failed password" /var/log/auth.log | tail -50 | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -10
Check for new user accounts
echo -e "\n3. Recent User Account Changes:"
sudo grep -E "(useradd|userdel|usermod)" /var/log/auth.log | tail -10
Review sudo usage
echo -e "\n4. Recent Sudo Activity:"
sudo grep "sudo:" /var/log/auth.log | tail -10
Check for privilege escalation attempts
echo -e "\n5. Privilege Escalation Attempts:"
sudo grep -E "(su:|sudo:.*FAILED)" /var/log/auth.log | tail -10
EOF
chmod +x weekly_security_audit.sh
```
4. Automated Response Procedures
```bash
Automated incident response script
cat << 'EOF' > incident_response.sh
#!/bin/bash
ALERT_THRESHOLD=20
BLOCK_THRESHOLD=50
LOG_FILE="/var/log/auth.log"
Function to block IP
block_ip() {
local ip=$1
sudo iptables -A INPUT -s "$ip" -j DROP
echo "Blocked IP: $ip"
logger "Security: Automatically blocked IP $ip due to excessive failed logins"
}
Function to send alert
send_alert() {
local message=$1
echo "$message" | mail -s "Security Alert: $(hostname)" admin@example.com
logger "Security Alert: $message"
}
Analyze recent failures
grep "Failed password" "$LOG_FILE" | grep "$(date '+%b %d')" | awk '{print $(NF-3)}' | sort | uniq -c | while read count ip; do
if [ "$count" -gt "$BLOCK_THRESHOLD" ]; then
block_ip "$ip"
send_alert "IP $ip blocked after $count failed login attempts"
elif [ "$count" -gt "$ALERT_THRESHOLD" ]; then
send_alert "Warning: IP $ip has $count failed login attempts"
fi
done
EOF
chmod +x incident_response.sh
```
5. Performance Considerations
- Use indexed log analysis for large log files
- Implement log compression to save disk space
- Set up centralized logging for multiple servers
- Monitor system resources used by security tools
6. Compliance and Documentation
- Maintain audit trails for compliance requirements
- Document security procedures and escalation paths
- Regular backup of security logs
- Test incident response procedures periodically
Conclusion
Monitoring failed login attempts is a crucial component of Linux system security. This comprehensive guide has covered multiple approaches, from basic log analysis to advanced automated monitoring systems. Key takeaways include:
1. Start with basic log monitoring using built-in Linux tools
2. Implement real-time monitoring for critical systems
3. Use automated tools like fail2ban for active protection
4. Set up appropriate alerts and notification systems
5. Regular security audits and procedure testing
6. Follow security best practices for comprehensive protection
Next Steps
After implementing failed login monitoring:
1. Test your monitoring setup with controlled failed login attempts
2. Fine-tune alert thresholds to minimize false positives
3. Integrate with existing security infrastructure
4. Train team members on incident response procedures
5. Regular review and updates of security configurations
6. Consider advanced security tools for enterprise environments
Additional Resources
- Linux Security Documentation: Distribution-specific security guides
- Fail2ban Documentation: Advanced configuration options
- SIEM Integration: Enterprise security management
- Incident Response: Security incident handling procedures
Remember that security monitoring is an ongoing process that requires regular attention, updates, and improvements. Stay informed about new threats and adjust your monitoring strategies accordingly to maintain robust system security.