Skip to main content

Reporter Module

The reporter module receives ban events from fail2ban and reports them to the central Bloqd server in real-time.

How It Works

┌─────────────┐    ban event    ┌──────────────┐    Unix Socket    ┌─────────────────┐
│ │────────────────►│ │──────────────────►│ │
│ fail2ban │ │ bloqd-report │ │ Reporter Module │
│ │ │ (helper) │ │ │
└─────────────┘ └──────────────┘ └─────────────────┘

│ POST /api/v1/bans

┌─────────────────┐
│ │
│ Bloqd Server │
│ │
└─────────────────┘
  1. fail2ban triggers the bloqd-report action on ban
  2. Helper script sends data to Unix socket
  3. Reporter module receives the ban event
  4. Module validates and sends to Bloqd API

Configuration

modules:
reporter:
enabled: true
log_excerpt_max: 2000
socket_path: "/var/run/bloqd-agent/report.sock"
SettingDescriptionDefault
enabledEnable the reporter moduletrue
log_excerpt_maxMaximum log excerpt length2000
socket_pathUnix socket path for ban reports/var/run/bloqd-agent/report.sock

fail2ban Action

The reporter uses a fail2ban action to capture bans:

# /etc/fail2ban/action.d/bloqd-report.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = /usr/local/bin/bloqd-report "<ip>" "<name>" "<matches>"
actionunban =
actionban_on_restore =

[Init]

The action is triggered on every ban and sends:

  • <ip> - Banned IP address
  • <name> - Jail name
  • <matches> - Log lines that triggered the ban

Important: actionban_on_restore

The empty actionban_on_restore = directive prevents reporting restored bans when fail2ban restarts. This avoids duplicate reports for IPs that were already banned.

Helper Script

The /usr/local/bin/bloqd-report script:

#!/bin/sh
SOCKET_PATH="/var/run/bloqd-agent/report.sock"
IP="$1"
JAIL="$2"
MATCHES="$3"

if [ -z "$IP" ] || [ -z "$JAIL" ]; then
exit 1
fi

if [ ! -S "$SOCKET_PATH" ]; then
logger -t "bloqd-report" "Socket not found: $SOCKET_PATH"
exit 1
fi

# Find netcat command (nc on Debian, ncat on RHEL)
if command -v nc >/dev/null 2>&1; then
NC_CMD="nc"
elif command -v ncat >/dev/null 2>&1; then
NC_CMD="ncat"
else
logger -t "bloqd-report" "netcat not installed"
exit 1
fi

printf '%s %s %s' "$IP" "$JAIL" "$MATCHES" | $NC_CMD -U "$SOCKET_PATH" -w 2

Socket Protocol

The Unix socket accepts two formats:

Simple Format

IP JAIL [LOG_EXCERPT]

Example:

192.168.1.100 sshd Failed password for root from 192.168.1.100

JSON Format

{
"ip": "192.168.1.100",
"jail": "sshd",
"log_excerpt": "Failed password for root..."
}

Ban Report Payload

The module sends bans to the server:

{
"ip": "192.168.1.100",
"jail": "sshd",
"hostname": "web-server-01",
"log_excerpt": "Failed password for root from 192.168.1.100 port 22 ssh2"
}

Events

EventDirectionDescription
ban_detectedSubscribesInternal ban detection
ban_reportedEmitsBan successfully reported

IP Validation

The module validates IP addresses before reporting:

  • IPv4: Standard dotted decimal (e.g., 192.168.1.100)
  • IPv6: Colon-separated hexadecimal (e.g., 2001:db8::1)
  • Invalid IPs are logged and rejected

Troubleshooting

Bans Not Appearing in Dashboard

  1. Check socket exists:

    ls -la /var/run/bloqd-agent/report.sock
  2. Test the helper script:

    /usr/local/bin/bloqd-report 192.0.2.1 test "test message"
  3. Check agent logs:

    journalctl -u bloqd-agent | grep -i reporter
  4. Verify fail2ban action is configured:

    cat /etc/fail2ban/action.d/bloqd-report.conf
  5. Check jail uses the action:

    cat /etc/fail2ban/jail.d/00-bloqd-base.conf

Socket Not Found

If the socket doesn't exist:

  1. Check agent is running:

    systemctl status bloqd-agent
  2. Check reporter module is enabled in config

  3. Restart agent:

    systemctl restart bloqd-agent

Log Excerpts Missing

Log excerpts depend on fail2ban capturing <matches>. Ensure:

  1. Log file is readable by fail2ban
  2. Filter regex captures the relevant lines
  3. log_excerpt_max is set appropriately