Files
housecarl/CHANGELOG.md
T
abrown38andClaude Opus 5.5 b6f31c86a6 Zone matrix: what the rules do between zones
internal/matrix walks each pair's rules in order, as nftables would, for
new connections: zone → zone (forward), zone → the firewall (input) and
back (output), with the built-ins that act on new connections. A rule
for the whole pair decides it; one for part of its traffic (addresses,
services, times, rates, a quota) is an exception; the rest falls to the
policy. Rules whose addresses all lie in networks connected to other
zones are left out of a pair. GET /matrix (with ?changeset, pending
changes), hc matrix [FROM TO], and a Matrix page whose cells open their
rules.

e2e: 166 checks, among them the matrix of the maintainer's imported
ruleset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 20:35:26 +01:00

6.2 KiB

Changelog

All notable changes to Housecarl are documented here. The format follows Keep a Changelog, and versions follow Semantic Versioning.

[Unreleased]

The first version of Housecarl, a firewall manager for nftables, built the way Jarl and Steward are.

Added

  • Zones, address sets and services: interfaces grouped by what they connect to (wildcards like incusbr*; external zones face the internet); sets of IPv4 and IPv6 addresses, prefixes and ranges, mixed; ports and ICMP types by name, with twenty built in (docs/rules.md).
  • Rules in four chains (input, forward, output, and early, before connection tracking), in order, matching by zone, address, service, family, connection state and status, days and hours, a rate (also per source address), and a connection count; accept, drop, reject (ICMP or TCP reset) or log. Raw nftables rules for the rest.
  • IPv4 and IPv6 together: one rule becomes the nftables rules each family needs.
  • NAT: port forwards as one object (DNAT, the forward accept, hairpin NAT, and optionally an IPv6 pinhole to a host's own port); source NAT (masquerade or an address; NAT66 on request); redirects to the firewall (docs/nat.md).
  • Built-ins, each switchable: loopback, established connections, invalid packets, ICMPv6 (RFC 4890), ping from internal zones, DHCPv6 client replies, antispoofing with your own prefixes, MSS clamping, and a flowtable fast path.
  • Changesets, as in Jarl: changes staged to be reviewed and applied together, as one history entry. Each is checked as it is staged; the review shows the problems, nftables' check and the diff of the ruleset. The web UI collects edits as pending changes by default (pending rows, a bar with Review and Apply now, a Changes page), with a switch for live edits, and Undo in History is staged like any edit; hc stages with -C ID or HOUSECARL_CHANGESET, and has hc changeset create/list/show/diff/apply/discard/remove. An applied changeset is on probation like any change. --dry-run shows the ruleset's diff too (docs/design.md, docs/cli.md).
  • Bandwidth limits and quotas: rate limits in bytes (--limit 20mbytes/second,over,per-source), per source or per destination; quotas, an allowance of traffic per rule or per address, reset daily, weekly, monthly on a chosen day, or by hand, kept across changes, restarts and reboots (hc quotas, hc rule reset-quota, usage on the rules page). Rules that count traffic are checked before established connections are accepted, so they see every packet. Per-address limits group IPv6 by /64 by default (--group-v4, --group-v6). Meters, byte rates and quotas in an imported ruleset carry over (docs/rules.md).
  • Changes checked twice and applied atomically: validation of the whole configuration with stable problem codes (docs/validation.md), then nft -c, then one nft -f transaction that replaces Housecarl's own table, inet housecarl, and nothing else. Dynamic sets' entries and the counters carry across.
  • Probation: a change made over the network rolls itself back unless confirmed within two minutes. The web UI and hc confirm their own changes once they reach Housecarl again over a new connection, from the same address (a change that cuts its client off can't, and rolls back); --no-confirm and the "a person confirms each change" setting leave it to hc confirm or the banner; changes through the local socket are kept at once; a restart rolls back what was pending. No rule is forced to keep SSH or the web UI open.
  • At boot: the confirmed ruleset is loaded by housecarl-ruleset.service before the network comes up, without housecarld. An empty configuration applies nothing.
  • Warnings about the machine: while nftables.service is enabled (it loads /etc/nftables.conf at boot, and flushes every table when stopped), and while the table an import came from still applies.
  • The zone matrix (Matrix, hc matrix): what the rules do to new connections between zones and to and from the firewall, worked out from the rules in order, with each pair's exceptions; rules about networks connected to other zones are left out of a pair.
  • Connections and tracing: the connections the kernel tracks, with their NAT, and closing them so the rules check them again (Traffic → Connections, hc connections); a rule option, "every packet", for blocks that stop connections already open; and a packet tracer (Traffic → Trace, hc trace) that follows packets through every table's rules and names what accepted or dropped them.
  • Hits and the log: packet and byte counters for every rule, NAT rule, built-in and policy; packets logged by rules and policies, read from netlink log group 4171 (hc log -f, the Log page).
  • Dynamic sets whose entries expire by themselves, changed through their own API with tokens that may be limited to one set (sets:write:guests).
  • Import of an existing nftables ruleset (hc import): rules keep their order, defines name the sets, DNAT becomes port forwards, what can't be translated stays as raw rules, with notes; hc takeover deletes the old table, on probation (docs/import.md). DNAT maps and verdict maps are expanded into one port forward or rule per element.
  • The hc CLI, the REST API and the web UI (dashboard, rules per chain with hits and reordering, NAT, zones, sets, services, the log, settings, import, history with undo; the rule dialog keeps the less used parts, such as rate limits, quotas and time windows, behind "+" buttons; each chain's built-ins are listed, with their hits, and switched in a window), with users, roles, scoped API tokens, sessions, the audit log, and the web UI's certificate from Let's Encrypt through Jarl, as in Steward.
  • Packaging: Debian packages housecarl and housecarl-cli, a systemd unit whose only privilege is CAP_NET_ADMIN, daily backups.
  • The Housecarl logo: a carved Nordic doorway in Jarl's blue, with a simplified version for small sizes, lighter on dark backgrounds; and a HOUSECARL wordmark in Jarl's and Steward's angular letters.