Monitoring Apache web server logs is essential for identifying and mitigating brute-force login attempts. Brute-force attacks involve an attacker systematically attempting various username and password combinations to gain unauthorized access. By analyzing Apache access logs, you can detect patterns indicative of such attacks and implement measures to prevent them.
1. Identifying Relevant Log Entries Showing Login Failures
Apache access logs record all HTTP requests made to your server. To detect brute-force attempts, focus on entries related to login endpoints (e.g., /login, /wp-login.php). Repeated access to these endpoints, especially with unsuccessful login attempts, may indicate an attack.
Example of an Apache Access Log Entry:
127.0.0.1 - - [10/Feb/2025:13:55:36 +0530] "POST /login HTTP/1.1" 200 4234 "-" "Mozilla/5.0"
In this log entry:
- 127.0.0.1: Client IP address.
- [10/Feb/2025:13:55:36 +0530]: Timestamp of the request.
- "POST /login HTTP/1.1": HTTP method and endpoint.
- 200: HTTP status code returned by the server.
A 200 status code indicates a successful request, but it doesn't confirm a successful login. The application should log authentication failures explicitly, which can then be monitored.
2. Parsing Logs and Detecting Patterns Using Python
To automate the detection of brute-force attempts, you can write a Python script that parses the access logs and identifies IP addresses with excessive failed login attempts.
Sample Python Script:
import re
from collections import defaultdict
# Path to the Apache access log
log_file = '/var/log/apache2/access.log'
# Dictionary to count failed attempts per IP
failed_attempts = defaultdict(int)
# Regular expression to match log lines
log_pattern = re.compile(r'(?P<ip>\S+) - - \[(?P<date>.*?)\] "(?P<method>\S+) (?P<endpoint>\S+) \S+" (?P<status>\d{3})')
# Define the login endpoint and the status code for failed attempts
login_endpoint = '/login'
failed_status = '401' # Unauthorized
with open(log_file, 'r') as file:
for line in file:
match = log_pattern.match(line)
if match:
ip = match.group('ip')
endpoint = match.group('endpoint')
status = match.group('status')
if endpoint == login_endpoint and status == failed_status:
failed_attempts[ip] += 1
# Threshold for failed attempts
threshold = 5
# Identify IPs exceeding the threshold
suspicious_ips = [ip for ip, count in failed_attempts.items() if count > threshold]
if suspicious_ips:
print("Suspicious IP addresses detected:")
for ip in suspicious_ips:
print(f"{ip} with {failed_attempts[ip]} failed attempts")
else:
print("No suspicious activity detected.")
In this script:
- We define the path to the Apache access log.
- We use a regular expression to parse each log line and extract the IP address, endpoint, and status code.
- We check if the request was made to the login endpoint and resulted in a 401 Unauthorized status. If so, we increment the count for that IP address.
- After processing the log, we identify IPs that have exceeded a defined threshold of failed attempts.
3. Setting Up Alerts for Suspicious Login Attempts
To automate the blocking of IPs exhibiting suspicious behavior, you can integrate tools like Fail2ban. Fail2ban monitors log files and bans IPs that show malicious signs, such as multiple failed login attempts.
Installing and Configuring Fail2ban:
-
Install Fail2ban:
sudo apt-get install fail2ban
-
Configure Fail2ban:
Create a local configuration file to override the default settings:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit /etc/fail2ban/jail.local to add a jail for your web application.
Example Configuration:
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/access.log
maxretry = 5
bantime = 3600 ; Ban for 1 hour
findtime = 600 ; Monitor for 10 minutes
This configuration sets up a jail that bans IPs with more than 5 failed login attempts within a 10-minute window for 1 hour.
-
Define the Filter:
Create a filter to detect failed login attempts by adding a file at /etc/fail2ban/filter.d/apache-auth.conf.
Example Filter:
[Definition]
failregex = ^<HOST> - - .* "POST /login HTTP/1.1" 401
ignoreregex =
This filter matches log entries with a POST request to /login that resulted in a 401 Unauthorized response.
-
Restart Fail2ban:
After configuring, restart the Fail2ban service to apply the changes:
sudo systemctl restart fail2ban
By implementing these steps, you can effectively monitor and respond to brute-force login attempts on your Apache web server. Regularly reviewing your logs and adjusting your security configurations will help maintain the integrity and security of your web applications.