InfraGuard

Blocklist & Reputation

Narrates the blacklist_info (/24 range blocks) that AI/IDS auto-defense fills, and lets operators block, release, and re-block ranges directly.

Overview — what it does

Blocklist & Reputation (/security/blocklist) tells the story of the threat ranges that Kitsune ML and Suricata IDS have been auto-blocking, and gives operators a control console to block (add) · release · re-block ranges by hand.

A "block" always covers an entire /24 range. Even if you enter a single IP, only the first three octets are kept and it is normalized to x.y.z.0/24. False positives are exempted via the Whitelist, not by narrowing the block.

When to use

Layout

Top KPIs

Computed by summary() with a 30-second cache (infr:sec:blocklist:summary).

KPI Meaning Calculation
Active blocks /24 ranges currently enforced COUNT(*) WHERE is_use=1
Addresses (subtitle) Addresses covered by active blocks active × 256 (/24 ≈ 256)
Today New blocks in the last 24h is_use=1 AND created_at >= today 00:00
Auto-defense rate Share handled automatically by AI/IDS (kitsune + suricata) / active × 100
Watched countries Distinct countries among active ranges COUNT(DISTINCT country) WHERE is_use=1
Released Currently released (awaiting re-block) COUNT(*) WHERE is_use=0

Defense-engine contribution

Active blocks are broken down by source tag into a share bar plus tiles. Classification is by reason LIKE matching.

Engine Match rule Meaning
Kitsune ML reason LIKE '%Kitsune%' Ensemble-autoencoder anomaly detection
Suricata IDS reason LIKE '%Suricata%' Auto-block on scan / protocol violation
Manual reason LIKE '%Manual%' or %수동% Operator-designated block
Other Everything not matched above active − (kitsune+suricata+manual), floored at 0

Threat origins

blockByCountry(12) aggregates active ranges into the top 12 countries (GROUP BY country ORDER BY COUNT DESC), shown as flag emoji + rank bars. Clicking a bar filters the list to that country.

Recent defense activity feed

blockFeed(16) shows the most recent 16 rows regardless of status (ORDER BY created_at DESC, id DESC) in a 4×4 grid — a live sense of what just got caught.

Filterable block list

40 cards per page (PER_PAGE=40, ORDER BY created_at DESC, id DESC). Each card shows the range · country · source badge · evidence chip (behavior + key figure) · block time · status, with row actions [Reputation] · [Detail] · [Release]/[Re-block]. If a range is a registered internal network it gets an Internal badge and its reputation button is hidden (internal_scope.js).

Filters:

How to use

Reading the reason

Each card's evidence chip picks the single highest-weight ruleset from the reason string and shows it as a label + representative figure. Among srct heuristic categories the top one is chosen by this weight order:

Category marker Weight behavior key Label Representative figure (detail)
[A2:...] 6 brute Admin brute-force hits=N → N hits
[A:...] 5 scanner Vulnerable-path scan hits=N → N hits
[D:...] 4 ja3 JA3 botnet fingerprint ja3=N → ja3×N
[B:...] 3 bot_ua Malicious bot access hits=N → N hits
[C:...] 2 err_flood 4xx error flood err_rate=NN%
[E:...] 1 short_scan TCP port scan port=N or N scan

If the source is Kitsune, or reason contains score=, it is classified as ml_anomaly (ML anomaly) ahead of any category, showing top= (largest-error component) plus score. Manual/other fall back to manual / auto.

Additional facts extracted from reason: score=, top=, port=, short_scan_sessions=, bytes=. Example reasons:

[Kitsune v2.2] anomaly top=TLS score=0.83
[Suricata Auto-Block] [A:URL] hits=42 port=443
[Manual] repeated login abuse (uid=5)

Adding a manual block

  1. [Manual block] in the list header opens the add modal. (When arriving from Threats / IP investigation, the IP is pre-filled from ?add=203.0.113.10.)
  2. Enter an IP or CIDR. A single IP is expanded to /24 (203.0.113.10 → 203.0.113.0/24).
  3. Enter an optional reason (≤ 160 chars) and click [Block].
  4. Server behavior:
    • Input is normalized to x.y.z.0/24 via cclassCidr() (non-IPv4 rejected as invalid_cidr).
    • For a full IPv4, the country is enriched from ip_info_loop (else the existing value / Unknown).
    • If (server_index=0, c_class) already exists it is updated to is_use=1 (reactivated); otherwise a new row is inserted. The reason is "[Manual] <note> (uid=N)".
    • The summary cache is flushed and the refreshed list + summary are returned.

The block hits blacklist_info immediately, but actual firewall DROP is applied when each host's sync_black daemon next syncs it into ipset/iptables. If that batch is not running, the block is not enforced at the firewall.

Release / Re-block

Polling

security-blocklist.js calls /security/blocklist/live every 30 seconds to refresh the summary and current page.

Data sources

Item Source Notes
Block ledger blacklist_info (legacy_glory) id, server_index, c_class, country, reason, is_use, created_at, updated_at · UNIQUE(server_index, c_class)
Country enrichment ip_info_loop (legacy_glory) country lookup for full IPv4 on add
Internal-net check SecurityScope::internalMatchers() registered instance IPs + Ops-Policy whitelist → Internal badge
Firewall enforcement sync_black daemon blacklist_info → ipset/iptables DROP
Auto-block supply kts_tx.js · srct_tx.js writes reason source tags & evidence strings
Audit log infr_audit_log sec.block_add · sec.block_release · sec.block_readd

The read backbone is App\Repositories\SecurityRepository; narration and writes are orchestrated by App\Services\Security\BlocklistService. Credentials come only from config('database.connections.legacy_glory') — never hardcoded.

Access

Because these are destructive security actions, the UI shows a confirm (step-up) dialog before executing. Double-check the CIDR so you don't accidentally block a large range.

Troubleshooting & FAQ

Related

Blocklist and reputation
Blocklist and reputation