How to Report CrowdSec Detections to AbuseIPDB

Introduction

CrowdSec can be configured to automatically report detected malicious IP addresses to AbuseIPDB, a community-driven database of abusive IP addresses. This article will show you how it can be set up.

Creating an AbuseIPDB Account

To report IP addresses to AbuseIPDB, you need a free account. Visit the AbuseIPDB registration page and sign up. A free account can report up to 1,000 IPs a day, this can be increased to 3,000 a day by confirming your ownership of a domain.

Generating an API Key

After registering, navigate to the API section in your account settings and generate a new API key.

Configuring CrowdSec

CrowdSec uses an HTTP notification plugin to send reports. Create a file called abuseipdb.yaml in the CrowdSec notifications directory /etc/crowdsec/notifications. This file defines the HTTP request that CrowdSec sends to the AbuseIPDB API each time a new alert is triggered.

You also need to reference this notification in your CrowdSec profiles configuration /etc/crowdsec/profiles.yaml so that alerts are routed to the plugin:

# profiles.yaml (add to your existing profile)
notifications:
  - report_abuseipdb

Notification Configuration

The configuration below uses CrowdSec's Go template syntax to build the JSON payload. It extracts the alert's source IP, maps the CrowdSec scenario to AbuseIPDB category codes, and includes the scenario name as a comment.

The AbuseIPDB categories field uses numeric codes to classify the type of abuse. A list of these categories can be found here.

Each CrowdSec scenario is mapped to one or more of these categories. For example, SSH brute-force scenarios map to categories 22 (SSH) and 18 (Brute-Force).

# abuseipdb.yaml
name: report_abuseipdb
type: http
log_level: debug
url: https://api.abuseipdb.com/api/v2/report
method: POST
headers:
    Content-Type: application/json
    Key: #YOUR_ABUSEIPDB_API_KEY#
format: |
    {
    {{range . -}}
    {{$alert := . -}}
    {{range .Decisions -}}
    "ip": "{{ $alert.Source.IP }}",
    "categories": [
        {{ if contains $alert.Scenario "crowdsecurity/apache_log4j2_cve-2021-44228" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/appsec-native" }} "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/appsec-vpatch" }} "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/crowdsec-appsec-outofband" }} "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2017-9841" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2019-18935" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2021-4034" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-26134" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-35914" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-37042" }} "15", "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-40684" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-41082" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-41697" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-42889" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-44877" }} "15", "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2022-46169" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2023-22515" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2023-22518" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2023-23397" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2023-49103" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2023-4911" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2024-0012" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2024-38475" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/CVE-2024-9474" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/f5-big-ip-cve-2020-5902" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/fortinet-cve-2018-13379" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/grafana-cve-2021-43798" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-admin-interface-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-backdoors-attempts" }} "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-bad-user-agent" }} "21", "19" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-bf-wordpress_bf" }} "18", "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-crawl-non_statics" }} "21", "19" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-cve-2021-41773" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-cve-2021-42013" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-cve-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-dos-bypass-cache" }} "4" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-dos-invalid-http-versions" }} "4" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-dos-random-uri" }} "4" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-dos-switching-ua" }} "4" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-generic-bf" }} "21", "18" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-open-proxy" }} "21" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-path-traversal-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-sap-interface-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-sensitive-files" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-sqli-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-wordpress_user-enum" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-wordpress_wpconfig" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-wordpress-scan" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/http-xss-probing" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/jira_cve-2021-26086" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/netgear_rce" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/pulse-secure-sslvpn-cve-2019-11510" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/spring4shell_cve-2022-22965" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/ssh-bf" }} "22", "18" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/ssh-slow-bf" }} "22", "18" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/ssh-time-based-bf" }} "22", "18" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/thinkphp-cve-2018-20062" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/vmware-cve-2022-22954" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "crowdsecurity/vmware-vcenter-vmsa-2021-0027" }} "21", "15" {{end}}
        {{ if contains $alert.Scenario "ltsich/http-w00tw00t" }} "21" {{end}}
    ],
    "comment": "CrowdSec detection: {{ $alert.Scenario }}"
    {{end -}}
    {{end -}}
    }

Replace the Key value in the headers with your own AbuseIPDB API key. You can extend the scenario-to-category mapping by adding more if contains blocks for any additional CrowdSec scenarios you have installed.

Sources

  1. Reddit - Integrate CrowdSec with AbuseIPDB