Files
housecarl/internal/model/settings.go
T
abrown38andClaude Opus 5.5 cf30715c5a Statistics: traffic, drops, devices and connections over time
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>
2026-10-19 22:27:48 +01:00

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
}