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.