suricata

package
v1.8.2 Latest Latest
Warning

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

Go to latest
Published: Jan 30, 2026 License: MPL-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseProxyNetworks added in v1.8.1

func ParseProxyNetworks(cidrs []string) ([]*net.IPNet, error)

ParseProxyNetworks parses CIDR strings into IPNet slice

Types

type ActorTrust added in v1.8.1

type ActorTrust string

ActorTrust represents the trust level of the resolved actor IP

const (
	ActorDirect         ActorTrust = "direct"
	ActorProxyTrusted   ActorTrust = "proxy_trusted"
	ActorProxyUntrusted ActorTrust = "proxy_untrusted"
)

func ResolveActorIP added in v1.8.1

func ResolveActorIP(srcIP string, http *HTTPDetails, proxyCfg ProxyTrustConfig) (actorIP string, trust ActorTrust)

ResolveActorIP determines the real client IP, handling trusted proxies Security: XFF is ONLY trusted when source IP is in trusted proxy networks

type AlertDetails added in v1.8.1

type AlertDetails struct {
	SID       int                 `json:"sid,omitempty"`       // Suricata Signature ID
	GID       int                 `json:"gid,omitempty"`       // Generator ID
	Rev       int                 `json:"rev,omitempty"`       // Revision
	Signature string              `json:"signature,omitempty"` // Full signature text
	Category  string              `json:"category,omitempty"`  // Alert category
	Severity  int                 `json:"severity,omitempty"`  // 1-4 (1=high)
	Action    string              `json:"action,omitempty"`    // "allowed", "blocked"
	Metadata  map[string][]string `json:"metadata,omitempty"`
}

AlertDetails contains Suricata alert data

type BanHandler

type BanHandler interface {
	BanIP(ip string, duration time.Duration, reason string) error
}

BanHandler defines the interface for banning IPs

type Config

type Config struct {
	GlobalEnabled    bool
	DefaultThreshold int
	DefaultBanTime   time.Duration
	DefaultAction    string
	ScoreDecay       time.Duration
	Filters          map[string]*FilterConfig
}

Config holds the complete Suricata filter configuration

func LoadConfig

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

LoadConfig loads Suricata filter configuration from files Loads filters.conf first, then filters.conf.local overrides

func (*Config) GetEnabledFilters

func (c *Config) GetEnabledFilters() map[string]*FilterConfig

GetEnabledFilters returns only enabled filters

func (*Config) GetFilter

func (c *Config) GetFilter(name string) (*FilterConfig, bool)

GetFilter returns a specific filter by name

type DNSDetails added in v1.8.1

type DNSDetails struct {
	Type   string   `json:"type,omitempty"`   // "query" or "answer"
	RRType string   `json:"rrtype,omitempty"` // A, AAAA, MX, etc.
	RRName string   `json:"rrname,omitempty"` // Query name
	RCode  string   `json:"rcode,omitempty"`  // Response code
	RData  []string `json:"rdata,omitempty"`  // Response data
}

DNSDetails contains DNS-specific event data

type EveAlert

type EveAlert struct {
	Timestamp string `json:"timestamp"`
	EventType string `json:"event_type"`
	SrcIP     string `json:"src_ip"`
	SrcPort   int    `json:"src_port"`
	DestIP    string `json:"dest_ip"`
	DestPort  int    `json:"dest_port"`
	Proto     string `json:"proto"`
	Alert     struct {
		SignatureID int    `json:"signature_id"`
		Signature   string `json:"signature"`
		Category    string `json:"category"`
		Severity    int    `json:"severity"` // 1=High, 2=Medium, 3=Low, 4=Info
		Action      string `json:"action"`
	} `json:"alert"`
	HTTP *struct {
		Hostname string `json:"hostname"`
		URL      string `json:"url"`
		Method   string `json:"http_method"`
	} `json:"http,omitempty"`
	SSH *struct {
		Client  string `json:"client"`
		Server  string `json:"server"`
		Version string `json:"proto_version"`
	} `json:"ssh,omitempty"`
}

EveAlert represents a Suricata eve.json alert entry

type EveAlertFields added in v1.8.1

type EveAlertFields struct {
	Action    string              `json:"action"`
	GID       int                 `json:"gid"`
	SID       int                 `json:"signature_id"`
	Rev       int                 `json:"rev"`
	Signature string              `json:"signature"`
	Category  string              `json:"category"`
	Severity  int                 `json:"severity"`
	Metadata  map[string][]string `json:"metadata,omitempty"`
}

EveAlertFields represents alert fields in EVE JSON

type EveDNS added in v1.8.1

type EveDNS struct {
	Type   string   `json:"type"`
	RRType string   `json:"rrtype"`
	RRName string   `json:"rrname"`
	RCode  string   `json:"rcode"`
	RData  []string `json:"rdata"`
}

EveDNS represents DNS fields in EVE JSON

type EveEvent added in v1.8.1

type EveEvent struct {
	Timestamp   string `json:"timestamp"`
	EventType   string `json:"event_type"`
	SrcIP       string `json:"src_ip"`
	SrcPort     int    `json:"src_port"`
	DestIP      string `json:"dest_ip"`
	DestPort    int    `json:"dest_port"`
	Proto       string `json:"proto"`
	AppProto    string `json:"app_proto"`
	FlowID      uint64 `json:"flow_id"`
	TxID        int    `json:"tx_id,omitempty"`
	CommunityID string `json:"community_id,omitempty"`

	// HTTP fields (when event_type=http or embedded in alert)
	HTTP *EveHTTP `json:"http,omitempty"`

	// TLS fields
	TLS *EveTLS `json:"tls,omitempty"`

	// Alert fields
	Alert *EveAlertFields `json:"alert,omitempty"`

	// DNS fields
	DNS *EveDNS `json:"dns,omitempty"`

	// SSH fields
	SSH *EveSSH `json:"ssh,omitempty"`
}

EveEvent represents a raw Suricata EVE JSON event (extended fields) This extends the basic EveAlert with additional L7 protocol support

type EveHTTP added in v1.8.1

type EveHTTP struct {
	Hostname    string `json:"hostname"`
	URL         string `json:"url"`
	Method      string `json:"http_method"`
	Status      int    `json:"status"`
	UserAgent   string `json:"http_user_agent"`
	Referer     string `json:"http_refer"`
	XFF         string `json:"xff"`
	ContentType string `json:"http_content_type"`
	Length      int64  `json:"length"`
	Protocol    string `json:"protocol"`
}

EveHTTP represents HTTP fields in EVE JSON

type EveReader

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

EveReader reads and parses Suricata eve.json log file

func NewEveReader

func NewEveReader(evePath string, matcher *FilterMatcher) (*EveReader, error)

NewEveReader creates a new eve.json reader

func (*EveReader) Close

func (r *EveReader) Close() error

Close closes the eve.json file

func (*EveReader) ReadEvent

func (r *EveReader) ReadEvent() (*Event, error)

ReadEvent reads the next event from eve.json Returns nil if no event available (non-blocking)

func (*EveReader) ReadEvents

func (r *EveReader) ReadEvents(events chan<- *Event, stopChan <-chan struct{}) error

ReadEvents continuously reads events from eve.json Sends events to the provided channel

type EveSSH added in v1.8.1

type EveSSH struct {
	Client *struct {
		ProtoVersion    string `json:"proto_version"`
		SoftwareVersion string `json:"software_version"`
	} `json:"client,omitempty"`
	Server *struct {
		ProtoVersion    string `json:"proto_version"`
		SoftwareVersion string `json:"software_version"`
	} `json:"server,omitempty"`
}

EveSSH represents SSH fields in EVE JSON

type EveTLS added in v1.8.1

type EveTLS struct {
	SNI     string `json:"sni"`
	Version string `json:"version"`
	Subject string `json:"subject"`
	Issuer  string `json:"issuerdn"`
	JA3     *struct {
		Hash string `json:"hash"`
	} `json:"ja3,omitempty"`
	JA3S *struct {
		Hash string `json:"hash"`
	} `json:"ja3s,omitempty"`
	Fingerprint string `json:"fingerprint,omitempty"`
	Serial      string `json:"serial,omitempty"`
	NotBefore   string `json:"notbefore,omitempty"`
	NotAfter    string `json:"notafter,omitempty"`
}

EveTLS represents TLS fields in EVE JSON

type Event

type Event struct {
	Timestamp   time.Time
	EventType   string // "alert", "http", "ssh", etc.
	SrcIP       string
	SrcPort     int
	DestIP      string
	DestPort    int
	Proto       string
	SignatureID int
	Signature   string
	Category    string
	Severity    int    // 1=High, 2=Medium, 3=Low, 4=Info
	Filter      string // Matched filter name (e.g., "ssh", "http")
}

Event represents a normalized Suricata event for NFTBan processing

type EventLogger

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

EventLogger logs Suricata events and actions to file

func NewEventLogger

func NewEventLogger(logPath string) (*EventLogger, error)

NewEventLogger creates a new event logger

func (*EventLogger) Close

func (l *EventLogger) Close() error

Close closes the log file

func (*EventLogger) LogBanAction

func (l *EventLogger) LogBanAction(ip string, filter string, score int, threshold int, banTime time.Duration, reason string) error

LogBanAction logs a Suricata-triggered ban action with score details

func (*EventLogger) LogError

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

LogError logs an error

func (*EventLogger) LogEvent

func (l *EventLogger) LogEvent(event *Event, score int, threshold int, action string, decision string) error

LogEvent logs a Suricata event with calculated score

type FilterConfig

type FilterConfig struct {
	Name        string
	Enabled     bool
	Keywords    []string
	Threshold   int
	BanTime     time.Duration
	Action      string        // "log", "observe", "ban"
	BanType     string        // "temporary", "permanent", "escalate"
	MaxBans     int           // For escalate: after X temp bans, go permanent
	Period      time.Duration // For escalate: count bans in this period
	Description string
}

FilterConfig represents a single Suricata filter configuration

type FilterMatcher

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

FilterMatcher handles matching Suricata signatures to filters

func NewFilterMatcher

func NewFilterMatcher(config *Config) *FilterMatcher

NewFilterMatcher creates a new filter matcher

func (*FilterMatcher) GetFilterForEvent

func (fm *FilterMatcher) GetFilterForEvent(signature, category string) (string, *FilterConfig)

GetFilterForEvent determines which filter matches an event Tries signature first, then category, returns first match

func (*FilterMatcher) MatchCategory

func (fm *FilterMatcher) MatchCategory(category string) (string, *FilterConfig)

MatchCategory matches a Suricata category against configured filters

func (*FilterMatcher) MatchSignature

func (fm *FilterMatcher) MatchSignature(signature string) (string, *FilterConfig)

MatchSignature matches a Suricata signature against configured filters Returns the matching filter name, or empty string if no match

type HTTPDetails added in v1.8.1

type HTTPDetails struct {
	Method      string `json:"method"`
	Host        string `json:"host,omitempty"`
	URI         string `json:"uri,omitempty"`
	Status      int    `json:"status,omitempty"`
	UserAgent   string `json:"user_agent,omitempty"`
	Referer     string `json:"referer,omitempty"`
	XFF         string `json:"xff,omitempty"` // X-Forwarded-For (untrusted unless proxy verified)
	ContentType string `json:"content_type,omitempty"`
	Length      int64  `json:"length,omitempty"`
	Protocol    string `json:"protocol,omitempty"` // HTTP/1.1, HTTP/2
}

HTTPDetails contains HTTP-specific event data

type IPScore

type IPScore struct {
	IP           string
	CurrentScore int
	Events       []time.Time // Timestamps of recent events (capped to MaxEventsPerIP)
	LastUpdate   time.Time
	TotalEvents  int
	// contains filtered or unexported fields
}

IPScore tracks scoring for a single IP address

type NetlinkBanHandler

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

NetlinkBanHandler implements BanHandler using the existing netlink infrastructure This matches the existing fail2ban approach - uses sync.NFTManager for banning

func NewNetlinkBanHandler

func NewNetlinkBanHandler() (*NetlinkBanHandler, error)

NewNetlinkBanHandler creates a new ban handler using the existing netlink infrastructure

func (*NetlinkBanHandler) BanIP

func (h *NetlinkBanHandler) BanIP(ip string, duration time.Duration, reason string) error

BanIP bans an IP using the existing netlink/nftables infrastructure This is the same mechanism used by fail2ban integration

func (*NetlinkBanHandler) Close

func (h *NetlinkBanHandler) Close()

Close closes the ban handler and cleans up resources

type Processor

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

Processor handles the main Suricata event processing loop

func NewProcessor

func NewProcessor(cfg *ProcessorConfig) (*Processor, error)

NewProcessor creates a new Suricata event processor

func (*Processor) GetScores

func (p *Processor) GetScores() map[string]*IPScore

GetScores returns all current IP scores

func (*Processor) GetStats

func (p *Processor) GetStats() map[string]interface{}

GetStats returns current processor statistics

func (*Processor) Start

func (p *Processor) Start() error

Start starts the processor

func (*Processor) Stop

func (p *Processor) Stop() error

Stop stops the processor

type ProcessorConfig

type ProcessorConfig struct {
	ConfigDir  string
	EvePath    string
	LogPath    string
	BanHandler BanHandler
}

ProcessorConfig holds configuration for the processor

type ProxyTrustConfig added in v1.8.1

type ProxyTrustConfig struct {
	Enabled         bool
	Networks        []*net.IPNet
	RejectPrivateIP bool // Reject private IPs from XFF
}

ProxyTrustConfig configures trusted proxy handling for actor IP resolution

type SSHDetails added in v1.8.1

type SSHDetails struct {
	Client struct {
		Version  string `json:"version,omitempty"`
		Software string `json:"software,omitempty"`
	} `json:"client,omitempty"`
	Server struct {
		Version  string `json:"version,omitempty"`
		Software string `json:"software,omitempty"`
	} `json:"server,omitempty"`
}

SSHDetails contains SSH-specific event data

type Scorer

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

Scorer calculates threat scores for IPs based on Suricata events Implements bounded memory via LRU eviction and per-IP event caps. Protects against CWE-400 (Uncontrolled Resource Consumption).

func NewScorer

func NewScorer(config *Config) *Scorer

NewScorer creates a new scorer with bounded memory

func (*Scorer) AddEvent

func (s *Scorer) AddEvent(event *Event) int

AddEvent processes a new event and updates IP score

func (*Scorer) GetAllScores

func (s *Scorer) GetAllScores() map[string]*IPScore

GetAllScores returns all current IP scores

func (*Scorer) GetIPScore

func (s *Scorer) GetIPScore(ip string) *IPScore

GetIPScore returns full scoring details for an IP

func (*Scorer) GetScore

func (s *Scorer) GetScore(ip string) int

GetScore returns the current score for an IP

func (*Scorer) GetStats added in v1.0.28

func (s *Scorer) GetStats() map[string]int

GetStats returns memory usage statistics for monitoring

func (*Scorer) ResetScore

func (s *Scorer) ResetScore(ip string)

ResetScore resets the score for an IP (e.g., after banning)

func (*Scorer) Stop

func (s *Scorer) Stop()

Stop stops the scorer

type TLSDetails added in v1.8.1

type TLSDetails struct {
	SNI         string `json:"sni,omitempty"`
	JA3         string `json:"ja3,omitempty"`
	JA3S        string `json:"ja3s,omitempty"`
	JA4         string `json:"ja4,omitempty"`
	Version     string `json:"version,omitempty"`
	Subject     string `json:"subject,omitempty"`
	Issuer      string `json:"issuer,omitempty"`
	Fingerprint string `json:"fingerprint,omitempty"`
	Serial      string `json:"serial,omitempty"`
	NotBefore   string `json:"not_before,omitempty"`
	NotAfter    string `json:"not_after,omitempty"`
}

TLSDetails contains TLS-specific event data

type ThreatEvent added in v1.8.1

type ThreatEvent struct {
	// Identity
	EventID   string          `json:"event_id"`
	Timestamp time.Time       `json:"timestamp"`
	Sensor    string          `json:"sensor,omitempty"`
	EventType ThreatEventType `json:"event_type"`
	FlowID    uint64          `json:"flow_id,omitempty"`
	TxID      int             `json:"tx_id,omitempty"`

	// Actor (resolved real client IP)
	ActorIP    string     `json:"actor_ip"`
	ActorTrust ActorTrust `json:"actor_trust"`
	ActorKey   string     `json:"actor_key"` // stable key for aggregation (usually ActorIP)

	// Network layer
	SrcIP    string `json:"src_ip"`
	DstIP    string `json:"dst_ip"`
	Proto    string `json:"proto"`
	AppProto string `json:"app_proto,omitempty"`
	SrcPort  int    `json:"src_port,omitempty"`
	DstPort  int    `json:"dst_port,omitempty"`

	// Correlation
	CommunityID       string `json:"community_id,omitempty"`
	ObservedDirection string `json:"direction,omitempty"` // "inbound", "outbound"

	// Protocol-specific details
	HTTP  *HTTPDetails  `json:"http,omitempty"`
	TLS   *TLSDetails   `json:"tls,omitempty"`
	Alert *AlertDetails `json:"alert,omitempty"`
	DNS   *DNSDetails   `json:"dns,omitempty"`
	SSH   *SSHDetails   `json:"ssh,omitempty"`

	// Scoring (computed by scorer)
	Score      float64            `json:"score,omitempty"`
	Category   string             `json:"category,omitempty"`
	Confidence float64            `json:"confidence,omitempty"`
	Features   map[string]float64 `json:"features,omitempty"`
}

ThreatEvent is the canonical event model for all Suricata events This extends the basic Event struct with L7 deep packet inspection fields

func MapEVEToThreatEvent added in v1.8.1

func MapEVEToThreatEvent(eve *EveEvent, sensor string, proxyCfg ProxyTrustConfig) (*ThreatEvent, error)

MapEVEToThreatEvent converts a raw Suricata EVE event to canonical ThreatEvent

type ThreatEventType added in v1.8.1

type ThreatEventType string

ThreatEventType represents the type of Suricata event

const (
	ThreatEventTypeHTTP  ThreatEventType = "http"
	ThreatEventTypeTLS   ThreatEventType = "tls"
	ThreatEventTypeDNS   ThreatEventType = "dns"
	ThreatEventTypeSSH   ThreatEventType = "ssh"
	ThreatEventTypeAlert ThreatEventType = "alert"
	ThreatEventTypeFlow  ThreatEventType = "flow"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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