Files
housecarl/internal/server/routes_cfg.go
T
abrown38andClaude Opus 5.5 a45c893830 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>
2026-10-19 20:22:34 +01:00

31 lines
677 B
Go

package server
import (
"encoding/json"
"housecarl/internal/trace"
)
// otherTables lists the tables in an `nft -j list ruleset` other than
// Housecarl's ("inet main").
func otherTables(data []byte) []string {
var doc struct {
Nftables []map[string]json.RawMessage `json:"nftables"`
}
out := []string{}
if json.Unmarshal(data, &doc) != nil {
return out
}
for _, item := range doc.Nftables {
raw, ok := item["table"]
if !ok {
continue
}
var t struct{ Family, Name string }
if json.Unmarshal(raw, &t) == nil && !(t.Family == "inet" && (t.Name == "housecarl" || t.Name == trace.Table)) {
out = append(out, t.Family+" "+t.Name)
}
}
return out
}