Pipeline Filters#

The pipeline is an ordered chain of filters. Each filter assigns a score (0.0–1.0) to the request. When the cumulative score exceeds block_score_threshold, the request is dropped and drop_action fires.

Schema#

pipeline:
  filter_mode: "scoring"        # scoring | strict
  block_score_threshold: 0.7    # cumulative score threshold for BLOCK

  enable_ip_filter: true        # IP blocklist / threat intel feeds
  enable_bot_filter: true       # user-agent bot detection
  enable_header_filter: true    # header anomaly detection
  enable_geo_filter: true       # country/ASN geofencing
  enable_dns_filter: true       # PTR/rDNS analysis
  enable_profile_filter: true   # C2/phishing profile validation
  enable_replay_filter: true    # replay attack prevention
  replay_window_seconds: 86400
  replay_persist: true          # survive restarts (SQLite-backed)

  enable_enumeration_filter: true
  enumeration_unique_path_threshold: 20     # BLOCK at this many unique paths
  enumeration_unique_path_suspect_threshold: 8
  enumeration_window_seconds: 60

  enable_sandbox_filter: true   # headless browser / sandbox detection
  enable_ja3_filter: true       # TLS fingerprint filtering

  ja3_filter:
    ja3_header: "x-ja3"         # header injected by load balancer (nginx/Caddy)
    log_ja3: true
    block_unknown: false        # block hashes not in allowed_ja3
    blocked_ja3:
      - "e7d705a3286e19ea42f587b344ee6865"   # Masscan
      - "c35b0c7bd583d49d5b0f17de25ecdf7a"   # ZGrab2
      - "6734f37431670b3ab4292b8f60f29984"   # Python requests
      - "b386946a5a44d1ddcc843bc75336dfce"   # curl
    allowed_ja3: []             # if block_unknown=true, allowlist beacon hashes

Filter Modes#

ModeBehavior
scoringAccumulate scores; block when total ≥ threshold. Nuanced — a request with several minor signals is blocked while one strong signal alone may not be.
strictAny single BLOCK result from any filter drops the request immediately.

scoring is recommended for phishing (avoid blocking legitimate but imperfect browser fingerprints). strict is appropriate for C2 (only known beacons should ever reach the backend).

Filter Descriptions#

IP Filter#

Checks source IP against:

  • Internal blocklist (manual adds via CLI)
  • Threat intel feeds (auto-refreshed)
  • Tor exit nodes
  • Known cloud/datacenter ranges

Bot Filter#

Scores based on User-Agent string. Headless Chrome, Googlebot, curl, wget, Python, and common scanner UAs score high.

Header Filter#

Detects anomalous HTTP headers: missing Accept, Accept-Language, unusual header ordering, scanner-specific custom headers.

Geo Filter#

Blocks or scores requests from configured countries or ASNs.

geo:
  blocked_countries: ["CN", "RU", "KP"]
  allowed_countries: []    # if set, all others blocked
  blocked_asns: [15169, 8075]

DNS Filter#

Reverse DNS lookup on source IP. Scores cloud providers, hosting ASNs, Tor exit PTR records.

Profile Filter#

For C2 domains: validates that the request matches the loaded C2 profile (URI pattern, method, required headers). Non-matching requests score high.

For phishing domains: validates paths match profile_type patterns.

Replay Filter#

Hashes each request (IP + path + body digest + timestamp bucket). Duplicate within replay_window_seconds scores 1.0 (BLOCK). With replay_persist: true, persists to SQLite — survives restarts.

Enumeration Filter#

Per-IP sliding window tracking unique paths. Dirbuster/ffuf/gobuster hit the threshold quickly; legitimate beacons hit 1–3 paths.

Sandbox Filter#

Scores based on headless browser and sandbox signals:

  • HeadlessChrome UA: +0.7
  • Missing Accept-Language: +0.25
  • Chrome UA without sec-ch-ua: +0.2
  • No Referer on non-root path: +0.15
  • Non-browser Accept ordering: +0.1

JA3 Filter#

Blocks requests with known scanner TLS fingerprints. Operates at TLS handshake — before HTTP pipeline runs. Requires JA3 hash injection by an upstream component (nginx, Caddy, HAProxy).

CLI Pipeline Management#

# Show current pipeline config
infraguard config pipeline show -c config.yaml

# Enable/disable a filter
infraguard config pipeline enable sandbox_filter -c config.yaml
infraguard config pipeline disable replay_filter -c config.yaml

# Set score threshold
infraguard config pipeline set-threshold 0.65 -c config.yaml

# Block/unblock JA3 hashes
infraguard config pipeline ja3 block e7d705a3286e19ea42f587b344ee6865 -c config.yaml
infraguard config pipeline ja3 unblock e7d705a3286e19ea42f587b344ee6865 -c config.yaml
infraguard config pipeline ja3 list -c config.yaml