Connections, "every packet" rules, and a packet tracer

- Connections: the kernel's tracked connections, read and closed over
  ctnetlink (internal/conntrack, raw netlink like the drop log), with
  their NAT and TCP state; closing one makes the rules check its next
  packet again (GET /connections, POST /connections/close; hc
  connections; Traffic → Connections).
- Rules can check every packet (every_packet, --every-packet): before
  established connections are accepted, so a drop or reject also stops
  connections already open. They can't accept.
- A packet tracer (internal/trace): a table of its own, inet
  housecarl-trace, marks the packets a filter picks, `nft monitor trace`
  reports every rule and policy they meet in every table, and the tracer
  names what accepted or dropped them, Housecarl's rules by name (POST,
  GET, DELETE /trace; hc trace; Traffic → Trace). One trace at a time,
  at most 200 packets and 20 a second; the table goes when it ends.

e2e: 157 checks, among them an upload a normal block doesn't stop and an
every-packet one does, and a trace naming the blocking rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-19 20:22:34 +01:00
1 parent 98e11a8bec
commit a45c893830
34 files changed
+1830 -41

No files matched your search

+51 -5
View File
@@ -133,16 +133,62 @@ the last 2000 are kept in memory. They aren't written to the kernel log
or the journal. A rule's log isn't rate-limited: on a busy rule, give it
a limit, or log only new connections (`--state new`).
## Connections
The built-in that accepts established connections lets their packets
through without checking the rules again: a rule added later doesn't
stop a connection already open. Traffic → Connections (`hc connections`)
lists what the kernel tracks, with NAT (`to 192.168.1.10:443`: a port
forward; `as 203.0.113.10`: masqueraded) and the time left:
```sh
hc connections --search 192.168.1.50
hc connections --search ":443 tcp"
hc connections close --search 192.168.1.50
```
Closing a connection deletes its tracking entry: its next packet is
checked by the rules as they are now. One they block is stopped; one they
allow carries on (TCP connections are picked up again mid-stream).
To make a block stop open connections by itself, tick "every packet" on
the rule (`--every-packet`): it is checked before established connections
are accepted, like rules with a quota ([rules.md](rules.md#rules)).
## Tracing
Traffic → Trace (`hc trace`) follows packets through the whole ruleset:
Housecarl's rules and every other table (Docker's, fail2ban's, an old
`inet main`), each rule and policy they meet, and what accepted or
dropped them:
```
$ hc trace --address 192.168.1.50 --port 443 --seconds 60
14:02:13.120 192.168.1.50:51432 -> 198.51.100.9:443 tcp syn in eth1 out wan
inet housecarl forward: built-in: mss-clamp -> continue
inet housecarl forward: rule forward #12 (kids at night) -> drop
=> DROPPED by rule forward #12 (kids at night)
```
It traces packets from or to the address, on the port (either way), for
5 to 600 seconds, at most 200 packets and 20 a second. It works with
nftables' own tracing: a table of its own (`inet housecarl-trace`,
hooked before everything else) marks the packets, and `nft monitor
trace` reports them; the table goes when the trace ends. One trace runs
at a time.
## When something doesn't get through
1. `hc log -f` with `--log-drops on`: is it dropped by a policy (no rule
1. Trace it (above): it names the rule or policy that dropped it, in
whichever table.
2. `hc log -f` with `--log-drops on`: is it dropped by a policy (no rule
accepted it), or by a rule (its number is in the line)?
2. `hc rule list forward` (or `input`): hits on the rule you expect?
3. `hc ruleset`: the rule as nftables sees it, with the zones' interfaces
3. `hc rule list forward` (or `input`): hits on the rule you expect?
4. `hc ruleset`: the rule as nftables sees it, with the zones' interfaces
and the sets' families.
4. `hc status`: other tables. A Docker or Incus table, or an old one,
5. `hc status`: other tables. A Docker or Incus table, or an old one,
can drop what Housecarl accepts.
5. Port forwards: `hc forward list` hits, and the inside host's own
6. Port forwards: `hc forward list` hits, and the inside host's own
firewall and default route (answers must go back through Housecarl).
## Backups