# AbuseTrack × CrowdSec

Two-way integration, pick either or both:

- **Report** the IPs CrowdSec bans locally back to the AbuseTrack community
  (like the fail2ban integration). See [Report bans to AbuseTrack](#report-bans-to-abusetrack).
- **Consume** the AbuseTrack community blocklist inside CrowdSec, so flagged
  IPs get blocked by your bouncers. See [Consume the blocklist](#consume-the-blocklist).

---

## Report bans to AbuseTrack

Every IP CrowdSec bans locally (WordPress brute-force, scanners, CVE probes, …)
is reported to your AbuseTrack account through the public API. Report-only: it
never touches your firewall or CrowdSec decisions, and it only reports
`origin: crowdsec` detections, so IPs you pull from the community blocklist are
never reported back (no feedback loop).

### Install

Create an API key at `…/account/api-keys`, then as **root**:

```bash
curl -fsSL https://abusetrack.io/integrations/crowdsec/install.sh | \
  AT_API_KEY=your_api_key AT_API_URL=https://abusetrack.io bash
```

The installer auto-detects CrowdSec (docker container or host `cscli`), writes
`/etc/abusetrack/crowdsec.conf`, installs the reporter to
`/usr/local/bin/abusetrack-crowdsec-report`, adds a cron job that runs every 10
minutes, shows a preview and sends one harmless test report.

### Options (environment variables)

| Variable            | Default            | Meaning                                              |
| ------------------- | ------------------ | ---------------------------------------------------- |
| `AT_API_KEY`        | _(required)_       | Your AbuseTrack API key                              |
| `AT_API_URL`        | `https://abusetrack.io` | Base URL of the AbuseTrack instance             |
| `AT_CONTAINER`      | _(auto-detect)_    | CrowdSec docker container name (empty = host cscli)  |
| `AT_THREAT_DEFAULT` | `Port Scan`        | Fallback threat type when no scenario rule matches   |
| `AT_COOLDOWN_HOURS` | `24`               | Don't re-report the same IP within this window       |
| `AT_INTERVAL_MIN`   | `10`               | Cron interval in minutes                             |

### Scenario → threat-type mapping

| CrowdSec scenario contains                  | Reported as   |
| ------------------------------------------- | ------------- |
| `bf`, `brute`, `wordpress_bf`               | Brute Force   |
| `scan`, `probing`, `crawl`, `user-agent`, `proxy` | Port Scan |
| `wpconfig`, `env-access`, `git-config`, `backup` | Data Theft |
| `cve`, `rce`, `exploit`, `log4j`, `sqli`, … | Malware       |
| anything else                               | `AT_THREAT_DEFAULT` |

### Try it without sending anything

```bash
AT_DRY_RUN=1 /usr/local/bin/abusetrack-crowdsec-report
```

### How a report looks

```json
{
  "type": "ip",
  "value": "203.0.113.10",
  "threatType": "Brute Force",
  "comment": "CrowdSec: crowdsecurity/http-bf-wordpress_bf (6 events)"
}
```

### Uninstall

```bash
rm /etc/cron.d/abusetrack-crowdsec /usr/local/bin/abusetrack-crowdsec-report
```

---

## Consume the blocklist

Use the community-reported abusive IPs from AbuseTrack as a blocklist in
CrowdSec. Every IP that enough people flagged becomes a CrowdSec decision and
gets blocked by your bouncers, on top of CrowdSec's own scenarios.

The feed lives at:

```
https://abusetrack.io/api/v1/blocklist.txt
```

It is plain text, one IP per line, and authenticated with your AbuseTrack API
key. Create one at `…/account/api-keys`.

## Quick test

```bash
curl -fsSL -H "Authorization: Bearer YOUR_API_KEY" \
  "https://abusetrack.io/api/v1/blocklist.txt"
```

## Tuning (query parameters)

| Param       | Default | Meaning                                                         |
| ----------- | ------- | --------------------------------------------------------------- |
| `score`     | `25`    | Minimum community risk score, 0-100 (25 = Medium and up)        |
| `reporters` | `1`     | Require at least this many distinct reporters                   |
| `since`     | _(off)_ | Only IPs reported within the last N days                        |
| `limit`     | `10000` | Maximum number of IPs                                            |
| `comments`  | `1`     | `0` returns pure IPs with no `#` header (for `cscli ... import`) |

A stricter, lower-noise feed, for example:

```
…/api/v1/blocklist.txt?score=60&reporters=2&since=30&comments=0
```

## Import into CrowdSec (cron)

The simplest, version-agnostic method: pull the feed and import it as ban
decisions. Use `comments=0` so the `#` header is left out.

`/etc/cron.d/abusetrack-blocklist`:

```cron
*/30 * * * * root curl -fsSL -H "Authorization: Bearer YOUR_API_KEY" "https://abusetrack.io/api/v1/blocklist.txt?score=60&reporters=2&comments=0" -o /tmp/abusetrack.txt && cscli decisions import -i /tmp/abusetrack.txt --format values --duration 36h --reason "AbuseTrack community blocklist" >/dev/null 2>&1
```

Poll every 15-30 minutes, not every few seconds. The feed is cached for 5
minutes and **counts as one API call per refresh** against your daily account
quota, so a 30-minute cron uses about 48 calls a day, far under any tier.
Set `--duration` a little longer than your poll interval so entries refresh
before they expire.

Flags differ slightly between CrowdSec versions; check `cscli decisions import --help`.

## Console (CrowdSec SaaS)

If you use the CrowdSec Console, you can instead subscribe to the URL directly
under **Blocklists → Add a custom blocklist**, using the same feed URL. The
console pulls it for you; no cron needed.

## Verify

```bash
cscli decisions list | grep AbuseTrack    # imported bans
cscli decisions list -o json | head       # full detail
```

## Notes

- The feed is **report-direction-independent**: it only *consumes* AbuseTrack
  data. To also *report* the IPs your own server bans back into the community,
  point a CrowdSec HTTP notification (or a small script over
  `cscli decisions list`) at `POST /api/v1/reports`.
- Private, loopback and reserved ranges are never reportable, so they never
  appear in the feed.
