InfraGuard

Auto-Block-Pipeline

Der Abwehrablauf im Hintergrund, bei dem Collectors und der Scheduler angreifende IPs, die konfigurierbare Auslöser erfüllen, automatisch listen und über das Kernel-ipset durchsetzen.

Überblick — was diese Funktion leistet

Auto-Block ist die Hintergrund-Pipeline von InfraGuard, die angreifende IPs ohne menschliches Zutun erkennt, prüft und sperrt. Es handelt sich nicht um eine Seite, sondern um einen Ablauf über Collectors, den Scheduler und das Kernel-ipset hinweg. Dieser Artikel dokumentiert diese Gesamtstruktur.

Die Pipeline besitzt zwei voneinander unabhängige Sperrwege, die an einem einzigen Durchsetzungspunkt (ipset) zusammenlaufen.

Weg Läuft als Schreibt nach Einheit Quelle
① Auto-Block des Collectors Node-Collectors auf jedem Host (srct_tx · kts_tx · eve_ingest) blacklist_info /24 (C-Klasse) Suricata L7 · Kitsune ML
② Auto-Block des Schedulers InfraGuard-Anwendung (infr:auto-block → AutoBlockService) infr_block /32 (einzeln) oder /24 suricata_alert_ct · suricata_tls_ct
③ Durchsetzung (gemeinsam) infr_sync_black.mjs (Host-Cron) Kernel-ipset blacklist hash:net Vereinigung von ①+②

Beide Wege führen unmittelbar vor dem Sperren eine Whitelist- und eine Unschuldsprüfung durch. Nur bestätigter Missbrauch übersteht sie; Kandidaten, die wahrscheinlich Fehlalarme sind, werden entlastet. Weg ② (Scheduler) ist standardmäßig deaktiviert und muss von einem Administrator aktiviert werden.

Wann verwenden

Aufbau

Auto-Block hat keine eigene Seite. Seine Steuer- und Beobachtungspunkte sind:

Verwendung

1. Weg ② Auto-Block des Schedulers — aktivieren und abstimmen

Die Voreinstellung ist AUS (autoblock_on=0). Legen Sie den Hauptschalter unter Betriebsrichtlinie ▸ Sicherheitseinstellungen um und passen Sie anschließend die Richtlinie an.

Modus

Wert Bedeutung
global (Standard) Eine auf einem Server beobachtete Kompromittierung wird flottenweit angewendet (server_index=0).
per_server Wird nur auf den angegriffenen Server angewendet — die Ziel-dest_ip wird über infr_server_index zu einem server_index aufgelöst.

Umfang

Wert Der Scheduler schreibt Beschreibung
balanced (empfohlen, Standard) einzelne /32 IDS-Programme verwenden /24; InfraGuard ergänzt einzelne /32 — sync_black überspringt jede /32, die bereits von einer /24 abgedeckt ist.
broad /24 Sperrt die gesamte C-Klasse — breite Abdeckung, aber mit dem Risiko, unbeteiligte Nachbar-IPs zu treffen.
granular einzelne /32 Eine IP nach der anderen — präzise, aber langsam gegen Rotation.

Auslöser (ODER — für einen Kandidaten genügt einer)

① IDS-Regelsatzschwere   suricata_alert_ct
   WHERE alert_ts >= NOW() - INTERVAL {window_min} MINUTE
     AND severity <= {sev_max}          -- crit=1, warn=2 (Suricata: 1=kritisch … 3=niedrig)
   GROUP BY src_ip HAVING COUNT(*) >= {sev_count}

② Botnetz mit JA3-Rotation   suricata_tls_ct
   WHERE event_ts >= NOW() - INTERVAL {ja3_window_min} MINUTE
     AND ja3_hash IS NOT NULL
   GROUP BY src_ip HAVING COUNT(DISTINCT ja3_hash) >= {ja3_rotation}

Die Zeitstempelspalte des Schwere-Auslösers ist alert_ts, während der JA3-Auslöser event_ts verwendet (sie unterscheiden sich je Tabelle). Behalten Sie beim Abstimmen der Schwellenwerte im Blick, auf welche Spalte das jeweilige Zeitfenster filtert.

Richtlinien-Standardwerte (OpsPolicy::autoBlock())

Einstellungsschlüssel Standard Grenzen Bedeutung
autoblock_on 0 — Hauptschalter (1=ein). Standardmäßig AUS
autoblock_mode global global|per_server Sperrmodus
autoblock_scope balanced broad|granular|balanced Sperrumfang
autoblock_interval_min 10 ≥1 Effektives Durchlaufintervall (Min.)
autoblock_window_min 10 ≥1 Auswertungsfenster für die Schwere (Min.)
autoblock_sev_on 1 — Auslöser ① aktiviert
autoblock_severity crit crit|warn crit=sev≤1, warn=sev≤2
autoblock_sev_count 1 ≥1 Mindestzahl an Alarmen im Fenster
autoblock_ja3_on 1 — Auslöser ② aktiviert
autoblock_ja3_rotation 50 ≥2 verschiedene JA3-Fingerabdrücke ≥ N
autoblock_ja3_window_min 360 ≥1 Auswertungsfenster für JA3 (Min. · 6 h)
autoblock_innocent_on 1 — Unschuldsveto aktiviert
autoblock_innocent_days 30 ≥1 Dauer der automatischen Whitelist-Eintragung (Tage)
autoblock_reputation_cap 25 0–200 Reputationsabfragen je Durchlauf

Abstimmung der JA3-Rotation (gemessen): Reale JA3-Rotationstäter erreichen typischerweise einen Höchstwert von etwa 32 verschiedenen JA3 je /32-Sitzung (Rechenzentrums- bzw. Cloud-Bots, ohne GREASE = stabil und sperrbar). Deshalb erfasst der Standardwert ja3_rotation=50 überhaupt nichts. Damit er tatsächlich auslöst, senken Sie ihn auf etwa 15–20. Führen Sie zuerst --dry aus, um die Anzahl der Kandidaten zu sehen.

2. Prüfreihenfolge für Kandidaten (AutoBlockService::run)

Jede erfasste Kandidaten-IP muss diese Hürden der Reihe nach überwinden, bevor sie tatsächlich gesperrt wird.

  1. Ausschluss interner bzw. eigener Netze — übersprungen, wenn SecurityScope::isInternal($ip) zutrifft (skipped_internal). Diese Entscheidung vereinigt die IPs registrierter Instanzen (/24-Präfix + exakte IP) mit der Whitelist internal_networks aus der Betriebsrichtlinie. Bereits in der Abfragestufe wird excludePrefixes() per NOT LIKE vorab ausgeschlossen.
  2. Entlastung durch die Whitelist — übersprungen, wenn infr_whitelist einen aktiven, nicht abgelaufenen /32- oder /24-Eintrag enthält (skipped_wl).
  3. Unschuldsveto — gilt ausschließlich für reine JA3-Kandidaten ohne hartes Signal (Schwere-Auslöser). Innerhalb des Budgets reputation_cap wird die AbuseIPDB-Reputation abgefragt; ist die IP makellos (Missbrauchswert 0 UND Meldungen 0 UND kein Tor), wird sie für innocent_days automatisch auf die Whitelist gesetzt (infr_whitelist(source=auto)), statt gesperrt zu werden (innocent). Schwere-Kandidaten überspringen diese Hürde und werden unmittelbar gesperrt.
  4. Auflösung des server_index — global→[0], per_server→Auflösung der Ziel-dest_ip über ServerIndexResolver::byIp (Rückfall [0]).
  5. Schreiben — Upsert in infr_block über InfrBlock::updateOrCreate([server_index, cidr], …) mit source='schedule', is_active=true, reason='[InfraGuard Auto] …'.
Kandidaten erfassen (ODER) → interne ausschließen → Whitelist → (nur JA3) Unschuldsveto → server_index → infr_block schreiben

isSpotless() liefert false (also: vorsichtshalber sperren), wenn die Reputationsabfrage fehlschlägt, nicht konfiguriert ist oder unaufgelöst bleibt. Die Entlastung durch Unschuld ist eine konservative Hürde, die nur greift, wenn eine IP eindeutig sauber ist.

3. Scheduler und Befehl

infr:auto-block ist ein einmalig ausgeführter Befehl, der einmal auswertet und sich dann beendet — kein Daemon. Der Scheduler taktet jede Minute, das wirksame Intervall ist jedoch autoblock_interval_min.

# Die Sperre prüfen (sofort wirkungslos, wenn die Richtlinie AUS ist), dann einmal auswerten und schreiben
php artisan infr:auto-block

# Nur Kandidaten zählen, ohne Schreibvorgänge (zum Abstimmen/Prüfen)
php artisan infr:auto-block --dry

# Einen Lauf erzwingen und dabei die Richtlinienprüfung (ein + Intervall) umgehen
php artisan infr:auto-block --force

# Ausgabe unterdrücken, wenn nichts gesperrt wurde (für die Planung)
php artisan infr:auto-block --quiet-if-ok

Registrierung im Zeitplan (routes/console.php):

Schedule::command('infr:auto-block --quiet-if-ok')
    ->everyMinute()
    ->withoutOverlapping(2)
    ->onOneServer()
    ->when($is_leader);   // Leader-Gating — nur ein Knoten in der gesamten Flotte

Logik der Prüfung:

Beispielausgabe:

infr:auto-block — Kandidaten 12 (sev 3 · ja3 9) · gesperrt 7 · wl-skip 1 · internal-skip 2 · innocent 2

4. Weg ① Auto-Block des Collectors (Node)

Die Node-Collectors auf jedem Host verarbeiten Suricata-Ereignisse und sperren direkt mit /24-Granularität in blacklist_info. Dieser Weg ist vom Scheduler (Weg ②) unabhängig und läuft immer.

Collector Ebene Erkennt
infr_eve_ingest.cjs Aufnahme Suricata-eve.json → befüllt suricata_http_ct · suricata_tls_ct · suricata_flow_ct · suricata_alert_ct
infr_srct_tx.cjs Signatur/Heuristik Aggregiert Suricata L7 → Scanner-/Bot-Erkennung in 5 Kategorien → blacklist_info /24
infr_kts_tx.cjs Kitsune ML conntrack + Anomalieerkennung per Autoencoder (anomaly_score) → blacklist_info /24

Die fünf Bedrohungskategorien von srct_tx:

(A) [HTTP] URL-Scanner          .env / .git / wp-login und weitere URLs mit Scanner-Signatur
(B) [HTTP] Bot-User-Agent       curl / python-requests / sqlmap und weitere Werkzeugsignaturen
(C) [HTTP] Brute-Force-Sondierung  viele 4xx-Antworten in kurzem Fenster (Pfad-Brute-Force)
(D) [TLS]  JA3-Anomalie         viele JA3, fehlender SNI und weitere Botnetz-Fingerabdrücke
(E) [FLOW] TCP-Flag-Anomalie    viele kurze Scan-Sitzungen (Portscan)

Auch srct_tx führt unmittelbar vor dem Sperren eine Whitelist-Filterung + eine automatische Entlastung durch: Nur E-only-Kandidaten (kurzer Scan allein) erhalten eine AbuseIPDB-Reputationsabfrage, und sind sie eindeutig sauber (0 Meldungen · Missbrauchswert 0 · kein Tor), werden sie als 30-tägige Ausnahme eingetragen (infr_whitelist(source=auto)) und die Sperre entfällt. Liegt irgendein hartes Signal (A/A2/B/C/D) vor, wird unmittelbar gesperrt. Seine Konstanten und Schwellenwerte werden unter Regeln und Schwellenwerte verwaltet.

5. Weg ③ Durchsetzung — sync_black → ipset

infr_sync_black.mjs läuft periodisch auf jedem Host und synchronisiert beide Listen in das Kernel-ipset blacklist.

# Je Host mit dessen server_index ausführen (erfordert root)
node infr_sync_black.mjs sv=4

# crontab (alle 5 Min., flock verhindert Überschneidungen)
*/5 * * * * /usr/bin/flock -n /var/run/sync_black.lock \
  /usr/bin/node /root/server_monitor/infr_sync_black.mjs sv=4 \
  >> /var/log/sync_black.log 2>&1

Verhalten:

  1. Aus blacklist_info (/24) + infr_block (/32) laden, wobei server_index IN (0, <sv>) AND is_active/is_use=1 gilt.
  2. Balanced-Deduplizierung — jede /32 überspringen, deren übergeordnete /24 sie bereits abdeckt.
  3. Das Kernel-ipset auf hash:net zwingen (bei abweichendem Typ neu anlegen), in ein temporäres Set laden und dann atomar tauschen (ohne Ausfallzeit).
  4. Sicherstellen, dass iptables -I INPUT -m set --match-set blacklist src -j DROP vorhanden ist (idempotent).
  5. Sicherheitsnetz — private (RFC1918), Loopback- und eigene Netzpräfixe (HOME_NET_PREFIX) werden niemals in das ipset geladen, selbst wenn sie in die Datenbank gelangen.

sync_black benötigt root sowie die Kernel-Werkzeuge ipset/iptables, und das ipset blacklist muss auf dem Zielhost bereits vorhanden sein:

ipset create blacklist hash:net family inet hashsize 8192 maxelem 65536
iptables -I INPUT -m set --match-set blacklist src -j DROP

Datenquellen

Alle Quell- und Protokolltabellen liegen auf der Verbindung legacy_glory (der von Collectors und Durchsetzungsskripten gemeinsam genutzten Datenbank).

Tabelle Verbindung Rolle Einheit
suricata_alert_ct legacy_glory Quelle des Schwere-Auslösers (Spalten alert_ts · severity · src_ip · dest_ip · signature) —
suricata_tls_ct legacy_glory Quelle des JA3-Rotationsauslösers (Spalten event_ts · ja3_hash · src_ip) —
blacklist_info legacy_glory Auto-Block-Liste des Collectors (IDS-Programme · srct/kts) /24
infr_block legacy_glory Sperrliste im Besitz des InfraGuard-Schedulers (Migration 000751) /32·/24
infr_whitelist legacy_glory Sperr-Ausnahmen (manuell · automatische Unschuld · Seed) /32·/24
infr_server_index default (MAIN) Nachschlagetabelle für den dünn besetzten, nicht fortlaufenden server_index ↔ Alias/Instanz (000750) —

Schema von infr_block (Zusammenfassung)

Spalte Typ Bedeutung
server_index int 0=global · sonst=über infr_server_index aufgelöster Server
cidr varchar(43) einzelne IP (/32) oder normalisierte /24 · UNIQUE(server_index,cidr)
ip varchar(45) ursprüngliche IP (Anzeige)
reason varchar(500) Nachweis des Auslösers ([InfraGuard Auto] sev1 x3 …)
source varchar(16) auto · manual · schedule
is_active bool ob sync_black den Eintrag lädt
expires_at datetime NULL=dauerhaft
last_seen_at datetime letzte erneute Erkennung (Entscheidung über die Bereinigung)

Zugriff

Auto-Block besitzt keine Benutzeroberfläche zur Ausführung. Die einschlägigen Berechtigungsprüfungen sind (Stufen: demo=1 · staff=5 · admin=10):

Ziel Erforderlicher Zugriff
Konfiguration der Auto-Block-Richtlinie (Betriebsrichtlinie ▸ Sicherheitseinstellungen) Administrator (Verwaltung, Stufe ≥5 / admin)
Einsicht in die Sperrergebnisse (Sperrliste) Lesezugriff Sicherheit (staff, Stufe ≥2)
Manuelles Sperren/Freigeben · Schreibzugriff auf die Whitelist staff (Stufe ≥2) + Auditprotokoll
Ausführung durch den Scheduler (infr:auto-block) System (kein angemeldeter Benutzer) — per Leader-Gating

Die vom Scheduler verwendeten Zugangsdaten sind niemals fest im Code hinterlegt — sie sind nach infr_collector / .env ausgelagert. Ebenso werden die Datenbank-Zugangsdaten von sync_black und die Präfixe des eigenen Netzes über Umgebungsvariablen oder die Mashup-Ersetzung unter Inventar ▸ Werkzeuge eingespeist (keine feste Hinterlegung).

Fehlerbehebung und FAQ

Ich habe es eingeschaltet, aber es wird nichts gesperrt.

Die Sperren erreichen die tatsächliche Firewall nicht.

Eine unbeteiligte IP wurde gesperrt.

Der Modus ist per_server, doch die Einträge landen global (server_index=0).

Der Scheduler läuft auf mehreren Servern gleichzeitig.

Verwandte Themen

자동 차단 스위치가 있는 운영 정책 보안 탭
자동 차단 스위치가 있는 운영 정책 보안 탭
자동 차단 결과가 쌓이는 차단 목록
자동 차단 결과가 쌓이는 차단 목록