Fail2Ban

Monitor Fail2Ban intrusion prevention logs including ban actions, filter logs, jail status, and security events using the File Stream plugin

Fail2BanFail2Ban Integration

Monitor and analyze Fail2Ban intrusion prevention logs in real-time using LogFlux Agent’s File Stream plugin. This configuration-based approach provides comprehensive security monitoring, attack pattern analysis, and IP reputation tracking for Fail2Ban deployments.

Overview

The Fail2Ban integration leverages LogFlux Agent’s File Stream plugin to:

  • Real-time monitoring of ban/unban actions, filter matches, and jail status
  • Attack pattern analysis with failed login attempts and brute force detection
  • IP reputation tracking with banned IP addresses and geolocation analysis
  • Security event correlation with system logs and application events
  • Jail performance monitoring with ban rates and filter effectiveness
  • Custom filter analysis for application-specific security rules

Installation

The File Stream plugin is included with LogFlux Agent. Enable it for Fail2Ban log monitoring:

1
2
3
4
5
# Enable File Stream plugin
sudo systemctl enable --now logflux-filestream

# Verify plugin status
sudo systemctl status logflux-filestream

Fail2Ban Configuration

Configure Fail2Ban logging in /etc/fail2ban/fail2ban.conf:

Basic Logging Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[Definition]
# Log level (CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG)
loglevel = INFO

# Log file location
logtarget = /var/log/fail2ban.log

# Log format
logencoding = auto

# Syslog facility (if using syslog)
syslogsocket = auto

# Database logging (if using database backend)
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 86400

Enhanced Logging Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[Definition]
# Detailed logging
loglevel = DEBUG
logtarget = /var/log/fail2ban.log

# Additional log targets
logtarget = SYSLOG
syslogfacility = authpriv

# Action logging
actionstart_on_demand = false
actionstop_on_demand = false

# Custom log format with timestamps
logencoding = utf-8

# Performance monitoring
usedns = warn
findtime = 600
bantime = 3600
maxretry = 3

Jail Configuration Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# SSH brute force protection
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
action = iptables[name=SSH, port=ssh, protocol=tcp]
         sendmail-whois[name=SSH, dest=admin@example.com]

# Apache/Nginx protection
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 3
findtime = 600
bantime = 3600

# Custom application protection
[myapp-bruteforce]
enabled = true
port = 8080
filter = myapp-bruteforce
logpath = /var/log/myapp/auth.log
maxretry = 5
findtime = 300
bantime = 1800

Basic Configuration

Configure the File Stream plugin to monitor Fail2Ban logs by creating /etc/logflux-agent/plugins/filestream-fail2ban.toml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[filestream.fail2ban_main]
paths = ["/var/log/fail2ban.log"]
format = "fail2ban_log"
tags = ["fail2ban", "security", "ips"]
fields = {
  service = "fail2ban",
  log_type = "main"
}

[filestream.fail2ban_actions]
paths = ["/var/log/fail2ban.log"]
format = "fail2ban_log"
tags = ["fail2ban", "actions", "ban"]
fields = {
  service = "fail2ban",
  log_type = "actions"
}

# Filter for ban/unban actions only
[filestream.fail2ban_actions.processors.grep]
patterns = [
  "Ban",
  "Unban",
  "Found",
  "Restore Ban"
]

[filestream.fail2ban_jail_status]
paths = ["/var/log/fail2ban-status.log"]
format = "json"
tags = ["fail2ban", "jail", "status"]
fields = {
  service = "fail2ban",
  log_type = "jail_status"
}

Fail2Ban Log Formats

Standard Fail2Ban Log Format

1
2
3
4
5
6
7
[filestream.fail2ban_standard]
paths = ["/var/log/fail2ban.log"]
format = "regex"
regex = '^(?P<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?P<level>\w+) \[(?P<jail>[^\]]+)\]: (?P<action>\w+) (?P<ip>[\d\.]+)(?:\s+(?P<additional>.*))?$'
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02 15:04:05,000"

Ban/Unban Action Format

1
2
3
4
5
6
7
8
[filestream.fail2ban_ban_actions]
paths = ["/var/log/fail2ban.log"]
format = "regex"
regex = '^(?P<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?P<level>\w+) \[(?P<jail>[^\]]+)\]: (?P<action>Ban|Unban) (?P<ip>[\d\.]+)$'
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02 15:04:05,000"
tags = ["fail2ban", "ban-actions"]

Filter Match Format

1
2
3
4
5
6
7
8
[filestream.fail2ban_filter_matches]
paths = ["/var/log/fail2ban.log"]
format = "regex"
regex = '^(?P<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?P<level>\w+) \[(?P<jail>[^\]]+)\]: Found (?P<ip>[\d\.]+) - (?P<current_matches>\d+)(?:\s+(?P<details>.*))?$'
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02 15:04:05,000"
tags = ["fail2ban", "filter-matches"]

Jail Status Format (Custom Script)

1
2
3
4
5
6
[filestream.fail2ban_jail_status_parsed]
paths = ["/var/log/fail2ban-status.log"]
format = "json"
parse_timestamp = true
timestamp_field = "timestamp"
timestamp_format = "2006-01-02T15:04:05.000Z"

Create jail status monitoring script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# Monitor Fail2Ban jail status
while true; do
    timestamp=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
    
    fail2ban-client status | grep "Jail list:" | sed 's/.*Jail list://' | sed 's/,/ /g' | \
    while read -r jail; do
        jail=$(echo $jail | xargs)  # trim whitespace
        if [ -n "$jail" ]; then
            status_output=$(fail2ban-client status "$jail" 2>/dev/null)
            if [ $? -eq 0 ]; then
                currently_failed=$(echo "$status_output" | grep "Currently failed:" | awk '{print $3}')
                total_failed=$(echo "$status_output" | grep "Total failed:" | awk '{print $3}')
                currently_banned=$(echo "$status_output" | grep "Currently banned:" | awk '{print $3}')
                total_banned=$(echo "$status_output" | grep "Total banned:" | awk '{print $3}')
                
                echo "{\"timestamp\": \"$timestamp\", \"jail\": \"$jail\", \"currently_failed\": $currently_failed, \"total_failed\": $total_failed, \"currently_banned\": $currently_banned, \"total_banned\": $total_banned, \"metric_type\": \"jail_status\"}" >> /var/log/fail2ban-status.log
            fi
        fi
    done
    
    sleep 60
done

Advanced Configuration

Attack Pattern Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
[filestream.fail2ban_attack_patterns]
paths = ["/var/log/fail2ban.log"]
format = "fail2ban_log"
tags = ["fail2ban", "attack", "patterns"]
fields = {
  service = "fail2ban",
  log_type = "attack_patterns"
}

# Add geographic and pattern analysis
[filestream.fail2ban_attack_patterns.processors.geoip]
source_field = "ip"
target_field = "geo"

[filestream.fail2ban_attack_patterns.processors.add_fields]
fields = {
  attack_severity = "{{ if gt .current_matches 10 }}high{{ else if gt .current_matches 5 }}medium{{ else }}low{{ end }}",
  is_repeat_offender = "{{ if gt .total_banned 1 }}true{{ else }}false{{ end }}"
}

Security Event Correlation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[filestream.fail2ban_correlation]
paths = ["/var/log/fail2ban.log"]
format = "fail2ban_log"
tags = ["fail2ban", "correlation", "security"]
fields = {
  service = "fail2ban",
  log_type = "security_correlation"
}

# Filter for specific security events
[filestream.fail2ban_correlation.processors.grep]
patterns = [
  "Ban",
  "Found.*ssh",
  "Found.*apache",
  "Found.*nginx",
  "service.*attack"
]

Performance Monitoring

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[filestream.fail2ban_performance]
paths = ["/var/log/fail2ban.log"]
format = "fail2ban_log"
tags = ["fail2ban", "performance"]
fields = {
  service = "fail2ban",
  log_type = "performance"
}

# Filter for performance-related events
[filestream.fail2ban_performance.processors.grep]
patterns = [
  "Started",
  "Stopped",
  "Reload",
  "jail.*enabled",
  "jail.*disabled"
]

Custom Filter Monitoring

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[filestream.fail2ban_custom_filters]
paths = ["/var/log/fail2ban.log"]
format = "fail2ban_log"
tags = ["fail2ban", "custom", "filters"]
fields = {
  service = "fail2ban",
  log_type = "custom_filters"
}

# Monitor specific application jails
[filestream.fail2ban_custom_filters.processors.grep]
patterns = [
  "myapp-bruteforce",
  "wordpress",
  "drupal",
  "phpmyadmin",
  "roundcube"
]

Usage Examples

Monitor Security Events

1
2
3
4
5
6
7
8
# Stream all Fail2Ban logs
logflux-cli stream --filter 'service:fail2ban'

# Monitor ban actions only
logflux-cli stream --filter 'service:fail2ban AND action:Ban'

# Track specific jail activity
logflux-cli stream --filter 'service:fail2ban AND jail:sshd'

Attack Analysis

1
2
3
4
5
6
7
8
# Monitor high-severity attacks
logflux-cli stream --filter 'service:fail2ban AND attack_severity:high'

# Track repeat offenders
logflux-cli stream --filter 'service:fail2ban AND is_repeat_offender:true'

# Monitor specific IP addresses
logflux-cli stream --filter 'service:fail2ban AND ip:192.168.1.100'

Geographic Analysis

1
2
3
4
5
6
7
8
# Track attacks by country
logflux-cli stream --filter 'service:fail2ban AND geo.country_code:CN'

# Monitor attacks from specific regions
logflux-cli stream --filter 'service:fail2ban AND geo.continent_code:AS'

# Track domestic vs international attacks
logflux-cli stream --filter 'service:fail2ban AND NOT geo.country_code:US'

Performance Monitoring

1
2
3
4
5
6
7
8
# Monitor jail status changes
logflux-cli stream --filter 'service:fail2ban AND log_type:performance'

# Track filter effectiveness
logflux-cli stream --filter 'service:fail2ban AND metric_type:jail_status'

# Monitor system resource usage
logflux-cli stream --filter 'service:fail2ban AND message:memory'

Fail2Ban Metrics Collection

Ban Statistics Collection

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash
# Collect comprehensive ban statistics
collect_ban_stats() {
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
    
    # Get list of all jails
    jails=$(fail2ban-client status | grep "Jail list:" | sed 's/.*Jail list://' | sed 's/,/ /g')
    
    for jail in $jails; do
        jail=$(echo $jail | xargs)
        if [ -n "$jail" ]; then
            # Get detailed jail statistics
            status=$(fail2ban-client status "$jail" 2>/dev/null)
            if [ $? -eq 0 ]; then
                filter_file=$(echo "$status" | grep "Filter" | awk '{print $2}')
                actions=$(echo "$status" | grep "Actions" | sed 's/.*Actions: //')
                currently_failed=$(echo "$status" | grep "Currently failed:" | awk '{print $3}')
                total_failed=$(echo "$status" | grep "Total failed:" | awk '{print $3}')
                currently_banned=$(echo "$status" | grep "Currently banned:" | awk '{print $3}')
                total_banned=$(echo "$status" | grep "Total banned:" | awk '{print $3}')
                
                # Get banned IP list
                banned_ips=$(echo "$status" | grep "Banned IP list:" | sed 's/.*Banned IP list: //')
                
                echo "{\"timestamp\": \"$timestamp\", \"jail\": \"$jail\", \"filter_file\": \"$filter_file\", \"actions\": \"$actions\", \"currently_failed\": $currently_failed, \"total_failed\": $total_failed, \"currently_banned\": $currently_banned, \"total_banned\": $total_banned, \"banned_ips\": \"$banned_ips\", \"metric_type\": \"detailed_jail_stats\"}" >> /var/log/fail2ban-detailed-stats.log
            fi
        fi
    done
}

while true; do
    collect_ban_stats
    sleep 300  # Every 5 minutes
done

IP Reputation Tracking

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
# Track IP reputation and repeated offenses
track_ip_reputation() {
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
    
    # Extract unique IPs from recent bans
    tail -n 1000 /var/log/fail2ban.log | \
    grep "Ban " | \
    awk '{print $NF}' | \
    sort | uniq -c | sort -nr | \
    head -20 | \
    while read count ip; do
        # Get whois information (optional)
        whois_info=$(whois "$ip" 2>/dev/null | grep -E "(country|Country)" | head -1 | awk -F: '{print $2}' | xargs)
        
        echo "{\"timestamp\": \"$timestamp\", \"ip\": \"$ip\", \"ban_count\": $count, \"country\": \"$whois_info\", \"reputation\": \"repeat_offender\", \"metric_type\": \"ip_reputation\"}" >> /var/log/fail2ban-ip-reputation.log
    done
}

# Run hourly
while true; do
    track_ip_reputation
    sleep 3600
done

Filter Effectiveness Analysis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash
# Analyze filter effectiveness across jails
analyze_filter_effectiveness() {
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)
    
    # Analyze recent activity by jail
    tail -n 5000 /var/log/fail2ban.log | \
    awk -v ts="$timestamp" '
    /Found/ && /\[.*\]/ {
        match($0, /\[([^\]]+)\]/, jail)
        jails[jail[1]]++
    }
    /Ban / && /\[.*\]/ {
        match($0, /\[([^\]]+)\]/, jail)
        bans[jail[1]]++
    }
    END {
        for (jail in jails) {
            ban_count = (bans[jail] ? bans[jail] : 0)
            detection_rate = (jails[jail] > 0 ? (ban_count / jails[jail] * 100) : 0)
            printf "{\"timestamp\": \"%s\", \"jail\": \"%s\", \"detections\": %d, \"bans\": %d, \"ban_rate\": %.2f, \"metric_type\": \"filter_effectiveness\"}\n",
                   ts, jail, jails[jail], ban_count, detection_rate
        }
    }' >> /var/log/fail2ban-filter-effectiveness.log
}

while true; do
    analyze_filter_effectiveness
    sleep 600  # Every 10 minutes
done

Monitoring and Alerting

Key Metrics to Monitor

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# High attack volume alert
[alerts.fail2ban_high_attack_volume]
query = "service:fail2ban AND action:Ban"
threshold = 10
window = "1m"
message = "High attack volume detected - {{ .threshold }} bans in 1 minute"

# Repeat offender alert
[alerts.fail2ban_repeat_offender]
query = "service:fail2ban AND ban_count:>5"
threshold = 1
window = "5m"
message = "Repeat offender detected: {{ .ip }} ({{ .ban_count }} bans)"

# Jail failure alert
[alerts.fail2ban_jail_failure]
query = "service:fail2ban AND (message:failed OR message:error) AND level:ERROR"
threshold = 1
window = "30s"
message = "Fail2Ban jail failure: {{ .jail }}"

# Geographic attack pattern alert
[alerts.fail2ban_geo_pattern]
query = "service:fail2ban AND action:Ban AND geo.country_code:CN"
threshold = 5
window = "5m"
message = "High attack volume from {{ .geo.country_name }}"

# Filter effectiveness alert
[alerts.fail2ban_low_effectiveness]
query = "service:fail2ban AND metric_type:filter_effectiveness AND ban_rate:<10"
threshold = 1
window = "10m"
message = "Low filter effectiveness in jail: {{ .jail }} ({{ .ban_rate }}%)"

# Service outage alert
[alerts.fail2ban_service_down]
query = "service:fail2ban AND message:Stopped"
threshold = 1
window = "30s"
message = "Fail2Ban service stopped"

Dashboard Metrics

Monitor these key Fail2Ban metrics:

  • Attack metrics (bans per hour, attacks by service, repeat offenders)
  • Geographic distribution (attacks by country, continent, ASN)
  • Jail performance (ban rates, filter effectiveness, active jails)
  • IP reputation (top attacking IPs, ban duration, repeat offenses)
  • Security trends (attack patterns over time, service targeting)
  • System health (jail status, service uptime, configuration changes)
  • Response times (detection to ban time, unban frequency)
  • Threat intelligence (malicious IP correlation, attack signatures)

Troubleshooting

Common Issues

Fail2Ban logs not appearing:

1
2
3
4
5
6
7
8
# Check Fail2Ban is running
sudo systemctl status fail2ban

# Verify log configuration
sudo grep -E "(logtarget|loglevel)" /etc/fail2ban/fail2ban.conf

# Check log file permissions
sudo ls -la /var/log/fail2ban.log

Log parsing errors:

1
2
3
4
5
6
7
8
# Check log format
sudo tail -n 10 /var/log/fail2ban.log

# Verify timestamp format
sudo grep -E "\d{4}-\d{2}-\d{2}" /var/log/fail2ban.log | head -5

# Test jail status
sudo fail2ban-client status

Jail configuration issues:

1
2
3
4
5
6
7
8
# Check jail status
sudo fail2ban-client status sshd

# Test filter patterns
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# Verify jail configuration
sudo fail2ban-client get sshd bantime

Performance issues:

1
2
3
4
5
6
7
# Check system resources
ps aux | grep fail2ban
top -p $(pgrep fail2ban-server)

# Monitor ban database
sudo ls -la /var/lib/fail2ban/
sudo file /var/lib/fail2ban/fail2ban.sqlite3

Best Practices

Security

  • Configure appropriate ban times based on threat assessment
  • Use geographic blocking for known high-risk regions
  • Implement progressive penalties for repeat offenders
  • Monitor and update filter patterns regularly

Performance

  • Optimize filter regular expressions for efficiency
  • Set appropriate findtime and maxretry values
  • Use database backend for better performance with many bans
  • Monitor memory usage and adjust accordingly

High Availability

  • Synchronize ban lists across multiple servers
  • Implement centralized logging for distributed deployments
  • Use shared storage for ban database in clusters
  • Monitor service health and implement automatic restart

Log Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Optimize log rotation for Fail2Ban
/var/log/fail2ban*.log {
    daily
    rotate 30
    missingok
    notifempty
    compress
    delaycompress
    postrotate
        systemctl reload fail2ban.service > /dev/null 2>&1 || true
        systemctl reload logflux-filestream.service > /dev/null 2>&1 || true
    endpostrotate
}

Custom Filter Development

Create effective custom filters:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Example custom filter for application brute force
[Definition]
failregex = ^.* "POST /login.*" 401 .*$
            ^.* "POST /admin.*" 403 .*$
            ^.*authentication failed.*from <HOST>.*$

ignoreregex = ^.*admin@example\.com.*$
              ^.*192\.168\.1\..*$

# Date pattern
datepattern = {^LN-BEG}

Integration Examples

Docker Deployment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: '3.8'
services:
  fail2ban:
    image: crazymax/fail2ban:latest
    container_name: fail2ban
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
    volumes:
      - ./data:/data
      - ./config/fail2ban:/etc/fail2ban
      - /var/log:/var/log:ro
      - fail2ban_logs:/var/log/fail2ban
    environment:
      - TZ=UTC
      - F2B_LOG_LEVEL=INFO
      - F2B_LOG_TARGET=/var/log/fail2ban/fail2ban.log
    restart: unless-stopped
    
  logflux-agent:
    image: logflux/agent:latest
    volumes:
      - fail2ban_logs:/var/log/fail2ban:ro
      - ./logflux-config:/etc/logflux-agent/plugins
    depends_on:
      - fail2ban

volumes:
  fail2ban_logs:

Kubernetes Deployment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fail2ban
spec:
  selector:
    matchLabels:
      app: fail2ban
  template:
    metadata:
      labels:
        app: fail2ban
    spec:
      hostNetwork: true
      hostPID: true
      containers:
      - name: fail2ban
        image: crazymax/fail2ban:latest
        securityContext:
          capabilities:
            add:
              - NET_ADMIN
              - NET_RAW
          privileged: true
        volumeMounts:
        - name: fail2ban-data
          mountPath: /data
        - name: fail2ban-config
          mountPath: /etc/fail2ban
        - name: host-logs
          mountPath: /var/log
          readOnly: true
        - name: fail2ban-logs
          mountPath: /var/log/fail2ban
        env:
        - name: TZ
          value: "UTC"
        - name: F2B_LOG_LEVEL
          value: "INFO"
      volumes:
      - name: fail2ban-data
        emptyDir: {}
      - name: fail2ban-config
        configMap:
          name: fail2ban-config
      - name: host-logs
        hostPath:
          path: /var/log
      - name: fail2ban-logs
        emptyDir: {}

Centralized Ban Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/bash
# Centralized ban synchronization across multiple servers
SERVERS=("server1.example.com" "server2.example.com" "server3.example.com")
LOCAL_BANS="/tmp/local_bans.txt"
REMOTE_BANS="/tmp/remote_bans.txt"

sync_bans() {
    # Collect local bans
    fail2ban-client status | grep "Jail list:" | sed 's/.*Jail list://' | sed 's/,/ /g' | \
    while read -r jail; do
        jail=$(echo $jail | xargs)
        if [ -n "$jail" ]; then
            fail2ban-client status "$jail" | grep "Banned IP list:" | sed "s/.*Banned IP list: //" | tr ' ' '\n' | while read ip; do
                if [ -n "$ip" ]; then
                    echo "$jail:$ip" >> "$LOCAL_BANS"
                fi
            done
        fi
    done
    
    # Sync with remote servers
    for server in "${SERVERS[@]}"; do
        if [ "$server" != "$(hostname)" ]; then
            scp "$LOCAL_BANS" "$server:$REMOTE_BANS" 2>/dev/null
            ssh "$server" "cat $REMOTE_BANS | while IFS=: read jail ip; do fail2ban-client set \$jail banip \$ip 2>/dev/null; done" 2>/dev/null
        fi
    done
    
    rm -f "$LOCAL_BANS" "$REMOTE_BANS"
}

# Run every 5 minutes
while true; do
    sync_bans
    sleep 300
done

This comprehensive Fail2Ban integration provides real-time intrusion prevention monitoring, attack pattern analysis, and IP reputation tracking using LogFlux Agent’s File Stream plugin. The configuration-based approach offers detailed insights into security events, jail performance, and threat patterns across different Fail2Ban deployment scenarios.

Disclaimer

The Fail2Ban logo and trademarks are the property of their respective owners. LogFlux is not affiliated with, endorsed by, or sponsored by the Fail2Ban project. The Fail2Ban logo is used solely for identification purposes to indicate compatibility and integration capabilities.