internal/stats samples every minute what the kernel already counts: the
interfaces' counters (per zone too), Housecarl's table (hits per rule,
built-in and policy; drops by chain; quotas; per-device sets), the
connection tracking table, and housecarld's and the host's memory, CPU
and load. Logged drops feed top lists of sources and what they tried.
Aggregates go to a database of their own (stats.db; per minute 7 days,
per hour 90 days, per day 2 years), with the store and queries from
Jarl's.
Traffic per inside device is a setting (stats_per_device): counting sets
stats_up/down_v4/v6 and rules at the top of the forward chain, IPv6 per
/64, carried across reloads. Set names starting with meter_, conn_,
quota_ or stats_ are reserved (set_name_reserved).
GET /stats/{status,summary,timeline,top,hits,heatmap}, hc stats, a
Statistics page with Jarl's charts, two charts on the dashboard, and a
conntrack_full warning. e2e: 188 checks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
100 lines
4.0 KiB
Go
100 lines
4.0 KiB
Go
package model
|
|
|
|
// Settings are the firewall-wide settings: default policies and the rules
|
|
// Housecarl adds by itself ("built-ins"), each of which can be turned off.
|
|
type Settings struct {
|
|
// Policies for packets no rule decided: accept or drop.
|
|
InputPolicy string `json:"input_policy"`
|
|
ForwardPolicy string `json:"forward_policy"`
|
|
OutputPolicy string `json:"output_policy"`
|
|
// LogPolicyDrops logs (rate-limited) what the input and forward
|
|
// policies drop.
|
|
LogPolicyDrops bool `json:"log_policy_drops,omitempty"`
|
|
|
|
Builtins Builtins `json:"builtins"`
|
|
|
|
// AntispoofV4 and AntispoofV6 are source addresses that can't come
|
|
// from the internet: dropped on external zones (Builtins.Antispoof),
|
|
// together with OwnPrefixes.
|
|
AntispoofV4 []string `json:"antispoof_v4"`
|
|
AntispoofV6 []string `json:"antispoof_v6"`
|
|
// OwnPrefixes are your own public prefixes (your delegated IPv6
|
|
// prefix, say): traffic claiming to come from them can't arrive from
|
|
// outside.
|
|
OwnPrefixes []string `json:"own_prefixes,omitempty"`
|
|
|
|
// Flowtable devices: forwarded TCP and UDP connections between them
|
|
// skip the rules once established (fast path). Empty: off. Names
|
|
// must be exact (no wildcards).
|
|
FlowtableDevices []string `json:"flowtable_devices,omitempty"`
|
|
|
|
// ProbationSeconds is how long a change made over the network has to
|
|
// be confirmed before it is rolled back (0: the default).
|
|
ProbationSeconds int `json:"probation_seconds,omitempty"`
|
|
// ManualConfirm: changes made over the network wait for a person to
|
|
// confirm them. Otherwise the client that made a change confirms it by
|
|
// itself once it reaches the API again over a new connection, from the
|
|
// same address: proof that it can still manage the firewall.
|
|
ManualConfirm bool `json:"manual_confirm,omitempty"`
|
|
|
|
// StatsPerDevice counts forwarded traffic to and from external zones
|
|
// per inside address (IPv6 per /64), for the statistics' top devices.
|
|
StatsPerDevice bool `json:"stats_per_device,omitempty"`
|
|
}
|
|
|
|
// Builtins are rules Housecarl adds itself, shown as "added by Housecarl".
|
|
type Builtins struct {
|
|
// Loopback accepts everything on lo.
|
|
Loopback bool `json:"loopback"`
|
|
// Established accepts packets of established and related connections.
|
|
Established bool `json:"established"`
|
|
// DropInvalid drops packets conntrack finds invalid.
|
|
DropInvalid bool `json:"drop_invalid"`
|
|
// ICMPv6 accepts the ICMPv6 IPv6 needs (RFC 4890): errors, echo, and
|
|
// neighbour discovery and MLD on the local link.
|
|
ICMPv6 bool `json:"icmpv6"`
|
|
// PingInternal accepts ICMP echo to the firewall from internal zones.
|
|
PingInternal bool `json:"ping_internal"`
|
|
// DHCPv6Client accepts DHCPv6 replies on external zones (an ISP's
|
|
// prefix delegation).
|
|
DHCPv6Client bool `json:"dhcpv6_client"`
|
|
// Antispoof drops impossible source addresses arriving on external
|
|
// zones (AntispoofV4, AntispoofV6, OwnPrefixes).
|
|
Antispoof bool `json:"antispoof"`
|
|
// MSSClamp clamps TCP MSS to the route MTU on external zones (needed
|
|
// with PPPoE).
|
|
MSSClamp bool `json:"mss_clamp"`
|
|
}
|
|
|
|
// Policies.
|
|
const (
|
|
PolicyAccept = "accept"
|
|
PolicyDrop = "drop"
|
|
)
|
|
|
|
// DefaultProbation is how long a network change has to be confirmed.
|
|
const DefaultProbation = 120
|
|
|
|
// DefaultSettings are the settings of a new database: drop what isn't
|
|
// allowed in and through, allow out, every built-in on.
|
|
func DefaultSettings() Settings {
|
|
return Settings{
|
|
InputPolicy: PolicyDrop,
|
|
ForwardPolicy: PolicyDrop,
|
|
OutputPolicy: PolicyAccept,
|
|
Builtins: Builtins{Loopback: true, Established: true, DropInvalid: true, ICMPv6: true,
|
|
PingInternal: true, DHCPv6Client: true, Antispoof: true, MSSClamp: false},
|
|
AntispoofV4: []string{"0.0.0.0/8", "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12",
|
|
"192.0.2.0/24", "192.168.0.0/16", "198.51.100.0/24", "203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4"},
|
|
AntispoofV6: []string{"::1/128", "::/128", "fc00::/7", "2001:db8::/32", "ff00::/8"},
|
|
}
|
|
}
|
|
|
|
// Probation is the probation in seconds, with its default.
|
|
func (s Settings) Probation() int {
|
|
if s.ProbationSeconds > 0 {
|
|
return s.ProbationSeconds
|
|
}
|
|
return DefaultProbation
|
|
}
|