-
Notifications
You must be signed in to change notification settings - Fork 0
CLI Commands Reference
Type: CLI Command (comprehensive reference) Scope: All operator-facing commands with trust levels and truth boundaries Since: v1.80.x Terminology: Glossary & Vocabulary
This page defines what each CLI command does, where its data comes from, and what it is allowed to claim. The CLI is a presentation layer for kernel-derived truth and operational actions — for truth-critical commands (status, health, validate), it renders the Go validator's output and must not compute health independently.
| Category | Examples | Scope |
|---|---|---|
| Truth commands |
status, health, validate
|
Read and present kernel-derived state |
| Module inspection |
ddos status, botguard status, login status
|
Per-module state display |
| Action commands |
ban, unban, firewall rebuild
|
Write to kernel sets or reload schema |
| Data pipeline |
feeds sync, geoban sync, geoip update
|
External data management |
| Infrastructure |
config show, watchdog status, services
|
System and service information |
For the health derivation model, see Health Model. For term definitions, see Glossary. For module-specific behavior, see individual module pages. For what the validator can and cannot observe, see Known Limitations.
Every command is classified by trust level based on its data source:
| Trust Level | Data Source | Meaning |
|---|---|---|
| KERNEL-BACKED | Kernel-derived via Go validator (nftban-validate --json) |
Derived from nftables kernel state. Authoritative for health interpretation. |
| DERIVED | Computed from kernel + config + daemon state | Accurate but one step removed from kernel. |
| CONFIG-ONLY | Config files (/etc/nftban/conf.d/) |
Operator intent. Does NOT reflect runtime state. |
| PRESENTATION | Formatting, UX display, orchestration | No truth claim. Informational only. |
Rule: A command at a lower trust level must never claim truth that belongs to a higher trust level. A CONFIG-ONLY command must not say "module is ENFORCING" — only KERNEL-BACKED commands can make that claim.
Override prohibition: A DERIVED or CONFIG-ONLY command must not override or contradict KERNEL-BACKED truth under any condition. If the validator says DEGRADED, no other command may display PROTECTED.
CLI output must match nftban-validate --json for all truth fields.
Any mismatch between CLI text and validator JSON is a bug (INV-CONS-001).
| CLI shows | Must match validator field |
|---|---|
| Overall protection state | .status |
| Module config state | .modules.{mod}.config |
| Module structural state | .modules.{mod}.structural |
| Module runtime state | .modules.{mod}.runtime |
| Module effective state | .modules.{mod}.effective |
| Findings | .findings[] |
| Consistency | .consistency.kernel_vs_validator |
Trust Level: KERNEL-BACKED (protection state from Go validator)
- DERIVED (service details, timer schedule)
- PRESENTATION (formatting, banner)
What it does: Displays overall system status including protection state, services, modules, timers, and operational summary.
Version-sensitive behavior:
| Change | Version | PR | Type |
|---|---|---|---|
| Validator is sole authority for protection state — shell no longer overrides PROTECTED→DEGRADED independently | v1.83.0 | #389 | Safety/truth-boundary |
| Validator JSON cached in-process — single binary call serves status + banner + render | v1.83.0 | #393 | Performance |
All systemctl is-active queries batched into single call (~35→1) |
v1.83.0 | #394 | Performance |
| Timer liveness checked by Go validator (VAL-TIMER-001/002) — shell timer count check removed | v1.83.0 | #388 | Safety/truth-boundary |
| Legacy fallback emits deprecation warning when Go binary missing | v1.83.0 | #391 | Safety |
Truth mapping:
| Output field | Source | Trust Level |
|---|---|---|
| Protection state (PROTECTED/DEGRADED/DOWN) | Go validator .status (sole authority since v1.83.0, PR #389) |
KERNEL-BACKED |
| Daemon state | Primary: Go validator .service_state.nftband. Secondary: batch systemctl query for UX detail (v1.83.0, PR #394). |
KERNEL-BACKED |
| Timer status + schedule |
systemctl show per timer (UX detail only — liveness checked by validator since v1.83.0, PR #388) |
DERIVED |
| Module presence (DDoS, Portscan, BotGuard) | Go validator .modules.* via cached JSON (v1.83.0, PR #393) |
KERNEL-BACKED |
| Config divergence hint | Go validator .findings[] (VAL-CONS-001) |
KERNEL-BACKED |
| Rule count |
nft -a list table (independent query) |
DERIVED |
| Feature status (GUI, Pro, metrics) | Batch systemctl (v1.83.0, PR #394) | PRESENTATION |
What it MUST claim:
- Protection state exactly as the validator reports it
- DEGRADED with finding-based reason code when validator says degraded
What it MUST NOT claim:
- PROTECTED when validator says DEGRADED or DOWN
- Module-specific enforcement from shared counters
- "All systems healthy" or "No attacks detected"
Incorrect output example:
Protection: PROTECTED
DDoS: ENABLED (42 threats blocked) ← wrong: "threats blocked" is interpretation
LoginMon: ACTIVE (protecting SSH) ← wrong: "ACTIVE" banned, "protecting" overclaim
Correct output example:
Protection: PROTECTED
DDoS: ENABLED, Present, Enforcing (syn_rate: 927 packets)
LoginMon: Enabled, Running, Idle (0 events/1h)
Exit codes: 0 = PROTECTED or IDLE, 1 = DEGRADED, 2 = DOWN
Trust Level: KERNEL-BACKED (reads Go validator directly)
What it does: Displays the 4-axis health truth table per module. This is the primary operator health surface since v1.83.
Version-sensitive behavior:
| Change | Version | PR | Type |
|---|---|---|---|
Default nftban health changed from 51-check shell scan to Go-backed 4-axis truth table |
v1.83.0 | #390 | Semantic |
Old 51-check scan moved to nftban health diagnostics
|
v1.83.0 | #390 | Semantic |
Argument leak fixed — --json no longer corrupts --auto-heal or --quiet forwarding |
v1.83.0 | #392 | Safety |
| Fallback to diagnostics when Go binary missing emits deprecation warning | v1.83.0 | #391 | Safety |
| Schema version guard warns if validator binary version mismatches expected | v1.83.0 | #391 | Safety |
Subcommands:
| Subcommand | What it does | Trust Level |
|---|---|---|
nftban health (default) |
4-axis truth table from Go validator | KERNEL-BACKED |
nftban health truth |
Explicit alias for default truth view | KERNEL-BACKED |
nftban health --json |
Canonical JSON output (frozen schema subset) | KERNEL-BACKED |
nftban health json |
Alias for --json (same output) |
KERNEL-BACKED |
nftban health diagnostics |
51 environment checks (shell) | DERIVED |
nftban health diagnostics --auto-heal |
Environment checks + auto-fix | DERIVED + side effects |
nftban health summary |
One-line summary | DERIVED |
Canonical forms: nftban health (text truth) and nftban health --json
(JSON truth). truth and json are convenience aliases — they produce
identical output to the canonical forms.
Truth mapping (default/truth subcommand):
| Output field | Source | Trust Level |
|---|---|---|
| Overall state | Go validator .status
|
KERNEL-BACKED |
| Daemon state | Go validator .service_state.nftband
|
KERNEL-BACKED |
| Consistency | Go validator .consistency
|
KERNEL-BACKED |
| Per-module config/structural/runtime/effective | Go validator .modules.*
|
KERNEL-BACKED |
| Blacklist sub-states | Go validator .modules.blacklist.*
|
KERNEL-BACKED |
| Findings | Go validator .findings[]
|
KERNEL-BACKED |
What it MUST NOT do:
- Compute health independently (it reads validator output, never derives)
- Soften or reinterpret a DEGRADED/DOWN verdict
- Show "OK" or "healthy" in health context
Diagnostics vs truth boundary:
-
nftban health= truth (Go validator, read-only, no side effects) -
nftban health diagnostics= environment audit (shell, checks permissions/binaries/integrations) - These are distinct responsibilities. Diagnostics cannot override truth.
Trust Level: KERNEL-BACKED (this IS the validator)
What it does: Reads kernel state via nft -j list ruleset, evaluates
4-axis health per module, checks consistency, and emits findings.
Version-sensitive behavior:
| Change | Version | PR | Type |
|---|---|---|---|
| Timer liveness check added (VAL-TIMER-001 if zero timers, VAL-TIMER-002 if critical timers missing) | v1.83.0 | #388 | Semantic |
| Schema version bumped to 1.83.0 | v1.83.0 | #388 | Schema |
Usage:
| Invocation | Output |
|---|---|
nftban-validate |
Human-readable summary |
nftban-validate --json |
Frozen JSON schema (M81-6) |
This is the single source of truth for derived health state. All other commands that report health must read from this binary's output. Since v1.83.0 (PR #389), no shell command may override or contradict the validator's verdict.
JSON schema version: 1.83.0 (frozen per M81-6)
Exit codes: 0 = PROTECTED or IDLE, 1 = DEGRADED, 2 = DOWN
Finding codes added in v1.83.0:
| Code | Severity | Meaning |
|---|---|---|
| VAL-TIMER-001 | warn | Zero nftban timers active |
| VAL-TIMER-002 | error | Critical timers missing (maintenance, watchdog) |
Trust Level: KERNEL-BACKED (delegates to Go validator via shell shim)
What it does: Shell wrapper that calls validate_structure() which
delegates to the Go validator binary.
Truth mapping:
| Output field | Source | Trust Level |
|---|---|---|
| Structural validation result | Go validator | KERNEL-BACKED |
| Finding codes | Go validator findings | KERNEL-BACKED |
Trust Level: KERNEL-BACKED + CONFIG-ONLY
| Output field | Source | Trust Level |
|---|---|---|
| ENABLED/DISABLED | Config file | CONFIG-ONLY |
| Chain presence | nft list chain |
KERNEL-BACKED |
| Counter values | nft list counter |
KERNEL-BACKED |
Must NOT claim:
- "X attacks blocked" (counter value is packet-level evidence, not attack classification)
- Interpretation of intent beyond kernel evidence
Trust Level: KERNEL-BACKED + DERIVED
| Output field | Source | Trust Level |
|---|---|---|
| ENABLED/DISABLED | Config file | CONFIG-ONLY |
| Set element counts |
nft list set per set |
KERNEL-BACKED |
| Chain presence | nft list chain |
KERNEL-BACKED |
| Daemon module registration | Journal query | DERIVED |
Must NOT claim: "Bots blocked" without set population evidence. Empty sets = IDLE, not broken.
Trust Level: KERNEL-BACKED (structure) + DERIVED (detection history)
| Output field | Source | Trust Level |
|---|---|---|
| ENABLED/DISABLED | Config file | CONFIG-ONLY |
| Chain presence | nft list chain |
KERNEL-BACKED |
| Recent detections | Kernel log / portscan log | DERIVED |
Must NOT claim: "Port scans blocked" — no dedicated counter exists. Chain logs traffic; detection and banning are userspace operations.
Trust Level: DERIVED (daemon journal) + CONFIG-ONLY
| Output field | Source | Trust Level |
|---|---|---|
| ENABLED/DISABLED | Config file | CONFIG-ONLY |
| Source bindings | Daemon journal | DERIVED |
| Event counts | Daemon journal | DERIVED |
| Ban count | Daemon journal | DERIVED |
Must NOT claim: Enforcement from input_blacklist_manual_drop counter
alone — it is shared with operator bans and portscan bans.
Trust Level: KERNEL-BACKED (writes to kernel set)
What it does: Adds IP to blacklist_manual_ipv4/ipv6 with timeout.
| Action | Evidence |
|---|---|
| IP added |
nft list set ip nftban blacklist_manual_ipv4 shows entry |
| IP enforced |
input_blacklist_manual_drop counter increments on matching traffic |
Trust Level: KERNEL-BACKED (removes from kernel set)
Trust Level: CONFIG-ONLY + DERIVED
| Output field | Source | Trust Level |
|---|---|---|
| Configured feeds | conf.d/feeds/*.conf |
CONFIG-ONLY |
| Sync status | Daemon journal | DERIVED |
| Loaded ranges | Sync log output | DERIVED |
Must NOT claim: "Feeds are blocking threats" — shared counter, no attribution.
Trust Level: CONFIG-ONLY + DERIVED
| Output field | Source | Trust Level |
|---|---|---|
| ENABLED/DISABLED | Config file | CONFIG-ONLY |
| GeoIP database status | File existence + mtime | DERIVED |
| Countries configured | Config file | CONFIG-ONLY |
Must NOT claim: "Countries blocked" — shared counter with feeds.
Trust Level: KERNEL-BACKED (generates schema, validates, loads atomically)
What it does: Regenerates the full nftables schema and loads it atomically.
Invariant: If validation fails, the existing ruleset is preserved. No partial state.
Trust Level: KERNEL-BACKED
What it does: Checks if a specific IP or port is allowed/blocked by tracing it through the kernel ruleset.
Trust Level: KERNEL-BACKED
What it does: Lists banned IPs from kernel sets.
Trust Level: DERIVED
What it does: Shows system pressure monitoring state.
Trust Level: CONFIG-ONLY
What it does: Shows current configuration values.
Must explicitly state: "Shows configured values, not runtime state."
Command semantics are anchored to the v1.80.x design baseline, v1.81 vocabulary, and v1.82 truth model. When command behavior changed after this baseline, the change is scoped to an exact version.
Rule: Use exact version (e.g., v1.83.0) when behavior changed. Use v1.80.x when describing behavior stable across the series.
| Command | Change | PR | Type |
|---|---|---|---|
nftban status |
Validator is sole authority — shell truth override removed | #389 | Truth-boundary |
nftban status |
Validator JSON cached in-process (1 binary call, not 3) | #393 | Performance |
nftban status |
systemctl calls batched (~35→1) | #394 | Performance |
nftban health |
Default changed from 51-check scan to Go-backed truth table | #390 | Semantic |
nftban health diagnostics |
New subcommand — old 51-check scan relocated here | #390 | Semantic |
nftban health --auto-heal / --quiet
|
Argument leak fixed (F1-F3) | #392 | Safety |
nftban-validate |
Timer liveness findings (VAL-TIMER-001/002) | #388 | Semantic |
| All truth commands | Fallback warning when Go binary missing | #391 | Safety |
| All truth commands | Schema version guard warns on binary/CLI version mismatch | #391 | Safety |
- Module command semantics (
ddos status,botguard status, etc.) — unchanged - Action commands (
ban,unban,firewall rebuild) — unchanged - Data pipeline commands (
feeds sync,geoban sync) — unchanged - Config commands (
config show) — unchanged - Trust level classification model — unchanged (defined in v1.82)
- CLI ↔ validator alignment rule (INV-CONS-001) — unchanged (defined in v1.80.x)
These patterns MUST NOT appear in any command output:
| Pattern | Why forbidden | Reference |
|---|---|---|
| "healthy" | Banned term | Glossary §Forbidden Terms |
| "working" | Banned term | Glossary §Forbidden Terms |
| "OK" (health context) | Banned term | Glossary §Forbidden Terms |
| "active" (alone, as state) | Banned term — ambiguous | Glossary §Forbidden Terms |
| "N threats/attacks blocked" | Counter interpretation | Glossary §Forbidden Interpretations |
| "protecting your server" | PRESENT does not equal ENFORCING | Glossary §Forbidden Interpretations |
| "all clear" / "no attacks" | Zero = NEUTRAL, not safety proof | Glossary §Counter Rules |
| PROTECTED without validator | Structure alone does not prove protection | Health Model §Overall Status |
| Module ENFORCING from shared counter | Attribution requires specific evidence | Module pages §Limitations |
# Verify CLI agrees with validator (INV-CONS-001)
nftban-validate --json | jq '.status'
nftban health truth
# Both must show the same protection state
# Verify no banned terms in CLI output
nftban status 2>&1 | grep -iE "healthy|working|all clear|no attacks"
# Expected: no matches
# Verify trust boundaries
nftban config show
# Must say "configured values" — never claim runtime truth
# Verify module states match validator
nftban-validate --json | jq '.modules.ddos'
nftban ddos status
# Both must agree on ENABLED/DISABLED + PRESENT/MISSING- CLI cannot prove enforcement without kernel evidence. If the validator reports IDLE, the CLI must report IDLE — even if config says ENABLED.
-
Shared counter attribution is not possible from CLI.
input_blacklist_dropcannot be split between feeds and geoban.input_blacklist_manual_dropcannot be split between LoginMon, portscan, and operator bans. - Portscan effective state is reported as IDLE by the validator due to lack of observable kernel evidence. The CLI cannot claim portscan is ENFORCING because no kernel counter proves it.
- LoginMon effective state is reported as IDLE by the validator because journal evidence is outside its current evaluation scope. The CLI shows event counts from journal queries, but the validator's effective field reports IDLE. This is a validator limitation, not a statement about actual module activity.
- Legacy fallback is deprecated (since v1.83.0, PR #391). If the Go validator binary is missing, the CLI falls back to shell-based detection with a visible deprecation warning. This fallback is scheduled for removal in v1.84.
- Schema version guard (since v1.83.0, PR #391). The CLI warns if the validator binary's schema version does not match the expected version. This prevents silent breakage when the binary is from a different release.
NFTBan Wiki
Getting Started
Architecture
Modules
- BotGuard (HTTP L7)
- DDoS Protection (L3/L4)
- Portscan Detection
- Login Monitoring
- Blacklist & Threat Intelligence
- Suricata IDS Integration
- DNS Tunnel Suspicion
Operator Reference
- CLI Commands Reference
- Configuration Reference
- Systemd Units & Timers
- Optimization & Tuning
- Security Operations Guide
- GeoIP Database Guide
- FHS Compliance
- Troubleshooting: Smoke & Selftest
Verification & Trust
- Glossary & Vocabulary
- Known Limitations
- Metrics & Evidence Model
- Binary Verification (SLSA)
- Security Architecture
Reference
Legal