-
Housecarl v0.1.1-rc.11 Pre-release
released this
2026-10-21 12:57:18 +01:00 | -42 commits to main since this releaseAdded
- Reset one address's quota, or give some back.
hc rule reset-quota ID --address ADDRstarts only that device's allowance
again;--give 5gbytestakes that much off what was used instead (one
address's, or everyone's): extra allowance until the next reset,
without changing the rule. In the web UI, a rule's quota is one
line (what it used, how it resets) that opens a dialog with the rest:
usage per address, last and next reset, and Reset and Give back for
everyone or one address.POST /rules/{ref}/reset-quotatakesaddressandgive. - Names beside inside addresses. Connections, the log, quota usage,
the dashboard's quotas and the statistics' devices and blocked
sources show each inside address's name, found by a reverse lookup:
laptop 192.168.1.20in the web UI,192.168.1.20 (laptop)inhc.
Only inside addresses are looked up (an inside zone's networks, and
private ones outside the external zones'). Names are cached for 10
minutes and never stored.names.enabled,names.resolverand
names.cachein housecarl.yaml;hc --no-names;POST /names. - Quotas on the dashboard. With any rule holding a quota, the
dashboard lists them all: the allowance, what is used (for a
per-address quota, how many addresses and the busiest) with a bar, and
the next reset. Each opens its rule. - Links to a rule open it. A rule named in the matrix, the log, the
tracer, statistics or the dashboard's busiest rules opens the Rules
page on its chain, scrolled to it and highlighted (#/rules?rule=ID).
The Rules page shows each rule's ID (#410, ashcand labels name
it) beside its order. - A clearer zone matrix. A cell reads allow, block, or partly
(some new connections let through, the rest not), with the exceptions
counted by what they do (+3 -1instead of+4), and what they let
through: services with the addresses they're limited to (ssh from trusted,5 port forwards), under the grid inhc matrix, in each
cell on the Matrix page. A zone to itself is marked (only traffic routed
between its interfaces passes the firewall). The details list each
rule's hits. API:summary,allowed,blocked,open,
same_zone,note,hits, andshortandhitsper exception.
Raw rules that are a match and then accept, drop or reject (without
interfaces) are read instead of shown as unknown. - Shadow mode (
shadow.enabledin housecarl.yaml; docs/shadow.md):
Housecarl's ruleset is loaded beside the firewall you have but blocks,
rejects and translates nothing. Drops and rejects are counted and accept
instead (an accept only ends Housecarl's chain), policies accept and
always log what they would drop, NAT only counts, MSS clamping and the
flowtable are left out, and raw rules that do more than accept, drop or
reject are left out with a warning (shadow_raw_left_out). Comments
mark what would happen ([would drop]).shadow.position: Housecarl's
filter chains run after the other firewall's (filter + 10, the
default: what it would drop is what switching would break) or before
(- 10); its NAT chains always first. Every change is checked by
nftables in both forms, so leaving shadow mode can't fail. No
probation; takeovers and closing connections are refused (409). The
boot ruleset is the shadow one, and its fallback filters nothing. When
a reload (flush ruleset) deletes Housecarl's table, housecarld puts it
back (it listens to nftables' netlink notifications).modein
/status,/healthzand/auth/whoami; a banner in the web UI;
would-be drops marked in the log (shadow) and the tracer
(would_drop);hc ruleset --enforcing(GET /ruleset?enforcing=1)
shows the ruleset for after.shadow_unprotectedwarns when no other
table filters the input hook;nftables_serviceandtakeover_pending
aren't raised in shadow mode. The e2e test imports in shadow mode
before taking over. - Zone names at import:
hc import --zone enp2s0=lan(repeat;
interfaces given one name share a zone; Zone names on the Import
page), and a note listing each zone and where its name came from.
Defines holding a VLAN sub-interface (enp2s0.20) name their zone,
and_ifname,_deviceand_nicare taken off define names too
(docs/import.md, "How things are named"). - Import: sets with
flags timeoutbecome dynamic sets; a DNAT of
several ports becomes one port forward per port.
Changed
- Rules read as a direction. A match's zones are written
lan → wan,
any but wan → any, or with the firewall itself as the other end
(lan → firewallin input,firewall → wanin output), instead of
in lan · out wanandin not wan; exclusions readfrom any but X.
On the Rules and NAT pages and inhc; the flags and JSON stay as
they were.
Fixed
- Changing how a quota counts lost or muddled what it used: per address
to a total started at nothing, per source to per destination kept the
sources' use as if it were the destinations', and other groups left
the old entries behind. Now a total starts at the addresses' sum,
wider groups add up their addresses, and what can't be carried starts
again with a warning (quota_restarts) on the change. hc stats top deviceslisted each device twice (once for what it
received, once for what it sent); it is one row with both again.hc rule add --before/--after/--firstmade two changes (create at the
end, then move), so two history entries, two probations, and the rule
briefly in force at the end of its chain; staged in a changeset, the
place was lost. The create now takes the place (POST /rules?before=ID,after,first) and makes one change.hc matrixin a terminal: the colours' escape codes threw the columns
out of line.hc counters(GET /counters) kept listing the objects of a
configuration replaced since housecarld started (hc import --replacegives every object a new ID), beside the current ones; the
totals of objects that no longer exist are now forgotten.- Import: two base chains on one hook had their rules imported twice,
and the second chain's leading built-ins were moved above the first
chain's rules; they now follow each other by priority (read in a
fixed order), with the stricter policy, and a note. - Import: a rule inside a jumped-to chain that stays raw kept only its
own text and so applied to everything; the jump's condition now goes
in front. A jump and a rule matching the same field are combined only
when one's addresses lie within the other's; else the rule stays raw.
A jump's ports, ICMP types, connection status and hop limit were
dropped; a limit or log on the jump is no longer silently lost. - Import: a second match on the same field (
ip saddr A ip saddr != B)
replaced the first;!=on the hop limit and TCP flags was read as
==. Such rules now stay raw, as written. - Import: a forward-chain accept to a forwarded host and port without
ct status dnatwas folded into the port forward, which only lets
forwarded connections through; it stays a rule now. An IPv6 accept
limited to an interface no longer becomes a pinhole open to all. - Import: raw rules naming a set of the old table made nftables refuse
the ruleset; address sets are now renamedNAME_v4/NAME_v6, other
sets written out with their elements, and what can't be is left out
with a note. Rules naming a set that isn't imported stay raw instead
of failing validation. - Import: a DNAT to an IPv6 address, or with matches a port forward
can't hold (an interface excluded, a limit, a log), is left out with a
note instead of being imported without them.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Reset one address's quota, or give some back.