botguard

package
v1.123.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2026 License: MPL-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ModuleName    = "botguard"
	ModuleVersion = "1.0.0"
)

Variables

This section is empty.

Functions

func DefaultGroupConfigs added in v1.79.0

func DefaultGroupConfigs() map[RuleGroup]GroupConfig

DefaultGroupConfigs returns the default configuration for all groups. These can be overridden by config.

func Descriptor

func Descriptor() module.Descriptor

Descriptor returns the module descriptor for registration.

Types

type Action added in v1.79.0

type Action string

Action defines what happens when a rule matches.

const (
	// ActionScore adds score points (default behavior).
	ActionScore Action = "score"

	// ActionBan immediately bans the IP.
	ActionBan Action = "ban"

	// ActionGrey immediately moves IP to grey state.
	ActionGrey Action = "grey"

	// ActionAllow marks IP as allowed (e.g., verified crawler).
	ActionAllow Action = "allow"

	// ActionLog logs the match without affecting score.
	ActionLog Action = "log"

	// ActionExempt exempts the IP from further scoring for this request.
	ActionExempt Action = "exempt"
)

type BatchSignal

type BatchSignal struct {
	IP      string   `json:"ip"`      // IP address
	Score   int      `json:"score"`   // Behavioral score (0-100)
	Reasons []string `json:"reasons"` // Why flagged (e.g., "404_flood", "wp_probe")
	Action  string   `json:"action"`  // "ban", "grey", "allow_demote", "allow_extend"
	TS      int64    `json:"ts"`      // Unix timestamp
}

BatchSignal represents a signal from the shell botscan (Clock 3). Written as JSONL to /var/lib/nftban/botguard/batch_signals.jsonl

type BotConfig

type BotConfig struct {
	Name       string   // e.g. "GOOGLEBOT"
	Domains    []string // Suffix match domains (e.g. ["googlebot.com", "google.com"])
	VerifyMode string   // Verification method: "fcrdns"
	MaxConn    int      // Max concurrent connections allowed
	MaxRate    string   // nft rate string (e.g. "80/second")
	Burst      int      // nft burst value
}

BotConfig describes an allowed or known crawler identity. Loaded from allowed_crawlers.conf (pipe-delimited).

type BotGuardStatusExtra added in v1.110.0

type BotGuardStatusExtra struct {
	LoopInterval          string `json:"loop_interval"`
	PressureMode          bool   `json:"pressure_mode"`
	TrackedIPs            int64  `json:"tracked_ips"`
	TotalTicks            int64  `json:"total_ticks"`
	SuspectsFound         int64  `json:"suspects_found"`
	Classified            int64  `json:"classified"`
	AllowCount            int64  `json:"allow_count"`
	GreyCount             int64  `json:"grey_count"`
	BanCount              int64  `json:"ban_count"`
	EmergencyCount        int64  `json:"emergency_count"`
	LastTickDuration      string `json:"last_tick_duration"`
	VerifyEnqueued        int64  `json:"verify_enqueued"`
	VerifyCompleted       int64  `json:"verify_completed"`
	VerifyVerified        int64  `json:"verify_verified"`
	VerifyFailed          int64  `json:"verify_failed"`
	BatchSignalsProcessed int64  `json:"batch_signals_processed"`
}

BotGuardStatusExtra is the typed status payload for the BotGuard module's Status().Extra field. Field names map to legacy map[string]any keys via JSON tags byte-for-byte; R-12 introduces type-safety without an API change.

func (BotGuardStatusExtra) ToExtraInfo added in v1.110.0

func (e BotGuardStatusExtra) ToExtraInfo() module.ExtraInfo

ToExtraInfo serializes the typed struct into the module.ExtraInfo map[string]any contract expected by module.Status.Extra.

type Classifier

type Classifier struct {
	// contains filtered or unexported fields
}

Classifier performs bot classification using FCrDNS verification and allowed/denied crawler configuration.

func NewClassifier

func NewClassifier(cfg *Config, verifier *FCrDNSVerifier) (*Classifier, error)

NewClassifier creates a classifier with loaded crawler configs.

func (*Classifier) AllowedBots

func (c *Classifier) AllowedBots() []BotConfig

AllowedBots returns a copy of the allowed bot list.

func (*Classifier) Classify

func (c *Classifier) Classify(r *IPRecord, cfg *Config) ClassifyResult

Classify determines the classification for a suspect IP record. Returns a ClassifyResult with the target state and reason.

func (*Classifier) ProcessVerification

func (c *Classifier) ProcessVerification(result VerifyResult) ClassifyResult

ProcessVerification processes a completed FCrDNS result and returns the classification decision for the verified IP.

func (*Classifier) ReloadConfigs

func (c *Classifier) ReloadConfigs() error

ReloadConfigs reloads allowed and denied crawler configs from disk.

type ClassifyResult

type ClassifyResult struct {
	State   IPState      // Target state (allow, ban, grey, pending)
	Reason  string       // Why this decision was made
	BotName string       // Identified bot name (if any)
	Verify  VerifyStatus // FCrDNS verification result
}

ClassifyResult is the decision returned by the Classifier.

type Config

type Config struct {
	// Module control
	Enabled bool

	// Classification loop intervals
	LoopInterval         time.Duration // Normal: 60s
	LoopPressureInterval time.Duration // Under pressure: 40s

	// Hysteresis thresholds (per IP connection count)
	TripConn      int // Start analyzing (default 200)
	ClearConn     int // Stop analyzing (default 150)
	EmergencyConn int // Immediate block (default 500)

	// Kernel suspect marking config (informational — actual values in nft rules)
	SuspectRate    string        // e.g. "30/second"
	SuspectBurst   int           // e.g. 60
	SuspectTimeout time.Duration // e.g. 5m

	// TTLs for classification sets
	AllowTTL     time.Duration // 24h initial
	BanTTL       time.Duration // 96h
	GreyTTL      time.Duration // 30m
	EmergencyTTL time.Duration // 30m
	PendingTTL   time.Duration // 60s

	// Auto-tuning
	AutoTune bool

	// Batch integration
	BatchSignalFile string
	BatchInterval   time.Duration

	// FCrDNS verification
	VerifyWorkers   int           // Max concurrent DNS workers (default 8)
	VerifyRateLimit int           // Max new lookups per second (default 10)
	VerifyTimeout   time.Duration // Timeout per DNS lookup (default 3s)
	VerifyCacheTTL  time.Duration // Positive cache TTL (default 24h)
	VerifyNegTTL    time.Duration // Negative cache TTL (default 1h)

	// Crawler config files
	AllowedCrawlersFile string
	DeniedCrawlersFile  string

	// Logging
	LogLevel     string
	LogDecisions bool
}

Config holds all bot guard configuration.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns production-safe defaults.

func LoadConfig

func LoadConfig(path string) (*Config, error)

LoadConfig reads configuration with the standard NFTBan override chain:

  1. main.conf — package defaults
  2. main.conf.local — user overrides (survive package updates)
  3. nftban.conf.local — central override (highest priority)

Each file uses KEY="VALUE" format. Later files override earlier ones.

type Enforcer

type Enforcer struct {
	// contains filtered or unexported fields
}

Enforcer writes classification decisions to nftables enforcement sets. All writes go through the OpQueue for safe async netlink batching.

func NewEnforcer

func NewEnforcer(queue *opqueue.OpQueue, config *Config) *Enforcer

NewEnforcer creates an enforcer that writes to nft sets via OpQueue.

func (*Enforcer) Apply

func (e *Enforcer) Apply(ip netip.Addr, oldState, newState IPState, reason string) error

Apply writes a classification decision to the appropriate nft set. It removes the IP from the old set (if any) and adds it to the new set.

func (*Enforcer) ApplyEmergency

func (e *Enforcer) ApplyEmergency(ip netip.Addr, reason string) error

ApplyEmergency adds an IP directly to the emergency set (fast path).

func (*Enforcer) Remove

func (e *Enforcer) Remove(ip netip.Addr, state IPState) error

Remove removes an IP from its current set (e.g., when state expires).

type FCrDNSVerifier

type FCrDNSVerifier struct {
	// contains filtered or unexported fields
}

FCrDNSVerifier performs Forward-Confirmed Reverse DNS verification using a bounded worker pool with rate limiting and caching.

func NewFCrDNSVerifier

func NewFCrDNSVerifier(cfg *Config, allowedBots []BotConfig) *FCrDNSVerifier

NewFCrDNSVerifier creates a new verifier with the given config and bot list.

func (*FCrDNSVerifier) Enqueue

func (v *FCrDNSVerifier) Enqueue(ip netip.Addr)

Enqueue submits an IP for FCrDNS verification. Non-blocking: drops the request if the queue is full.

func (*FCrDNSVerifier) Results

func (v *FCrDNSVerifier) Results() <-chan VerifyResult

Results returns the channel of completed verifications.

func (*FCrDNSVerifier) Start

func (v *FCrDNSVerifier) Start(ctx context.Context)

Start launches the worker pool and rate limiter. Blocks until ctx is cancelled.

type FeatureFlags added in v1.79.0

type FeatureFlags struct {
	// Scoring enables the v2 scoring engine.
	// When false, classic rate-based classification is used.
	Scoring bool

	// Profiles enables YAML profile loading.
	// When false, no profiles are loaded and path scoring is skipped.
	Profiles bool

	// Pressure enables pressure-based threshold adjustments.
	// When false, thresholds are static regardless of traffic.
	Pressure bool

	// Prefix enables /24 (v4) and /64 (v6) prefix tracking.
	// When false, only per-IP tracking is used.
	Prefix bool

	// PathScoring enables rule-based path scoring.
	// When false, only rate signals contribute to score.
	PathScoring bool

	// Distributed enables distributed attack detection signals.
	// When false, distributed patterns are not tracked.
	Distributed bool
}

FeatureFlags controls which v2 features are active. All flags default to false in v1.79.

func DefaultFeatures added in v1.79.0

func DefaultFeatures() FeatureFlags

DefaultFeatures returns the v1.79 defaults (all disabled).

func (FeatureFlags) IsEnabled added in v1.79.0

func (f FeatureFlags) IsEnabled() bool

IsEnabled returns true if any advanced feature is enabled. Used for fast-path checks to skip v2 logic entirely.

func (FeatureFlags) IsProfileActive added in v1.79.0

func (f FeatureFlags) IsProfileActive() bool

IsProfileActive returns true if profile loading should occur.

func (FeatureFlags) IsScoringActive added in v1.79.0

func (f FeatureFlags) IsScoringActive() bool

IsScoringActive returns true if the scoring engine should run. Requires both Scoring flag and at least one input source.

type GroupConfig added in v1.79.0

type GroupConfig struct {
	Mode       GroupMode // How to handle rules in this group
	Multiplier float64   // Score multiplier (1.0 = normal)
}

GroupConfig configures behavior for a rule group.

type GroupMode added in v1.79.0

type GroupMode string

GroupMode controls how a rule group behaves.

const (
	// GroupModeProtect scores and enforces rules in this group.
	GroupModeProtect GroupMode = "protect"

	// GroupModeMonitor scores but does not enforce (logging only).
	GroupModeMonitor GroupMode = "monitor"

	// GroupModeExempt exempts matching requests from scoring.
	GroupModeExempt GroupMode = "exempt"

	// GroupModeAggressive uses stricter thresholds for this group.
	GroupModeAggressive GroupMode = "aggressive"

	// GroupModeDisabled completely disables this group.
	GroupModeDisabled GroupMode = "disabled"
)

type GuardStats

type GuardStats struct {
	TickCount             int64         // Total classification ticks
	SuspectsFound         int64         // Total unique IPs found in suspect set
	Classified            int64         // Total IPs classified
	AllowCount            int64         // IPs classified as allow
	GreyCount             int64         // IPs classified as grey
	BanCount              int64         // IPs classified as ban
	EmergencyCount        int64         // IPs classified as emergency
	PendingCount          int64         // IPs currently pending
	TrackedIPs            int64         // Currently tracked IPs in state map
	LastTickDuration      time.Duration // Duration of last tick
	LastTickTime          time.Time     // When last tick completed
	PressureMode          bool          // Whether currently in pressure mode
	VerifyEnqueued        int64         // IPs enqueued for FCrDNS verification
	VerifyCompleted       int64         // FCrDNS verifications completed
	VerifyVerified        int64         // IPs that passed FCrDNS
	VerifyFailed          int64         // IPs that failed FCrDNS
	BatchSignalsProcessed int64         // Batch signals consumed from Clock 3
}

GuardStats holds runtime statistics for the bot guard module.

type IPRecord

type IPRecord struct {
	IP           netip.Addr   // Parsed IP address (IPv4 or IPv6)
	State        IPState      // Current classification
	Score        int32        // Accumulated threat score
	FirstSeen    time.Time    // When first detected as suspect
	LastSeen     time.Time    // Last time seen in suspect set
	ExpiresAt    time.Time    // When current state expires
	HitCount     int64        // Number of times seen in suspect set
	Reasons      []string     // Why this IP was flagged (for logging)
	BotName      string       // Identified bot name (empty if unknown)
	VerifiedAt   time.Time    // When FCrDNS verification completed (zero if not verified)
	VerifyStatus VerifyStatus // Result of FCrDNS verification
}

IPRecord tracks the classification state and history for one IP.

func (*IPRecord) Expired

func (r *IPRecord) Expired() bool

Expired returns true if the record has expired.

func (*IPRecord) IsIPv6

func (r *IPRecord) IsIPv6() bool

IsIPv6 returns true if this record tracks an IPv6 address.

type IPScore added in v1.79.0

type IPScore struct {
	IP             netip.Addr        // IP address
	TotalScore     int               // Current accumulated score
	RuleHits       map[string]int    // Count of hits per rule ID
	GroupScores    map[RuleGroup]int // Score contribution per group
	Signals        []Signal          // Recent signals (bounded buffer)
	State          IPState           // Current classification state
	FirstSeen      time.Time         // When first observed
	LastSeen       time.Time         // Last activity time
	WindowStart    time.Time         // Start of current scoring window
	ExpiresAt      time.Time         // When score expires (decay complete)
	HighWaterMark  int               // Peak score in current window
	StateHeldUntil time.Time         // Minimum time to hold current state
}

IPScore tracks the accumulated score and signal history for an IP. This is the v2 scoring structure used when feature flags are enabled.

func NewIPScore added in v1.79.0

func NewIPScore(ip netip.Addr) *IPScore

NewIPScore creates a new IPScore for the given IP.

func (*IPScore) AddSignal added in v1.79.0

func (s *IPScore) AddSignal(sig Signal)

AddSignal adds a signal to the IP's score tracking.

type IPState

type IPState int

IPState represents the classification state for an IP address. State machine: UNKNOWN → PENDING → ALLOW|GREY|BAN|EMERGENCY

const (
	StateUnknown   IPState = iota // Not yet seen by Go classifier
	StatePending                  // Awaiting classification (light throttle)
	StateAllow                    // Verified allowed crawler (bypass throttle)
	StateGrey                     // Suspicious, throttled via penalty ladder
	StateBan                      // Denied/malicious bot (full drop)
	StateEmergency                // Emergency pressure block (immediate drop)
)

func (IPState) SetName

func (s IPState) SetName() string

SetName returns the nftables set name for this state (IPv4). Returns empty string for states that don't map to a set.

func (IPState) SetName6

func (s IPState) SetName6() string

SetName6 returns the nftables set name for this state (IPv6).

func (IPState) String

func (s IPState) String() string

String returns the human-readable state name.

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger writes structured log entries for the bot guard module. Thread-safe: all writes are mutex-protected.

func NewLogger

func NewLogger(logDir string) (*Logger, error)

NewLogger creates a new file logger for botguard. Creates the log directory if it doesn't exist.

func (*Logger) Close

func (l *Logger) Close() error

Close closes both log files.

func (*Logger) LogClassification

func (l *Logger) LogClassification(ip string, oldState, newState IPState, reason, botName string, hitCount int64)

LogClassification logs a state transition to botguard.log. Format: TIMESTAMP|IP|OLD_STATE|NEW_STATE|REASON|BOT_NAME|HIT_COUNT

func (*Logger) LogDecision

func (l *Logger) LogDecision(ip string, state IPState, reason, botName string, verifyStatus VerifyStatus, hostname string)

LogDecision logs a verification-based decision to decisions.log. Format: TIMESTAMP|IP|STATE|REASON|BOT_NAME|VERIFY_STATUS|HOSTNAME

func (*Logger) LogError

func (l *Logger) LogError(context string, err error)

LogError logs an error to botguard.log.

func (*Logger) LogEvent

func (l *Logger) LogEvent(level, message string)

LogEvent logs a general event to botguard.log.

type MatchTargetType added in v1.79.0

type MatchTargetType string

MatchTargetType identifies which part of the request to match against.

const (
	// MatchRawTarget matches the raw request target (for evasion detection).
	MatchRawTarget MatchTargetType = "raw_target"

	// MatchNormalizedPath matches the normalized path (default).
	MatchNormalizedPath MatchTargetType = "normalized_path"

	// MatchDecodedPath matches the URL-decoded path.
	MatchDecodedPath MatchTargetType = "decoded_path"

	// MatchQueryString matches the query string only.
	MatchQueryString MatchTargetType = "query_string"
)

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module implements the bot guard module (module.Module interface).

func New

func New() *Module

New creates a new bot guard module.

func (*Module) GetIPRecord

func (m *Module) GetIPRecord(ip netip.Addr) (*IPRecord, bool)

GetIPRecord returns the current record for an IP (for CLI status queries).

func (*Module) GetStats

func (m *Module) GetStats() GuardStats

GetStats returns a copy of the current statistics.

func (*Module) Init

func (m *Module) Init(bus *eventbus.Bus) error

Init initializes the module with the event bus.

func (*Module) InitEnforcer

func (m *Module) InitEnforcer(queue *opqueue.OpQueue)

InitEnforcer sets up the enforcer with the OpQueue. Called after daemon creates the OpQueue.

func (*Module) Name

func (m *Module) Name() string

Name returns the module identifier.

func (*Module) Start

func (m *Module) Start(ctx context.Context) error

Start begins the classification loop.

func (*Module) Status

func (m *Module) Status() module.Status

Status returns the current module status.

func (*Module) Stop

func (m *Module) Stop() error

Stop gracefully shuts down the module.

type PressureConfig added in v1.79.0

type PressureConfig struct {
	// Enabled controls whether pressure adjustments are active.
	Enabled bool

	// ElevatedRPS is the requests-per-second threshold for elevated pressure.
	ElevatedRPS int

	// CriticalRPS is the requests-per-second threshold for critical pressure.
	CriticalRPS int

	// Multiplier adjusts thresholds during elevated pressure.
	// Example: 1.5 makes thresholds 50% stricter.
	Multiplier float64
}

PressureConfig configures pressure-based threshold adjustments.

func DefaultPressureConfig added in v1.79.0

func DefaultPressureConfig() PressureConfig

DefaultPressureConfig returns the default pressure configuration.

type PressureLevel added in v1.79.0

type PressureLevel int

PressureLevel represents the server-wide traffic pressure state.

const (
	// PressureNormal indicates normal traffic levels.
	PressureNormal PressureLevel = iota

	// PressureElevated indicates above-normal traffic (defensive adjustments).
	PressureElevated

	// PressureCritical indicates attack-level traffic (aggressive defense).
	PressureCritical
)

func (PressureLevel) String added in v1.79.0

func (p PressureLevel) String() string

String returns the pressure level as a string.

type Rule added in v1.79.0

type Rule struct {
	ID          string    `yaml:"id"`           // Unique rule identifier
	Profile     string    `yaml:"profile"`      // Which profile owns this rule
	Group       RuleGroup `yaml:"group"`        // Protection domain
	Pattern     string    `yaml:"pattern"`      // Regex pattern to match
	MatchTarget string    `yaml:"match_target"` // raw_target/normalized_path/decoded_path/query_string
	Methods     []string  `yaml:"methods"`      // HTTP methods (empty = all)
	StatusCodes []int     `yaml:"status_codes"` // Response codes to match (empty = all)
	Score       int       `yaml:"score"`        // Base score for this rule
	RateLimit   string    `yaml:"rate_limit"`   // nft rate string (e.g., "10/minute")
	Burst       int       `yaml:"burst"`        // nft burst value
	Action      Action    `yaml:"action"`       // What to do on match
	Exempt      bool      `yaml:"exempt"`       // If true, exempts from further scoring
	Description string    `yaml:"description"`  // Human-readable description
}

Rule defines a detection pattern with its scoring and action. Rules are loaded from YAML profile files.

type RuleGroup added in v1.79.0

type RuleGroup string

RuleGroup classifies rules by their protection domain. Groups can have different scoring multipliers and modes.

const (
	// GroupAuth protects authentication endpoints (login, admin, etc.).
	GroupAuth RuleGroup = "auth"

	// GroupRPC protects RPC endpoints (xmlrpc.php, wp-json, etc.).
	GroupRPC RuleGroup = "rpc"

	// GroupEnum protects against enumeration attacks (user discovery, etc.).
	GroupEnum RuleGroup = "enum"

	// GroupCommerce protects e-commerce endpoints (cart, checkout, etc.).
	GroupCommerce RuleGroup = "commerce"

	// GroupHeavy protects resource-intensive endpoints (search, export, etc.).
	GroupHeavy RuleGroup = "heavy"

	// GroupProbe detects scanning and probing behavior.
	GroupProbe RuleGroup = "probe"

	// GroupEvasion detects path obfuscation and encoding tricks.
	GroupEvasion RuleGroup = "evasion"

	// GroupGeneric is the default catch-all group.
	GroupGeneric RuleGroup = "generic"
)

func (RuleGroup) String added in v1.79.0

func (g RuleGroup) String() string

String returns the group as a string.

type ScoreDecay added in v1.79.0

type ScoreDecay struct {
	// Window is the scoring window duration.
	// Scores older than this are fully decayed.
	Window time.Duration

	// DecayRate is the per-tick decay multiplier (0.0-1.0).
	// Example: 0.1 means 10% decay per tick.
	DecayRate float64

	// HighSeverityHoldTime prevents decay for high-severity events.
	// If an IP hit a high-severity rule, decay is paused for this duration.
	HighSeverityHoldTime time.Duration

	// MinimumStateHoldTime prevents rapid state oscillation.
	// IP must stay in a state for at least this long before transitioning.
	MinimumStateHoldTime time.Duration

	// FloorScore is the minimum score after decay.
	// Prevents full decay for IPs with recent activity.
	FloorScore int
}

ScoreDecay configures how scores decay over time. Decay is applied per-tick by the scoring engine.

func DefaultScoreDecay added in v1.79.0

func DefaultScoreDecay() ScoreDecay

DefaultScoreDecay returns the default decay configuration. These values can be overridden by config.

type ScoreThresholds added in v1.79.0

type ScoreThresholds struct {
	// Suspect is the score at which an IP becomes a suspect.
	// Below this, IP is UNKNOWN.
	Suspect int

	// Grey is the score at which an IP is throttled.
	Grey int

	// Ban is the score at which an IP is banned.
	Ban int

	// Emergency is the score at which an IP is emergency-blocked.
	Emergency int
}

ScoreThresholds defines the score boundaries for state transitions.

func DefaultScoreThresholds added in v1.79.0

func DefaultScoreThresholds() ScoreThresholds

DefaultScoreThresholds returns the default threshold configuration.

func (ScoreThresholds) EvaluateState added in v1.79.0

func (t ScoreThresholds) EvaluateState(score int) IPState

EvaluateState determines the appropriate state for a given score.

type ScoringResult added in v1.79.0

type ScoringResult struct {
	IP        netip.Addr  // IP that was evaluated
	OldScore  int         // Score before this evaluation
	NewScore  int         // Score after this evaluation
	OldState  IPState     // State before this evaluation
	NewState  IPState     // State after this evaluation
	Changed   bool        // Whether state changed
	TopRules  []string    // Top contributing rule IDs
	TopGroups []RuleGroup // Top contributing groups
	Reason    string      // Human-readable reason for decision
}

ScoringResult represents the outcome of a scoring evaluation.

type Signal added in v1.79.0

type Signal struct {
	Type      SignalType     // Detection mechanism
	IP        netip.Addr     // Source IP address
	Score     int            // Score contribution from this signal
	Rule      *Rule          // Rule that triggered this signal (if path-based)
	Timestamp time.Time      // When signal was generated
	Metadata  map[string]any // Additional context (path, method, status, etc.)
}

Signal represents a detection event that contributes to an IP's score. Signals are generated by various detection mechanisms and aggregated by the scoring engine to determine state transitions.

func NewSignal added in v1.79.0

func NewSignal(typ SignalType, ip netip.Addr, score int) *Signal

NewSignal creates a new signal with the current timestamp.

func (*Signal) WithMeta added in v1.79.0

func (s *Signal) WithMeta(key string, value any) *Signal

WithMeta adds metadata to the signal.

func (*Signal) WithRule added in v1.79.0

func (s *Signal) WithRule(r *Rule) *Signal

WithRule attaches a rule to the signal.

type SignalType added in v1.79.0

type SignalType string

SignalType identifies the detection mechanism that generated a signal. v1.79: Types defined, not yet active in scoring.

const (
	// SignalPerIPRate is triggered when a single IP exceeds request rate threshold.
	SignalPerIPRate SignalType = "per_ip_rate"

	// SignalGlobalPressure is triggered when server-wide request rate is elevated.
	SignalGlobalPressure SignalType = "global_pressure"

	// SignalPrefixHot is triggered when multiple IPs in same /24 (v4) or /64 (v6) are active.
	SignalPrefixHot SignalType = "prefix_hot"

	// SignalPathMatch is triggered when request path matches a rule pattern.
	SignalPathMatch SignalType = "path_match"

	// SignalEvasion is triggered when raw request path differs from normalized (encoding tricks).
	SignalEvasion SignalType = "evasion"

	// Signal404Burst is triggered when IP generates high rate of 404 responses.
	Signal404Burst SignalType = "404_burst"

	// SignalMethodAbuse is triggered for unusual HTTP method usage (e.g., TRACE, OPTIONS flood).
	SignalMethodAbuse SignalType = "method_abuse"

	// SignalVerifyFail is triggered when FCrDNS verification fails.
	SignalVerifyFail SignalType = "verify_fail"
)

func (SignalType) String added in v1.79.0

func (s SignalType) String() string

String returns the signal type as a string.

type SuspectReader

type SuspectReader struct {
	// contains filtered or unexported fields
}

SuspectReader reads kernel-populated suspect sets.

func NewSuspectReader

func NewSuspectReader() *SuspectReader

NewSuspectReader creates a reader for the kernel suspect sets.

func (*SuspectReader) ReadSuspects

func (r *SuspectReader) ReadSuspects(ctx context.Context) ([]netip.Addr, error)

ReadSuspects reads both IPv4 and IPv6 suspect sets. Returns a combined list of suspect IPs (typically 20-100 entries). This operation completes in microseconds since the sets are small.

type V2Config added in v1.79.0

type V2Config struct {
	Features       FeatureFlags
	Thresholds     ScoreThresholds
	Decay          ScoreDecay
	Pressure       PressureConfig
	Groups         map[RuleGroup]GroupConfig
	ProfilesDir    string
	ActiveProfiles []string
}

V2Config holds all v2-specific configuration. This is populated from config files when feature flags are enabled.

func DefaultV2Config added in v1.79.0

func DefaultV2Config() V2Config

DefaultV2Config returns the default v2 configuration. All features disabled, conservative defaults.

type VerifyResult

type VerifyResult struct {
	IP       netip.Addr   // The IP that was verified
	Status   VerifyStatus // Verification outcome
	BotName  string       // Matched bot name (empty if not matched)
	Hostname string       // Reverse DNS hostname (empty if lookup failed)
}

VerifyResult holds the outcome of an FCrDNS verification.

type VerifyStatus

type VerifyStatus int

VerifyStatus represents the result of an FCrDNS verification.

const (
	VerifyNone     VerifyStatus = iota // Not yet verified
	VerifyVerified                     // FCrDNS confirmed: rDNS matches allowed domain + fwd confirms
	VerifyFailed                       // FCrDNS failed: rDNS does not match or fwd mismatch
	VerifyTimeout                      // DNS lookup timed out
	VerifyNoRDNS                       // No reverse DNS record found
)

func (VerifyStatus) String

func (v VerifyStatus) String() string

String returns the human-readable verify status name.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL