Documentation
¶
Overview ¶
============================================================================= NFTBan v1.78 - Validator CLI Helpers ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="validator-cli" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-05" meta:description="CLI output helpers for the validator" meta:inventory.files="internal/validator/cli.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="none" =============================================================================
============================================================================= NFTBan v1.78 - nft JSON Output Parsing ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="validator-nftjson" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-05" meta:description="Parse nft -j list ruleset JSON output" meta:inventory.files="internal/validator/nftjson.go" meta:inventory.binaries="nft" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root" =============================================================================
============================================================================= NFTBan v1.78 - Kernel Truth Validator Types ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="validator-types" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-05" meta:description="Type definitions for kernel state validation" meta:inventory.files="internal/validator/types.go" meta:inventory.binaries="" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="none" =============================================================================
============================================================================= NFTBan v1.78 - Kernel Truth Validator ============================================================================= SPDX-License-Identifier: MPL-2.0 meta:name="validator" meta:type="lib" meta:owner="Antonios Voulvoulis <contact@nftban.com>" meta:created_date="2026-04-05" meta:description="Validates live nftables kernel state against NFTBan requirements" meta:inventory.files="internal/validator/validator.go" meta:inventory.binaries="nft" meta:inventory.env_vars="" meta:inventory.config_files="" meta:inventory.systemd_units="" meta:inventory.network="" meta:inventory.privileges="root"
CRITICAL: This validator is ZERO-SIDE-EFFECT. It MUST NEVER write files, modify nft, or call mutating shell scripts. =============================================================================
Index ¶
- Constants
- Variables
- func CompareChainCounts(pre, post ChainCounts, tolerance int) (bool, string)
- func SetServiceChecker(sc ServiceChecker)
- type AnchorCheck
- type ChainCheck
- type ChainCounts
- type FamilyResult
- type Finding
- type ModuleInfo
- type ModuleStatus
- type NftChain
- type NftCounter
- type NftMetainfo
- type NftObject
- type NftRule
- type NftRuleset
- type NftSet
- type NftSetType
- type NftTable
- type RulesetDocument
- func (d *RulesetDocument) ChainExists(family, table, chain string) bool
- func (d *RulesetDocument) CountChains(family string) int
- func (d *RulesetDocument) CountRulesInChain(family, table, chain string) int
- func (d *RulesetDocument) CountSets(family string) int
- func (d *RulesetDocument) ExtractAnchorsFromChain(family, table, chain string) []string
- func (d *RulesetDocument) GetChains(family, table string) []string
- func (d *RulesetDocument) GetRules(family, table, chain string) []*NftRule
- func (d *RulesetDocument) GetSets(family, table string) []string
- func (d *RulesetDocument) SetExists(family, table, set string) bool
- func (d *RulesetDocument) TableExists(family, name string) bool
- type RuntimeState
- type ServiceChecker
- type ServiceState
- type SetCheck
- type Severity
- type Status
- type SummaryCounts
- type SystemdChecker
- type ValidationResult
Constants ¶
const ( // Table findings CodeTableMissing = "VAL-TABLE-001" CodeTableBothMissing = "VAL-TABLE-002" // Chain findings CodeChainMissing = "VAL-CHAIN-001" CodeHelperChainMissing = "VAL-CHAIN-002" CodeChainCountDrop = "VAL-CHAIN-003" CodeChainEmpty = "VAL-CHAIN-004" // B80-3: chain exists but has no rules // Anchor findings CodeAnchorMissing = "VAL-ANCHOR-001" CodeAnchorOrder = "VAL-ANCHOR-002" CodeAnchorFinal = "VAL-ANCHOR-003" // FINAL GUARD CodeAnchorTruncate = "VAL-ANCHOR-004" // Set findings CodeSetMissing = "VAL-SET-001" // Module findings CodeModuleDegraded = "VAL-MODULE-001" // Service findings (B80-4) CodeServiceDown = "VAL-SERVICE-001" // required service not active // System findings CodeNftFailed = "VAL-SYSTEM-001" CodeNftNoOutput = "VAL-SYSTEM-002" CodeParseError = "VAL-SYSTEM-003" )
Finding codes (stable for automation).
Variables ¶
var GeneratedAllSetsIPv4 = []string{
"blacklist_ipv4",
"blacklist_manual_ipv4",
"http_bot_allow",
"http_bot_ban",
"http_bot_emergency",
"http_bot_grey",
"http_bot_pending",
"http_bot_suspect",
"port_allow_tcp_ipv4",
"port_allow_udp_ipv4",
"tcp_ports_in",
"tcp_ports_out",
"udp_ports_in",
"udp_ports_out",
"whitelist_ipv4",
}
GeneratedAllSetsIPv4 — all known IPv4 set names from canonical schema (including optional module sets).
var GeneratedAllSetsIPv6 = []string{
"blacklist_ipv6",
"blacklist_manual_ipv6",
"http_bot_allow6",
"http_bot_ban6",
"http_bot_emergency6",
"http_bot_grey6",
"http_bot_pending6",
"http_bot_suspect6",
"port_allow_tcp_ipv6",
"port_allow_udp_ipv6",
"tcp_ports_in",
"tcp_ports_out",
"udp_ports_in",
"udp_ports_out",
"whitelist_ipv6",
}
GeneratedAllSetsIPv6 — all known IPv6 set names from canonical schema (including optional module sets).
var GeneratedRequiredBaseChains = []string{
"forward",
"input",
"output",
}
GeneratedRequiredBaseChains from NFTBAN_IPV4_CHAINS keys.
var GeneratedRequiredHelperChains = []string{
"ddos_penalty",
"ddos_prefix",
"ddos_protection",
"ddos_sanity",
"http_bot_guard",
"portscan_detection",
}
GeneratedRequiredHelperChains merges shell NFTBAN_IPV4_HELPER_CHAINS + DDoS fragment sub-chains (ddos_sanity, ddos_penalty, ddos_prefix).
var GeneratedRequiredSetsIPv4 = []string{
"blacklist_ipv4",
"blacklist_manual_ipv4",
"tcp_ports_in",
"udp_ports_in",
"whitelist_ipv4",
}
GeneratedRequiredSetsIPv4 — core sets required for base protection.
var GeneratedRequiredSetsIPv6 = []string{
"blacklist_ipv6",
"blacklist_manual_ipv6",
"tcp_ports_in",
"udp_ports_in",
"whitelist_ipv6",
}
GeneratedRequiredSetsIPv6 — core sets required for base protection.
var RequiredAnchors = []string{
"ANCHOR_HYGIENE",
"ANCHOR_TRUSTED",
"ANCHOR_BAN",
"ANCHOR_ESTABLISHED",
"ANCHOR_DETECT",
"ANCHOR_SERVICE",
"ANCHOR_FINAL",
}
Required anchors in strict order. AUTHORITY NOTE (B80-5): Anchors are a validator-defined invariant, NOT derived from the shell schema. They represent the required rule-comment sequence in the input chain. The canonical authority for chains/sets is nft_schema.sh via schema_generated.go. The canonical authority for anchor ordering is this list, maintained manually in this file.
var RequiredBaseChains = GeneratedRequiredBaseChains
Required base chains per family. B80-5/6: sourced from schema_generated.go (canonical: cli/lib/nftban/lib/nft_schema.sh).
var RequiredHelperChains = GeneratedRequiredHelperChains
Required helper chains per family (6 total: 3 shell-declared + 3 DDoS fragment sub-chains). B80-5/6: sourced from schema_generated.go (includes DDoS fragment sub-chains).
var RequiredSetsIPv4 = GeneratedRequiredSetsIPv4
Required sets for IPv4. B80-5/6: sourced from schema_generated.go (core required sets only).
var RequiredSetsIPv6 = GeneratedRequiredSetsIPv6
Required sets for IPv6. B80-5/6: sourced from schema_generated.go (core required sets only).
Functions ¶
func CompareChainCounts ¶
func CompareChainCounts(pre, post ChainCounts, tolerance int) (bool, string)
CompareChainCounts compares pre and post chain counts for rebuild safety. Returns (degraded bool, message string).
func SetServiceChecker ¶ added in v1.80.0
func SetServiceChecker(sc ServiceChecker)
SetServiceChecker replaces the service checker (for testing only).
Types ¶
type AnchorCheck ¶
type AnchorCheck struct {
RequiredCount int `json:"required_count"`
FoundCount int `json:"found_count"`
Ordered bool `json:"ordered"`
AnchorsFound []string `json:"anchors_found"`
Missing []string `json:"missing"`
OrderExpected []string `json:"order_expected"`
OrderActual []string `json:"order_actual"`
FinalPresent bool `json:"final_present"` // FINAL GUARD invariant
}
AnchorCheck holds anchor validation results.
type ChainCheck ¶
type ChainCheck struct {
Required []string `json:"required"`
Found []string `json:"found"`
Missing []string `json:"missing"`
AllFound bool `json:"all_found"`
}
ChainCheck holds chain validation results.
type ChainCounts ¶
type ChainCounts struct {
IPv4Total int `json:"ipv4_total"`
IPv4Base int `json:"ipv4_base"`
IPv4Helper int `json:"ipv4_helper"`
IPv6Total int `json:"ipv6_total"`
IPv6Base int `json:"ipv6_base"`
IPv6Helper int `json:"ipv6_helper"`
TotalChains int `json:"total_chains"`
}
ChainCounts for relative comparison (rebuild safety).
type FamilyResult ¶
type FamilyResult struct {
Family string `json:"family"` // "ip" or "ip6"
Status Status `json:"status"`
TablePresent bool `json:"table_present"`
ChainCount int `json:"chain_count"`
SetCount int `json:"set_count"`
BaseChains ChainCheck `json:"base_chains"`
HelperChains ChainCheck `json:"helper_chains"`
Anchors AnchorCheck `json:"anchors"`
Sets SetCheck `json:"sets"`
}
FamilyResult holds validation results for a single address family (ip/ip6).
type Finding ¶
type Finding struct {
Code string `json:"code"`
Severity Severity `json:"severity"`
Component string `json:"component"`
Family string `json:"family,omitempty"`
Message string `json:"message"`
Remediation string `json:"remediation,omitempty"`
}
Finding represents a single validation finding.
type ModuleInfo ¶
type ModuleInfo struct {
Enabled bool `json:"enabled"`
KernelPresent bool `json:"kernel_present"`
Details string `json:"details,omitempty"`
}
ModuleInfo holds information about a single module.
type ModuleStatus ¶
type ModuleStatus struct {
DDoS ModuleInfo `json:"ddos"`
Portscan ModuleInfo `json:"portscan"`
Blacklist ModuleInfo `json:"blacklist"`
Whitelist ModuleInfo `json:"whitelist"`
ServiceAdmission ModuleInfo `json:"service_admission"`
}
ModuleStatus holds runtime truth about protection modules.
type NftChain ¶
type NftChain struct {
Family string `json:"family"`
Table string `json:"table"`
Name string `json:"name"`
Type string `json:"type,omitempty"`
Hook string `json:"hook,omitempty"`
Priority int `json:"prio,omitempty"`
Policy string `json:"policy,omitempty"`
Handle int `json:"handle,omitempty"`
}
NftChain represents an nftables chain.
type NftCounter ¶
type NftCounter struct {
Family string `json:"family"`
Table string `json:"table"`
Name string `json:"name"`
Handle int `json:"handle,omitempty"`
Packets int64 `json:"packets,omitempty"`
Bytes int64 `json:"bytes,omitempty"`
}
NftCounter represents a named counter.
type NftMetainfo ¶
type NftMetainfo struct {
Version string `json:"version"`
ReleaseName string `json:"release_name"`
JsonSchemaVersion int `json:"json_schema_version"`
}
NftMetainfo holds nft version info.
type NftObject ¶
type NftObject struct {
Metainfo *NftMetainfo `json:"metainfo,omitempty"`
Table *NftTable `json:"table,omitempty"`
Chain *NftChain `json:"chain,omitempty"`
Set *NftSet `json:"set,omitempty"`
Rule *NftRule `json:"rule,omitempty"`
Counter *NftCounter `json:"counter,omitempty"`
}
NftObject is a wrapper for any nft object (table, chain, set, rule, etc.). Only one field will be populated per object.
type NftRule ¶
type NftRule struct {
Family string `json:"family"`
Table string `json:"table"`
Chain string `json:"chain"`
Handle int `json:"handle,omitempty"`
Comment string `json:"comment,omitempty"`
Expr []interface{} `json:"expr,omitempty"`
}
NftRule represents an nftables rule.
type NftRuleset ¶
type NftRuleset struct {
Nftables []NftObject `json:"nftables"`
}
NftRuleset represents the top-level nft -j list ruleset output. The JSON structure is: { "nftables": [ {...}, {...}, ... ] }
func LoadRulesetJSON ¶
func LoadRulesetJSON(ctx context.Context) (*NftRuleset, error)
LoadRulesetJSON executes nft -j list ruleset and parses the output. This is a PURE function - it only reads kernel state, never modifies.
type NftSet ¶
type NftSet struct {
Family string `json:"family"`
Table string `json:"table"`
Name string `json:"name"`
Type NftSetType `json:"type,omitempty"`
Flags []string `json:"flags,omitempty"`
Timeout int `json:"timeout,omitempty"`
Handle int `json:"handle,omitempty"`
}
NftSet represents an nftables set.
type NftSetType ¶
type NftSetType struct {
Types []string
}
NftSetType handles nft set type which can be string or []string (for concatenations).
func (*NftSetType) UnmarshalJSON ¶
func (t *NftSetType) UnmarshalJSON(data []byte) error
UnmarshalJSON handles both string and []string for nft set type field.
type NftTable ¶
type NftTable struct {
Family string `json:"family"`
Name string `json:"name"`
Handle int `json:"handle,omitempty"`
}
NftTable represents an nftables table.
type RulesetDocument ¶
type RulesetDocument struct {
// contains filtered or unexported fields
}
RulesetDocument provides structured access to the parsed ruleset.
func ParseRuleset ¶
func ParseRuleset(raw *NftRuleset) *RulesetDocument
ParseRuleset converts raw NftRuleset into a structured document.
func (*RulesetDocument) ChainExists ¶
func (d *RulesetDocument) ChainExists(family, table, chain string) bool
ChainExists checks if a chain exists.
func (*RulesetDocument) CountChains ¶
func (d *RulesetDocument) CountChains(family string) int
CountChains returns total chain count for a family's nftban table.
func (*RulesetDocument) CountRulesInChain ¶ added in v1.80.0
func (d *RulesetDocument) CountRulesInChain(family, table, chain string) int
CountRulesInChain returns the number of rules in a specific chain. Returns 0 if the chain has no rules or does not exist.
func (*RulesetDocument) CountSets ¶
func (d *RulesetDocument) CountSets(family string) int
CountSets returns total set count for a family's nftban table.
func (*RulesetDocument) ExtractAnchorsFromChain ¶
func (d *RulesetDocument) ExtractAnchorsFromChain(family, table, chain string) []string
ExtractAnchorsFromChain extracts anchor names from rule comments in a chain. Anchors are identified by comments containing "NFTBAN_ANCHOR:ANCHOR_*".
func (*RulesetDocument) GetChains ¶
func (d *RulesetDocument) GetChains(family, table string) []string
GetChains returns all chain names for a table.
func (*RulesetDocument) GetRules ¶
func (d *RulesetDocument) GetRules(family, table, chain string) []*NftRule
GetRules returns all rules for a chain.
func (*RulesetDocument) GetSets ¶
func (d *RulesetDocument) GetSets(family, table string) []string
GetSets returns all set names for a table.
func (*RulesetDocument) SetExists ¶
func (d *RulesetDocument) SetExists(family, table, set string) bool
SetExists checks if a set exists.
func (*RulesetDocument) TableExists ¶
func (d *RulesetDocument) TableExists(family, name string) bool
TableExists checks if a table exists.
type RuntimeState ¶ added in v1.80.0
type RuntimeState string
RuntimeState represents a three-state service status. Aligns with the v1.82 health model direction (RUNNING / STOPPED / ERROR).
const ( RuntimeRunning RuntimeState = "RUNNING" RuntimeStopped RuntimeState = "STOPPED" RuntimeError RuntimeState = "ERROR" // systemctl query itself failed )
type ServiceChecker ¶ added in v1.80.0
type ServiceChecker interface {
// CheckUnit returns (RuntimeState, detail string).
// RuntimeState: RUNNING / STOPPED / ERROR.
// detail: the raw systemctl output (e.g. "active", "inactive", "failed").
CheckUnit(unit string) (RuntimeState, string)
}
ServiceChecker abstracts service-state queries so unit tests can mock systemd without requiring a real init system. The default implementation calls `systemctl is-active <unit>`.
type ServiceState ¶ added in v1.80.0
type ServiceState struct {
Nftband RuntimeState `json:"nftband"`
NftbandDetail string `json:"nftband_detail,omitempty"`
}
ServiceState holds the live status of required system services. B80-4: the validator MUST check these before declaring PROTECTED. A system with correct kernel structure but a dead daemon is not protected.
type SetCheck ¶
type SetCheck struct {
Required []string `json:"required"`
Found []string `json:"found"`
Missing []string `json:"missing"`
AllFound bool `json:"all_found"`
}
SetCheck holds set validation results.
type SummaryCounts ¶
type SummaryCounts struct {
TotalFindings int `json:"total_findings"`
CriticalFindings int `json:"critical_findings"`
ErrorFindings int `json:"error_findings"`
WarnFindings int `json:"warn_findings"`
CheckedFamilies int `json:"checked_families"`
ProtectedFams int `json:"protected_families"`
DegradedFams int `json:"degraded_families"`
}
SummaryCounts provides quick stats.
type SystemdChecker ¶ added in v1.80.0
type SystemdChecker struct{}
SystemdChecker is the default production ServiceChecker.
func (SystemdChecker) CheckUnit ¶ added in v1.80.0
func (SystemdChecker) CheckUnit(unit string) (RuntimeState, string)
CheckUnit queries systemd for the unit's active state. This is a read-only query — zero side effects.
type ValidationResult ¶
type ValidationResult struct {
Status Status `json:"status"`
Timestamp time.Time `json:"timestamp"`
Families []FamilyResult `json:"families"`
Findings []Finding `json:"findings"`
Summary SummaryCounts `json:"summary"`
ModuleTruth ModuleStatus `json:"module_truth"`
ChainCount ChainCounts `json:"chain_counts"`
ServiceState ServiceState `json:"service_state"` // B80-4
}
ValidationResult is the complete output of kernel validation.
func RunValidation ¶
func RunValidation(ctx context.Context) (*ValidationResult, error)
RunValidation is a convenience function that runs validation and returns the result. Returns (result, nil) even if status is DOWN - that's a valid result.
func ValidateKernel ¶
func ValidateKernel(ctx context.Context) (*ValidationResult, error)
ValidateKernel performs complete kernel state validation. This is the main entrypoint for the validator.
CRITICAL: This function is PURE - it only reads, never modifies.
func (*ValidationResult) ExitCode ¶
func (r *ValidationResult) ExitCode() int
ExitCode returns the appropriate exit code for the status. 0 = PROTECTED, 1 = DEGRADED, 2 = DOWN
func (*ValidationResult) PrintSummary ¶
func (r *ValidationResult) PrintSummary()
PrintSummary prints a human-readable summary to stdout.
func (*ValidationResult) StatusString ¶
func (r *ValidationResult) StatusString() string
StatusString returns a human-readable status with emoji.
func (*ValidationResult) ToJSON ¶
func (r *ValidationResult) ToJSON() ([]byte, error)
ToJSON converts the validation result to JSON.