1. Comprehensive CLI Flags Reference

The persistent flags below (from --from to --namespace) are inherited by every subcommand (tail, top, diff, guard, config, block, unban, export-sigma) and the main analysis run. The root-only flags --watch, --follow, --interval, --detect, and --version are available only on caddy-analyze itself (see the "Display & Output" table below).

Time Range & Request Filters

Time range and request filtering flags
Flag Short Default Description & Usage Example
--from โ€” "" Filter entries after a time (RFC3339 or relative: 5m, 1h, 2d). caddy-analyze --from 1h
--to โ€” "" Filter entries before a time (RFC3339). caddy-analyze --to 2024-01-02T00:00:00Z
--ip โ€” "" Filter by client IP or CIDR subnet. caddy-analyze --ip 192.168.1.50 or --ip 10.0.0.0/8
--exclude-ip โ€” "" Exclude IP or CIDR subnet. caddy-analyze --exclude-ip 10.0.0.0/8
--status -s "" Filter by status code(s). caddy-analyze -s 200,404
--method -m "" Filter by HTTP method. caddy-analyze -m POST
--path -p "" Filter by path glob. caddy-analyze -p /api/*
--slow โ€” "" Filter requests slower than duration. caddy-analyze --slow 500ms
--2xx โ€” false Filter 2xx success responses. caddy-analyze --2xx
--3xx โ€” false Filter 3xx redirect responses. caddy-analyze --3xx
--4xx โ€” false Filter 4xx client errors. caddy-analyze --4xx
--5xx โ€” false Filter 5xx server errors. caddy-analyze --5xx
--errors-only -e false Filter server errors only. caddy-analyze -e
--no-bots โ€” false Exclude bot/crawler traffic. caddy-analyze --no-bots
--bots-only โ€” false Include only bot traffic. caddy-analyze --bots-only
--grep โ€” "" Search across URI, User-Agent, IP, Host. caddy-analyze --grep "/api"
--host โ€” "" Filter by request host (substring match, case-insensitive). caddy-analyze --host example.com
--max-latency โ€” "" Filter requests faster than a duration (counterpart to --slow). caddy-analyze --max-latency 100ms
--min-size โ€” "" Filter responses at least this size (bytes, or k/mb/gb suffix). caddy-analyze --min-size 1mb
--max-size โ€” "" Filter responses at most this size (bytes, or k/mb/gb suffix). caddy-analyze --max-size 512kb

Filter Behavior: Listing vs Report

When entry-level filters (--ip, -s, -m, -p, --5xx, --no-bots, --grep, etc.) are active, caddy-analyze automatically switches to a color-coded log listing instead of the aggregate report. Active filters are shown in the output header for all formats.

caddy-analyze --ip 10.0.0.0/8 access.log
15 entries matched

14:29:01  204 OK  OPTIONS /heartbeat  (0 B, 1.05ms) - 104.28.161.103
14:29:01  200 OK  POST /heartbeat     (0 B, 4.04ms) - 104.28.161.103

Use -f json, -f csv, -f html, or -o <file> to force the aggregate report. Time-based filters (--from, --to) alone still show the report.

Display & Output Configuration Flags

Display and output configuration flags
Flag Short Default Description & Usage Example
--detect -d false Enable security threat detection (SQLi, XSS, Path Traversal, Log4j, RCE, Probes, Scanners). Shows per-IP suspicious request details. caddy-analyze --detect
--format -f table Set output report format: table, json, csv, html. caddy-analyze -f html -o report.html
--output -o "" Write report output to specified file path instead of stdout. caddy-analyze -o analysis.txt
--watch -w false Launch 6-tab interactive full-screen terminal TUI dashboard (Bubbletea). caddy-analyze --watch
--top -t 10 Set maximum number of top entries displayed in tables. caddy-analyze -t 25
--interval -i "" Periodically re-run analysis every N duration (e.g. 10s, 1m). caddy-analyze -i 10s
--follow -F false Stream and process incoming log lines in real-time follow mode (like tail -f). caddy-analyze -F
--version -v false Print version (injected via -ldflags at build time; dev if unset) and exit.
--compact -c false Compact output mode (smaller, condensed tables). caddy-analyze -c
--max-cardinality โ€” 100000 Max distinct keys tracked per counter (paths, IPs, UAs). 0 = unlimited. Bounds memory on huge-cardinality logs.
--ua-rotation โ€” 10 Distinct User-Agents from one IP before the scanner/rotation heuristic fires (0 = default). Root-level variant of the guard flag.
--defang โ€” false Defang IPs in output (replace . with [.]) for safe sharing of IOCs. caddy-analyze tail --detect --defang
--namespace -n "" Kubernetes namespace for k8s:// sources. caddy-analyze top ip -n production k8s://pod

2. Subcommands Specification

caddy-analyze [source] [flags]

Runs batch analysis over the log source. When entry-level filters are active, shows a color-coded log listing instead of the aggregate report. Supports all flags.

caddy-analyze
caddy-analyze --detect
caddy-analyze --ip 10.0.0.0/8
caddy-analyze --5xx --no-bots
caddy-analyze -f html -o report.html

tail [source] [flags]

Streams and colorizes access log entries in real time. Supports all root-level filters (--ip, --5xx, --no-bots, etc.).

caddy-analyze tail docker://my-caddy
caddy-analyze tail --ip 192.168.1.100 --no-bots

--detect / -d (local flag)

Runs the full 26-category detection engine on every streamed entry and highlights threats inline with zero visual noise:

caddy-analyze tail --detect docker://my-caddy
caddy-analyze tail -d --ip 10.0.0.0/8 /var/log/caddy/access.log
caddy-analyze tail --detect --defang journalctl://

Works with --defang for safe IOC sharing. Note: --detect is a local flag on tail, not the root-level --detect.

โ„น Note

The --detect / -d flag on tail is a local flag โ€” it only applies to the tail subcommand, not to root-level caddy-analyze --detect.

top [dimension] [source] [flags]

Inspects top metrics by dimension (path, ip, ua, status, method, host, bandwidth). Supports -b, --by <dim> flag and filters like --5xx, --slow, --no-bots. Output respects the shared format and file options (-f json|csv, -o <file>).

caddy-analyze top ip -f csv /var/log/caddy/access.log
caddy-analyze top path --5xx -f json -o top.json /var/log/caddy/access.log

diff <log1> <log2>

Compares two log files side-by-side to detect RPS shifts, 5xx error spikes, latency regressions, and new failing URIs between deployments. Supports the shared format and file options (-f json|csv|html, -o <file>) and standard filters.

config [show|set|reset]

Manages persistent default log source settings in local (./caddy-analyzer.json) or global (~/.config/caddy-analyzer/config.json) JSON config files. Use the --global / -g flag to read or write the global config instead of the local one. Kubernetes sources are saved with the shared -n, --namespace flag:

caddy-analyze config k8s://caddy-pod-abc12 -n production     # remember pod + namespace

export-sigma [file]

Exports 23 detection categories as Sigma YAML rules (multi-document) for SIEM import (Splunk, Elastic, Sigma-compatible SIEMs). Each rule includes MITRE ATT&CK tags, deterministic UUID, and dynamically-constructed detection conditions. Validate with sigma check. The 3 behavioral detections (ua_rotation, object_enumeration, beaconing) are not pattern-based and not exported.

caddy-analyze export-sigma                    # stdout
caddy-analyze export-sigma rules.yml          # file
caddy-analyze export-sigma - | sigma check    # pipe to validator

guard [source] & block / unban

Monitors streaming logs and automatically adds offending IP addresses to Linux iptables DROP rules when attack thresholds are exceeded (--limit 50 --window 1m).

โš‘ Root required

guard, block, and unban require root/sudo because they modify iptables rules. Run with sudo or as root.

Guard Flags

Guard daemon configuration flags
Flag Short Default Description
--limit -l 100 Max detections per IP within the window before blocking
--window -w 1m Rolling time window for rate counting
--duration -d 10m How long to keep an IP blocked before auto-unbanning (0 = permanent)
--auth-limit โ€” 10 Max failed auth (401/403) requests before blocking
--notfound-limit โ€” 50 Max 404 responses before blocking (directory brute-force defense)
--audit-log โ€” /var/log/caddy-analyzer-audit.jsonl Path to JSON-lines audit log recording every block/unblock action (timestamp, IP, reason, duration, user). File created with 0600 permissions. Pass empty string to disable. Also available on block and unban subcommands.
--state-file โ€” /var/lib/caddy-analyzer/blocked.json Persist blocked-IP state to a JSON file so bans survive guard restarts. Expired entries are cleaned up on load. Pass empty string to disable.
--never-block โ€” "" Comma-separated list of IPs/CIDRs that should never be blocked (e.g. 10.0.0.0/8,192.168.1.1). Protects trusted gateways and proxies from false-positive bans.
--never-block-file โ€” "" Path to a file containing IPs/CIDRs (one per line, # comments supported) that should never be blocked. Merged with --never-block.
--detect-confidence โ€” 8 Minimum confidence (1-10) for pattern-detection blocking. Detections scoring below this threshold are reported but not blocked. Pass 0 to disable pattern-based blocking entirely (rate/status thresholds still apply).
--subnet-limit โ€” 0 Block a whole /24 (IPv4) or /64 (IPv6) when its combined requests exceed this threshold, even if no single IP trips. Distributed-scan defense. 0 disables.
--rps-anomaly โ€” 0 Alert when current RPS exceeds this factor over the EWMA baseline (e.g. 5 = 5ร— spike). Catches volumetric spikes / DDoS. 0 disables.
--cred-stuffing-limit โ€” 0 Alert when N distinct IPs fail auth (401/403) on the same path within the window. Catches distributed credential stuffing. 0 disables.
--enrich โ€” false Enable threat-intel enrichment via AbuseIPDB. Set ABUSEIPDB_KEY env var. IPs with auth failures and AbuseIPDB score โ‰ฅ --enrich-threshold are pre-blocked.
--enrich-threshold โ€” 70 Minimum AbuseIPDB abuse confidence score to pre-block an IP with auth failures. 0 disables enrichment blocking.
--ua-rotation โ€” 10 Distinct User-Agents from one IP before scanner/rotation heuristic fires.
--trust-forwarded โ€” false Trust X-Forwarded-For / X-Real-IP for client IP (use behind a reverse proxy/CDN).
sudo caddy-analyze guard --limit 50 --window 1m \
  --audit-log /var/log/caddy-analyzer-audit.jsonl \
  --state-file /var/lib/caddy-analyzer/blocked.json \
  --never-block 10.0.0.0/8,192.168.1.1 \
  --never-block-file /etc/caddy-analyzer/allowlist.txt \
  docker://my-caddy

Manual Block & Unban

The block <ip...> and unban <ip...> subcommands manage iptables rules directly. Both accept --audit-log and --state-file (same defaults as guard) to sync manual blocks/unbans with the guard's persisted state โ€” manual blocks survive guard restarts, manual unbans prevent re-blocking on restart. Both commands return non-zero exit code if any IP fails. block is idempotent: blocking an already-blocked IP is a no-op (no duplicate iptables rules).

Block and unban subcommand flags
Flag Short Default Description
--audit-log โ€” /var/log/caddy-analyzer-audit.jsonl JSON-lines audit log path (block/unban actions). Pass empty string to disable.
--state-file โ€” /var/lib/caddy-analyzer/blocked.json Guard state file to sync manual blocks/unbans. Pass empty string to disable.
--all -A false (unban only) Unblock all currently blocked IPs.
--list -l false (unban only) Show currently blocked IPs without removing any.
sudo caddy-analyze block 203.0.113.5 198.51.100.2
sudo caddy-analyze unban --all
sudo caddy-analyze unban --list