mirror of
https://github.com/slackhq/nebula.git
synced 2026-08-16 01:27:04 +02:00
103 lines
3.3 KiB
Go
103 lines
3.3 KiB
Go
// Package events defines the opt-in firewall event reporting interface.
|
|
//
|
|
// Nebula emits raw packet-level events (drops, flow creations, flow evictions,
|
|
// rule reloads) and does no aggregation, counting, batching, rule-description,
|
|
// transport, or timestamping. Embedders correlate events back to yaml rules
|
|
// out of band and capture whatever clock they need themselves. All Report*
|
|
// methods are invoked while nebula holds internal locks and must be
|
|
// non-blocking.
|
|
//
|
|
// Events are passed to Report* methods by value. Implementations must not
|
|
// take the address of a received event: doing so forces Go's escape
|
|
// analysis to move the event to the heap and costs one allocation per call.
|
|
// To forward an event, either copy its fields into the reporter's own
|
|
// pooled record or send it through a value-typed channel (chan DropEvent,
|
|
// not chan *DropEvent).
|
|
package events
|
|
|
|
import (
|
|
"github.com/slackhq/nebula/cert"
|
|
"github.com/slackhq/nebula/firewall"
|
|
)
|
|
|
|
type DropReason uint8
|
|
|
|
const (
|
|
DropInvalidLocalIP DropReason = iota
|
|
DropInvalidRemoteIP
|
|
DropPeerRejected
|
|
DropUnknownNetwork
|
|
DropNoMatchingRule
|
|
)
|
|
|
|
func (r DropReason) String() string {
|
|
switch r {
|
|
case DropInvalidLocalIP:
|
|
return "invalid_local_ip"
|
|
case DropInvalidRemoteIP:
|
|
return "invalid_remote_ip"
|
|
case DropPeerRejected:
|
|
return "peer_rejected"
|
|
case DropUnknownNetwork:
|
|
return "unknown_network"
|
|
case DropNoMatchingRule:
|
|
return "no_matching_rule"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
// DropEvent is emitted for every packet that fails the firewall check. Drops
|
|
// are not aggregated; every drop produces one event.
|
|
type DropEvent struct {
|
|
Incoming bool
|
|
Reason DropReason
|
|
Packet firewall.Packet
|
|
Context firewall.PacketContext
|
|
PeerCert *cert.CachedCertificate
|
|
RulesVersion uint16
|
|
}
|
|
|
|
// FlowCreateEvent is emitted when a packet is allowed and a new conntrack
|
|
// entry is created. Subsequent packets in the same flow do not re-emit.
|
|
type FlowCreateEvent struct {
|
|
Incoming bool
|
|
Packet firewall.Packet
|
|
Context firewall.PacketContext
|
|
PeerCert *cert.CachedCertificate
|
|
RulesVersion uint16
|
|
}
|
|
|
|
// FlowEvictEvent is emitted when a conntrack entry is removed. Context is
|
|
// not carried: timer-wheel eviction has no packet in hand, and reload
|
|
// revalidation evicts the OLD flow rather than the triggering packet.
|
|
// RulesVersion is the version under which the flow was originally allowed,
|
|
// which may differ from the current firewall version.
|
|
type FlowEvictEvent struct {
|
|
Incoming bool
|
|
Packet firewall.Packet
|
|
RulesVersion uint16
|
|
// Expired is true when eviction was due to conntrack timeout; false when
|
|
// the entry was removed because it failed re-validation after a reload.
|
|
Expired bool
|
|
}
|
|
|
|
// RulesReloadEvent is emitted once after each successful firewall reload.
|
|
// Reporters that bucket state by RulesVersion should close the old bucket
|
|
// and open a new one on receipt.
|
|
type RulesReloadEvent struct {
|
|
OldVersion uint16
|
|
NewVersion uint16
|
|
}
|
|
|
|
// Reporter is the embedder-supplied sink for firewall events. Implementations
|
|
// that want a timestamp should call time.Now() themselves at the top of the
|
|
// method; nebula does not provide one. See the package doc for the
|
|
// do-not-take-address rule.
|
|
type Reporter interface {
|
|
ReportDrop(DropEvent)
|
|
ReportFlowCreate(FlowCreateEvent)
|
|
ReportFlowEvict(FlowEvictEvent)
|
|
ReportRulesReload(RulesReloadEvent)
|
|
}
|