Pause blocking, blocked clients and a blocked line in the statistics, compact view picker

jarl block pause|resume (and the Blocking page) lets every name through
for a while; jarld resumes on time. The lists stay loaded: the rules zone
just passes everything. Statistics gain the clients with the most blocked
queries and blocked queries on the queries chart. The view choice in the
blocking forms is a dropdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adamandClaude Opus 5.5 committed 2026-10-10 11:10:44 +00:00
1 parent 9fc23310bd
commit 27d1f9e538
31 files changed
+417 -45

No files matched your search

+7 -3
View File
@@ -426,7 +426,10 @@ Needs `blocking:read` (`blocking:write` to change). See
| POST | `/blocking/rules` | `{"name": "doubleclick.net", "action": "block", "exact": false, "views": [], "comment": ""}` (`action` block or allow; `exact`: only the name, not the names below it) |
| PATCH / DELETE | `/blocking/rules/{id}` | |
| DELETE | `/blocking/rules` | `?name=DOMAIN[&view=V][&missing_ok=1]`: the rules for a domain |
| GET | `/blocking/check` | `?name=DOMAIN`: per view with blocking, `{view, result: blocked\|allowed\|none, entry, rule_id, list}` |
| GET | `/blocking/check` | `?name=DOMAIN`: per view with blocking, `{view, result: blocked\|allowed\|none, entry, rule_id, list}` (what applies when blocking isn't paused) |
| GET | `/blocking/status` | `{paused_until}` (null when not paused) |
| POST | `/blocking/pause` | `{"minutes": 15}` (1 to 1440): let every name through until then; jarld resumes by itself |
| POST | `/blocking/resume` | end a pause now |
Lists and rules are configuration like the rest: they can be staged, and
listing with `?changeset=` marks them `pending`.
@@ -484,6 +487,7 @@ An **Operation** is `{"op": "...", "id": 0, "base_version": 0, "data": {...}}`:
| `settings.update` | | settings fields |
| `blocklist.create` / `blocklist.update` / `blocklist.delete` | blocklist (update/delete) | list fields; views as `views` (names) or `view_ids` |
| `blockrule.create` / `blockrule.update` / `blockrule.delete` | rule (update/delete) | rule fields, likewise |
| `blocking.pause` | | `{"until": "2026-10-10T15:04:05Z"}`, or `null` to resume |
Operations later in a batch can refer to objects created earlier in it by
name (zone and view names). One request can therefore create a view, a zone
@@ -493,7 +497,7 @@ in it and its records.
| Method | Path | Notes |
|--------|------|-------|
| GET | `/status` | named status, adoption, drift, open changesets, current problems, object counts; `expiring_tokens` (tokens that expire within 14 days or expired in the last 14: all for administrators, otherwise the caller's); `backup` (administrators: `last_at`, `last_file`, `last_size`, `last_error`, `last_error_at`, `dir`, `warn_after` in seconds, `stale`); `blocklist_errors` (with `blocking:read`: lists whose last update failed, `{name, error, updated_at}`) |
| GET | `/status` | named status, adoption, drift, open changesets, current problems, object counts; `expiring_tokens` (tokens that expire within 14 days or expired in the last 14: all for administrators, otherwise the caller's); `backup` (administrators: `last_at`, `last_file`, `last_size`, `last_error`, `last_error_at`, `dir`, `warn_after` in seconds, `stale`); `blocklist_errors` (with `blocking:read`: lists whose last update failed, `{name, error, updated_at}`); `blocking_paused_until` (with `blocking:read`, while paused) |
| POST | `/system/check` | validation + named-checkconf of the current configuration (`options:read`) |
| POST | `/system/resync` | `{"dry_run": false, "force": false}`: rewrite every file from the database and reload (admin) |
| GET | `/audit` | `?user=&action=&outcome=&object_type=&changeset=&q=&since=&until=&limit=200&before=ID` |
@@ -508,7 +512,7 @@ Needs `stats:read`. When statistics are disabled, every endpoint but
| GET | `/stats/status` | | `{enabled, query_log, statistics_channel, log_file, last_poll, last_log_line, log_lines_read, first_data, retention, warnings}` |
| GET | `/stats/summary` | `since` (90m, 24h, 7d, 2w; default 24h), `top` (default 10) | totals, `avg_qps`, `peak`, `rcodes`, `qtypes`, `views`, `zones`, `answers`, `transport`, `cache_hit_ratio`, `nxdomain_ratio` (without blocked answers), `blocked`, `blocked_ratio`, `blocklists` (blocked per list; `rules` for your rules), `tops` |
| GET | `/stats/timeline` | `since`, `step` (auto, 1m, 5m, 15m, 1h, 6h, 1d), `key` (repeatable or comma separated; `rcode:*` = every counter of a group; default `queries`) | `{step, times: [unix...], series: [{key, values}]}` |
| GET | `/stats/top` | `kind` (name, client, nxdomain, servfail, refused, blocked), `since`, `limit` (default 20) | `[{key, count}]`; client and refused entries add `name`, the host name of Jarl's record for the address (the summary's client list too) |
| GET | `/stats/top` | `kind` (name, client, nxdomain, servfail, refused, blocked, blocked_client), `since`, `limit` (default 20) | `[{key, count}]`; client, refused and blocked_client entries add `name`, the host name of Jarl's record for the address (the summary's client list too) |
| GET | `/stats/heatmap` | `since` (default 28d), `key` (default queries) | `{key, from, avg[7][24], samples[7][24]}`, Monday first, local time, `-1` = no data |
| GET | `/stats/breakdown` | `group` (qtype, rcode, view, zone, answer, transport, rtt, dnssec, cache, ratelimit, blocklist), `since` | `[{key, count}]` |
+23 -4
View File
@@ -17,6 +17,7 @@ does the blocking itself; jarld only prepares the lists.
- [Your rules](#your-rules)
- [Blocklists](#blocklists)
- [Checking a name](#checking-a-name)
- [Pausing](#pausing)
- [Statistics](#statistics)
- [Memory and performance](#memory-and-performance)
- [How it works](#how-it-works)
@@ -163,13 +164,31 @@ Views without blocking aren't listed.
In the web UI a blocked name gets an **Allow** button, and the statistics'
most blocked names link to this check.
## Pausing
To see whether blocking is what breaks a site, pause it: every name is
answered normally until the time is up (at most a day), then blocking
resumes by itself, also if jarld was restarted in between.
```sh
jarl block pause # 10 minutes; or: jarl block pause 1h
jarl block resume # end it now
```
In the web UI, **Pause blocking** is at the top of the Blocking page, and
the dashboard says while blocking is paused. The lists stay loaded (the
rules zone just lets everything through), so pausing and resuming take
effect within a second. Pausing and resuming are recorded in the history
like other changes.
## Statistics
With [query statistics](stats.md) on (including `query_log`), Jarl counts
what blocking does: blocked queries over time and as a share of all
queries, which rules and lists blocked them, and the most blocked names
(`jarl stats summary`, `jarl stats top blocked`, `jarl stats breakdown
blocklist`). Blocked answers are left out of the NXDOMAIN figures, which
what blocking does: blocked queries over time (next to all queries) and
as a share of them, which rules and lists blocked them, the most blocked
names, and the clients with the most blocked queries (`jarl stats summary`,
`jarl stats top blocked`, `jarl stats top blocked-clients`, `jarl stats
breakdown blocklist`). Blocked answers are left out of the NXDOMAIN figures, which
are about names that really don't exist.
Without statistics named doesn't log what it blocks at all.
+3 -1
View File
@@ -419,7 +419,7 @@ working.
```sh
jarl stats status
jarl stats summary --since 7d
jarl stats top names | clients | nxdomain | servfail | refused | blocked [--since 24h] [--limit 20]
jarl stats top names | clients | nxdomain | servfail | refused | blocked | blocked-clients [--since 24h] [--limit 20]
jarl stats timeline --since 6h [--key rcode:NXDOMAIN] [--table]
jarl stats heatmap --since 28d
jarl stats breakdown qtype | rcode | view | zone | answer | rtt | blocklist
@@ -442,6 +442,8 @@ jarl block allow DOMAIN [--exact] [--view V]... # an exception that beats every
jarl block list
jarl block delete DOMAIN [--view V] | --id ID
jarl block check DOMAIN # blocked? by which rule or list?
jarl block pause [DURATION] # let everything through for a while (default 10m, at most 24h)
jarl block resume
```
See [blocking.md](blocking.md).
+1 -1
View File
@@ -107,7 +107,7 @@ lists, views, zones). named's own counters can't be filtered.
**Top lists** (per hour and per day, the `top_n` largest): `name` (most
queried names), `client`, `nxdomain` (names answered NXDOMAIN), `servfail`
(names answered SERVFAIL), `refused` (clients that were refused), `blocked`
(names blocking answered). Blocked answers are NXDOMAIN too, but they
(names blocking answered), `blocked_client` (clients by blocked queries). Blocked answers are NXDOMAIN too, but they
aren't counted as names that don't exist: not in the `nxdomain` list, and
not in the summary's NXDOMAIN ratio.