# KonfiguracjaKażde pokrętło, które oferuje daemon — zmienne środowiskowe, ścieżki plików i punkty integracji.

Daemon jest konfigurowany w całości przez zmienne środowiskowe i dwa pliki na dysku. Bez konieczności zmian w kodzie, aby dostosować zachowanie.

## Zmienne środowiskowe

| Zmienna | Typ | Default | Cel |
|---|---|---|---|
| `ABUSIVE_FAMILY` | `v4` / `v6` / `any` | `any` | Ograniczyć matching do rodziny IP. |
| `ABUSIVE_MIN_HITS` | integer ≥ 1 | `3` | Trafienia ze źródła, zanim IP zostanie zapisane na blocklistę. |
| `ABUSIVE_SCOPE` | lista oddzielona przecinkami | `request,ua` | Które pola loga są oceniane. Dozwolone: `request`, `ua`, `referrer`. |
| `ABUSIVE_REFERRER_DOMAINS` | lista whitespace/przecinek | _(puste)_ | Dozwolone hosty referrer. Istotne tylko, gdy `referrer` w `ABUSIVE_SCOPE`. |
| `ABUSIVE_SYSLOG_TAG` | string | `abusive_http_watch` | Tag programu syslog. |
| `ABUSIVE_SYSLOG_FACILITY` | string | `daemon` | Facility syslog. `local0`–`local7` dla własnych routingów. |
| `ABUSIVE_SYSLOG_PRIO` | `info` / `notice` / `warn` / `err` | `notice` | Priorytet syslog dla eventów `added`. |
| `ABUSIVE_DEBUG` | `0` / `1` | `0` | Verbose-stderr-trace każdej linii. Sensowne tylko do scopingu. |

### Uwagi

- **`ABUSIVE_MIN_HITS`** — Ustawienie na `1` blokuje przy pierwszym trafieniu. Agresywniej, ale podnosi ryzyko false-positive przez sondy one-shot z benignych cloud-IP, które później pojawiają się regularnie. Default `3` to dobry kompromis.
- **`ABUSIVE_SCOPE`** — `referrer` jest domyślnie wyłączony, ponieważ złośliwy referrer przez drive-by mógłby wepchnąć IP twojego odwiedzającego na blocklistę. Włączać tylko, gdy `ABUSIVE_REFERRER_DOMAINS` jest ustawiony jako ścisła allowlist.
- **`ABUSIVE_FAMILY`** — Przydatne, gdy chce się odzwierciedlić daemona przez dwa procesy: jeden dla IPv4, jeden dla IPv6, każdy z własnym plikiem blocklisty.

## Zestaw tokenów

Zestaw regex wykrywania jest na sztywno wpisany w skrypcie (`@TOKENS`) i pokrywa osiem klas ataków — eksploatacja PHP, sondy WordPress, path-traversal, ścieżki wrażliwe, próby RCE/CGI, SQL-injection, sondy login-loop i null-byte-injection.

Aby dostosować zestaw:

1. Otworzyć skrypt.
2. Dostosować tablicę `@TOKENS` — dodać lub usunąć wzorce, jeśli występują false-positives.
3. Zrestartować daemona.

Zestaw jest celowo konserwatywny. Dodawanie tokenów typu `/admin`, `/login` czy `phpmyadmin` bez scopingu prowadzi do false-positives na legalnym ruchu.

## Plik whitelist

Ścieżka: `/etc/abusive_http_whitelist`

Jeden wpis na linię. Wspierane są trzy formaty:

```
# komentarze dozwolone
203.0.113.42                    # pojedyncze IPv4
2001:db8::abcd                  # pojedyncze IPv6 (pełne lub skrócone)
203.0.113.0/24                  # IPv4 CIDR
2001:db8::/32                   # IPv6 CIDR
```

IP z whitelist są w całości pomijane — nie zwiększają licznika trafień i nigdy nie lądują na blockliście, nawet jeśli ich requesty trafiają w każdy token z zestawu.

Whitelisty używać dla:

- Publicznych IP biura i VPN (operatorzy, którzy nieumyślnie odpalają skanery).
- Dokumentowanych legalnych ranges crawlerów wyszukiwarek (Google, Bing). Najpierw przetestować — rzadko konieczne, bo ich requesty nie trafiają w tokeny ataków.
- Serwisów monitoringowych, które celowo odpytują `/wp-login.php`.

## Plik blocklisty

Ścieżka: `/var/www/run/abusive_http_hosts`

Format: jedno IP na linię, bez komentarzy, bez nagłówków, bez duplikatów. Daemon zapewnia deduplikację przez hash in-memory i `flock(LOCK_EX)` przy zapisie.

Plik jest w czasie działania **append-only** — stare wpisy nigdy nie są usuwane przez daemona. Do sprzątania (np. wygaszanie wpisów po 30 dniach) używać rotacji zewnętrznej:

```sh
# W cron dziennym
mv /var/www/run/abusive_http_hosts /var/www/run/abusive_http_hosts.old
touch /var/www/run/abusive_http_hosts
chown _www:_www /var/www/run/abusive_http_hosts
doas rcctl restart abusive_http_watch
```

To wymusza na daemonie odbudowę stanu in-memory z pustego pliku. Firewall ładuje nową (pustą) blocklistę przy następnym ticku crona.

## Konsumpcja przez firewall

Format pliku blocklisty jest celowo płaski, aby każda warstwa mogła go skonsumować. Częste integracje:

### OpenBSD `pf`

```pf
table <abusive> persist file "/var/www/run/abusive_http_hosts"
block in quick on egress from <abusive>
```

Przeładować tabelę:

```sh
pfctl -t abusive -T replace -f /var/www/run/abusive_http_hosts
```

### Linux `nftables`

```nft
table inet filter {
  set abusive_v4 {
    type ipv4_addr
    elements = { ... }
  }
  chain input {
    ip saddr @abusive_v4 drop
  }
}
```

Set przeładowywany przez helper z pliku:

```sh
nft 'flush set inet filter abusive_v4'
awk '/^[0-9]/ {print}' /var/www/run/abusive_http_hosts | \
  xargs -I{} nft 'add element inet filter abusive_v4 { {} }'
```

### Apache

```apache
<RequireAll>
  Require all granted
  Require not ip 203.0.113.0/24
  # … jeden Require not ip per wpis blocklisty
</RequireAll>
```

Generowane przez templater (`m4`, `sed`) z pliku blocklisty na cronie. Reaguje wolniej niż integracja firewallowa, ale działa, gdy nie kontrolujesz samej warstwy firewall.

### nginx

```nginx
geo $abusive {
  default 0;
  include /var/www/run/abusive_http_nginx.conf;
}
server {
  if ($abusive) { return 444; }
}
```

`abusive_http_nginx.conf` jest generowany przez template z pliku blocklisty.
