config

package
v0.0.0-...-45fb939 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: BSD-3-Clause Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ValidFieldNames

func ValidFieldNames() map[string]struct{}

ValidFieldNames returns the set of valid field names. Used by the anomaly package to build its accessor table without duplicating the list.

Types

type AlertingConfig

type AlertingConfig struct {
	WebhookURL    string `toml:"webhook_url"`
	WebhookMethod string `toml:"webhook_method"` // POST (default) or PUT
	SlackChannel  string `toml:"slack_channel"`
	MinSeverity   string `toml:"min_severity"` // "low", "medium", "high", "critical"
	RateLimitSec  int    `toml:"rate_limit_sec"`
	IncludeRaw    bool   `toml:"include_raw_fingerprints"`

	// Network alert sinks. Address format: "proto://host:port"
	// e.g. "udp://syslog.corp:514" or "tcp://siem.corp:514".
	SyslogOutput string `toml:"syslog_output"` // RFC 5424 syslog
	CEFOutput    string `toml:"cef_output"`    // ArcSight CEF over syslog
}

AlertingConfig holds webhook/alerting settings.

type Allowlist

type Allowlist struct {
	Fingerprints AllowlistFingerprints   `toml:"fingerprints"`
	Networks     AllowlistNetworks       `toml:"networks"`
	Rules        map[string]RuleOverride `toml:"rules"`
	// contains filtered or unexported fields
}

Allowlist is the parsed and validated form of an allowlist TOML file. It is loaded once at startup and hot-swapped on SIGHUP via atomic.Pointer.

Thread safety: Allowlist values are read-only after construction. All mutation happens by replacing the pointer, never by mutating in place.

func LoadAllowlist

func LoadAllowlist(path string) (*Allowlist, error)

LoadAllowlist reads and parses an allowlist TOML file. Returns a non-nil Allowlist on success; the returned error describes any parse or CIDR-validation failure. Callers should reject invalid allowlists and keep the previous valid one rather than running with no suppression.

func (*Allowlist) ShouldSuppress

func (al *Allowlist) ShouldSuppress(ruleName string, srcIP string, primaryFP string) bool

ShouldSuppress reports whether an alert from the given rule on the given connection should be suppressed per this allowlist.

Suppression matrix:

known_malicious_ja4 / known_malicious_ja4x → NEVER suppressed (safety invariant)
new_fingerprint → global FP list, global network list, per-rule FP, per-rule network
latency_anomaly → global network list, per-rule FP, per-rule network
all others      → per-rule FP, per-rule network only

ShouldSuppress is called per-alert on the hot path. All slice lookups are linear scans; typical allowlists are <100 entries so this costs ~1µs.

type AllowlistFingerprints

type AllowlistFingerprints struct {
	// SuppressNewFingerprint suppresses new_fingerprint alerts for matching
	// fingerprint values (any type). Applied globally.
	SuppressNewFingerprint []string `toml:"suppress_new_fingerprint"`
}

AllowlistFingerprints holds global fingerprint-based suppressions.

type AllowlistNetworks

type AllowlistNetworks struct {
	// Trusted CIDRs. Suppresses new_fingerprint and latency_anomaly for
	// connections whose SrcIP falls within these networks.
	// known_malicious_ja4, ua_mismatch, and ssh_tunnel still fire.
	Trusted []string `toml:"trusted"`
}

AllowlistNetworks holds global network-based suppressions.

type BehaviorConfig

type BehaviorConfig struct {
	Enabled bool `toml:"enabled"`

	// MinSeen is the number of times an anchor fingerprint must have been
	// observed before the profiler flags low-frequency companions.
	// Default: 50.
	MinSeen int `toml:"min_seen"`

	// NoveltyThreshold is the companion frequency (0.0–1.0) below which an
	// alert fires. 0.02 = flag companions seen in fewer than 2% of anchor
	// observations. Default: 0.02.
	NoveltyThreshold float64 `toml:"novelty_threshold"`

	// ProfileTTLHours is how long (in hours) an anchor profile is retained
	// without updates before it is evicted. Default: 24.
	ProfileTTLHours float64 `toml:"profile_ttl_hours"`
}

BehaviorConfig holds settings for the cross-fingerprint behavioral profiler. The profiler learns which fingerprint-type pairings are normal for this network and fires when a connection exhibits an unusual combination (e.g. JA4=X normally accompanies JA4H=Y but this connection shows JA4H=Z).

type Config

type Config struct {
	// Capture settings
	Interface     string `toml:"interface"`
	BPFFilter     string `toml:"bpf_filter"`
	Shards        int    `toml:"shards"`
	LearnDuration int    `toml:"learn_duration_minutes"` // 0 = disabled
	AFPacket      bool   `toml:"afpacket"`               // use AF_PACKET instead of libpcap
	AFPSockets    int    `toml:"afp_sockets"`            // number of AF_PACKET fanout sockets

	// Storage
	DBPath string `toml:"db_path"`

	// Alerting
	Alerting AlertingConfig `toml:"alerting"`

	// Anomaly rules
	Rules RulesConfig `toml:"rules"`

	// Daemon mode
	Daemon DaemonConfig `toml:"daemon"`

	// AllowlistFile is an optional path to a TOML allowlist for alert
	// suppression. Generated by: ja4monitor graduate. Leave empty to disable
	// suppression (all alerts fire). Reloaded on SIGHUP.
	AllowlistFile string `toml:"allowlist_file"`

	// CustomRulesFile is an optional path to a TOML file defining custom
	// threshold-based detection rules. Leave empty to use only built-in rules.
	// Reloaded on SIGHUP alongside the allowlist.
	CustomRulesFile string `toml:"custom_rules_file"`

	// Behavioral profiler settings.
	Behavior BehaviorConfig `toml:"behavior"`

	// MetricsAddr is the TCP address for the Prometheus /metrics endpoint.
	// Empty string (default) disables the metrics server. Bind to
	// "127.0.0.1:9090" for local-only access; "0.0.0.0:9090" for network.
	// No auth or TLS — use a reverse proxy for external exposure.
	MetricsAddr string `toml:"metrics_addr"`
}

Config holds all ja4monitor settings.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a Config with sensible defaults.

func Load

func Load(path string) (Config, error)

Load reads a TOML config file and merges with defaults.

type CustomRuleConfig

type CustomRuleConfig struct {
	Name        string `toml:"name"`
	Description string `toml:"description"`
	Enabled     bool   `toml:"enabled"`
	Severity    string `toml:"severity"`
	Type        string `toml:"type"`        // "threshold" (only type in v1)
	Aggregation string `toml:"aggregation"` // "count" or "count_distinct"
	Field       string `toml:"field"`       // field to aggregate over
	GroupBy     string `toml:"group_by"`    // field(s) to key the counter by
	Threshold   int    `toml:"threshold"`
	Window      string `toml:"window"`      // Go duration string: "60s", "5m", "1h"
	WindowType  string `toml:"window_type"` // "tumbling" (default) or "sliding"
	Condition   string `toml:"condition"`   // "gt", "gte", "lt", "lte", "eq"
}

CustomRuleConfig is the parsed form of one [[rule]] entry in a custom rules TOML file. Rules are loaded at startup and hot-swapped on SIGHUP.

func LoadCommunityRules

func LoadCommunityRules() ([]CustomRuleConfig, error)

LoadCommunityRules returns all rules embedded in the binary from rules.d/. These rules ship with every release and are not reloaded on SIGHUP.

If the caller also has user-defined custom rules, merge them with MergeRules so that user rules take priority when names collide.

func LoadCustomRules

func LoadCustomRules(path string) ([]CustomRuleConfig, error)

LoadCustomRules reads and validates a custom rules TOML file. Returns nil slice and nil error when path is empty (no-op). Returns a non-nil error for any parse or validation failure; callers should treat this as fatal at startup and non-fatal on SIGHUP reload (keep the previous valid set on reload failure).

func MergeRules

func MergeRules(community, custom []CustomRuleConfig) []CustomRuleConfig

MergeRules combines community rules and user custom rules into a single slice. User rules take priority: any community rule whose name matches a user rule is silently dropped. This lets operators disable or override a community rule by adding a rule with the same name to their custom file (set enabled=false to disable without writing a replacement).

The returned slice has community rules first, then user rules — consistent ordering for stable logging and deterministic test assertions.

type DaemonConfig

type DaemonConfig struct {
	SocketPath string `toml:"socket_path"`
	LogFile    string `toml:"log_file"` // JSON log output when running as daemon
	PIDFile    string `toml:"pid_file"`
}

DaemonConfig holds daemon/attach mode settings.

type RuleOverride

type RuleOverride struct {
	// SuppressForFingerprints suppresses this rule when the connection's
	// primary fingerprint matches any listed value.
	SuppressForFingerprints []string `toml:"suppress_for_fingerprints"`
	// SuppressForNetworks suppresses this rule when the connection's SrcIP
	// falls within any of these CIDRs.
	SuppressForNetworks []string `toml:"suppress_for_networks"`
}

RuleOverride provides per-rule suppression configuration.

type RulesConfig

type RulesConfig struct {
	NewFingerprint    bool `toml:"new_fingerprint"`
	UAMismatch        bool `toml:"ua_mismatch"`
	UnexpectedTunnel  bool `toml:"unexpected_tunnel"`
	KnownMaliciousJA4 bool `toml:"known_malicious_ja4"`
	KnownMaliciousX   bool `toml:"known_malicious_ja4x"`
	SSHTunnel         bool `toml:"ssh_tunnel"`
	LatencyAnomaly    bool `toml:"latency_anomaly"`

	// Thresholds
	MaxExpectedMSS     int `toml:"max_expected_mss"`     // MSS above this is normal (default: 1460)
	LatencyThresholdUS int `toml:"latency_threshold_us"` // flag latency above this (default: 100000 = 100ms)
}

RulesConfig enables/disables individual anomaly detection rules.

Jump to

Keyboard shortcuts

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