Skip to content

Detection and Bans

Paco5687 edited this page Jul 13, 2026 · 1 revision

Detection and Bans

secwatch turns access-log and auth-log activity into events, and the hostile ones into bans enforced at your proxy or firewall.

What it detects

Edge (access log):

  • Vuln probes — requests for known-exploitable paths.
  • Secret-file probes.env, .git, .aws, .ssh, and similar. Banned on sight (there's no legitimate reason to fetch these).
  • Path scanning — many 4xx across many paths from one IP.
  • Floods / rate abuse — request-rate spikes.
  • Credential stuffing — repeated auth failures against a login endpoint.
  • Custom per-endpoint rules — see below.

Host:

  • SSH / auth — brute-force sources from auth.log.
  • Persistence baseline — new systemd units, SUID binaries, ld.so.preload, cron entries, shell rc changes, UID-0 accounts.
  • Process signatures — reverse shells, miners, temp-dir execs, curl … | bash.
  • File integrity — webshells / dropped scripts in web roots, ransomware canaries.
  • Egress / C2 awareness — new outbound destinations.

Watchdogs — alerts if the access log goes silent (proxy down or logging disabled) or the proxy's route config changes unexpectedly.

Custom per-endpoint rules

Declarative rules match your app's real paths. Types: auth_abuse, privileged, rate, enumeration.

app_hosts:
  - app.example.com

endpoint_rules:
  - name: login_bruteforce
    label: app login
    hosts: [app.example.com]
    path_re: '^/(login|auth|signin)($|[/?])'
    type: auth_abuse
    statuses: [400, 401, 403, 422, 429]
    window: 300      # seconds
    limit: 12        # events in the window → fire
    severity: high
    ban: true

Auto-ban

High-severity events from banning rules trigger an auto-ban (configurable TTL). Enforcement is handled by a ban actuator:

ban:
  enabled: true
  actuator: traefik    # traefik | nftables | nginx | none
Actuator How it blocks Needs
traefik writes a ClientIP deny router file proxy.bans_file path
nftables maintains an nft set dropped in the input chain root
nginx writes a deny <ip>; include + reloads nginx root
none alert only, don't actually block

You can also ban/unban an IP by hand from the dashboard.

Traefik note: secwatch writes two ban routers (one for web, one for websecure with TLS) — a Traefik router is either TLS or non-TLS, so a single router would only block one protocol. secwatch handles this for you.

Trusted networks — keep them narrow

network.trusted_nets are exempt from detection and bans. Make this the server subnet plus the specific admin hosts you manage from — not your whole LAN. If your desktop VLAN is trusted and a device there is compromised, its attacks would sail through unblocked.

network:
  trusted_nets:
    - 127.0.0.0/8
    - 10.0.10.0/24        # server subnet
    - 10.0.20.50/32       # your admin workstation
  autoban_private: false  # LAN anomalies alert but aren't auto-banned by default

Set autoban_private: true only if you're confident you won't lock out a legit internal device on a false positive.

Never-ban list

Shared proxy edges (e.g. Cloudflare ranges) are exempt from banning by default — banning one would hit every visitor behind that edge. Override ban.exempt_nets if needed.

Clone this wiki locally