Add changesets, bandwidth limits and quotas; generic examples
Changesets, as in Jarl: configuration changes are operations that can be staged in a changeset, checked as they are added (validation and nft -c), reviewed with the diff of the ruleset, and applied together as one history entry, then on probation like any change made over the network. The web UI collects edits for review by default (pending rows, a bar with Review and Apply now, a Changes page, a switch for live edits); hc stages with -C ID or HOUSECARL_CHANGESET (checked like JARL_CHANGESET) and has hc changeset create/list/show/diff/apply/discard/remove. Undo, import and takeover refuse a changeset. --dry-run shows the ruleset's diff. Bandwidth and quotas: rate limits in bytes, per source or destination; quotas per rule or per address that reset daily, weekly, monthly on a day, or by hand, with their usage carried across reloads, saved for reboots, shown by hc quotas and on the rules page, and reset with hc rule reset-quota. Rules that count traffic are checked before established connections are accepted (so they see every packet) and can't accept. Per-address limits group IPv6 by /64 by default (--group-v4/-v6). Per-source rate meters use update. The importer turns meters, byte rates and quotas into these fields. The examples in the web UI, hc's help and the docs use documentation addresses and generic names instead of the maintainer's network. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ebec2cfcca
commit
2880f7ddc9
63 files changed
+4018
-385
No files matched your search
@@ -186,6 +186,68 @@ not_contains "disabled"
|
||||
run "the rollback is in the history" 0 H history list
|
||||
contains "rollback"
|
||||
|
||||
# ---- changesets: staged, reviewed, applied together
|
||||
|
||||
CS=$(C changeset create "e2e batch" -q)
|
||||
run "a changeset" 0 test -n "$CS"
|
||||
CE() { docker exec -e HOUSECARL_CHANGESET=$CS ${P}-client /w/hc --config /w/cli.yaml --server http://$LAN4:8070 --token "$TOKEN" "$@"; }
|
||||
run "staged from HOUSECARL_CHANGESET" 0 CE set add e2e_block 198.51.100.7
|
||||
contains "staged in changeset $CS as operation 1"
|
||||
contains "from HOUSECARL_CHANGESET"
|
||||
run "a rule naming the staged set" 0 CE rule add input --from e2e_block --service ssh -a drop
|
||||
contains "operation 2"
|
||||
run "disabling the jellyfin forward, staged" 0 CE forward update jellyfin --disabled
|
||||
contains "operation 3"
|
||||
run "nothing is live yet: the forward still works" 0 connect net $WAN4 8096
|
||||
contains "^jellyfin$"
|
||||
run "the set isn't there yet" 4 H set show e2e_block
|
||||
run "the changeset's diff" 0 CE changeset diff
|
||||
contains "^+.*ip saddr @e2e_block_v4 tcp dport 22 counter drop"
|
||||
contains "^-.*dnat ip to 10.88.10.57:443"
|
||||
contains "valid: nftables accepts"
|
||||
run "remove the forward operation" 0 CE changeset remove 3
|
||||
contains "has 2 operations"
|
||||
run "the diff without it" 0 CE changeset diff
|
||||
not_contains "dnat ip to 10.88.10.57"
|
||||
run "applied together" 0 CE changeset apply
|
||||
contains "applied on probation"
|
||||
contains "HOUSECARL_CHANGESET still names changeset $CS"
|
||||
run "one history entry" 0 H history list
|
||||
contains "e2e batch"
|
||||
run "confirmed" 0 C confirm
|
||||
run "the set is there now" 0 H set show e2e_block
|
||||
run "the forward still works" 0 connect net $WAN4 8096
|
||||
contains "^jellyfin$"
|
||||
run "a stale HOUSECARL_CHANGESET is refused" 1 CE zone add stale -i stale0
|
||||
contains "is applied"
|
||||
CS2=$(H changeset create -q)
|
||||
run "an undo can't be staged" 6 H -C "$CS2" history undo 1
|
||||
contains "can't be staged"
|
||||
run "discarded" 0 H changeset discard "$CS2"
|
||||
run "a dry run shows the ruleset's diff" 0 H -n set add e2e_dry 10.1.2.3
|
||||
contains "^+.*set e2e_dry_v4"
|
||||
|
||||
# ---- quotas: an allowance per device, kept across a restart, reset
|
||||
|
||||
QR=$(H -o id rule add forward --from $CLIENT4 --service tcp/9000 --quota 1mbytes,over,per-source -a drop --first --comment "e2e quota")
|
||||
run "a per-device quota" 0 test -n "$QR"
|
||||
send() { docker exec ${P}-client sh -c "head -c $1 /dev/zero | nc -N -w 3 $NET4 9000"; }
|
||||
run "within the quota" 0 send 300000
|
||||
send 2000000 >/dev/null 2>&1
|
||||
run "used up: the device is cut off" 1 send 1000
|
||||
run "the usage" 0 H quotas
|
||||
contains "e2e quota.*1.0 MB each.*by hand"
|
||||
contains "$CLIENT4 *1\.[0-9] MB"
|
||||
docker exec ${P}-router sh -c 'kill $(pidof housecarld)'; sleep 1; start
|
||||
run "after a restart, still used up" 1 send 1000
|
||||
run "the usage after a restart" 0 H quotas
|
||||
contains "$CLIENT4 *1\.[0-9] MB"
|
||||
run "reset by hand" 0 H rule reset-quota "$QR"
|
||||
run "the device is back" 0 send 1000
|
||||
run "the reset is audited" 0 H audit --action quota.
|
||||
contains "quota.reset"
|
||||
run "the quota rule goes" 0 H rule delete -y "$QR"
|
||||
|
||||
# ---- the drop log
|
||||
|
||||
run "log drops from the internet to the API" 0 H rule add input --in wan --service tcp/8070 -a drop --log --first
|
||||
|
||||
Reference in new issue
Block a user