docs: every rate-limit setting, with defaults and when to change them
A Settings section in docs/exposure.md: the counting model, a table of all 15 rate-limit settings from the BIND 9.20 ARM, and what was checked against real named (TCP never limited, NXDOMAIN falls back to responses-per-second and is counted per zone across names, all-per-second only drops, slipped answers are TC or BADCOOKIE depending on DNS cookies). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bdd7acfd3b
commit
bad360107e
1 file changed
+45
-3
+45
-3
@@ -114,9 +114,51 @@ The statistics also count it: the `rrl` breakdown (`drop`, `slip`,
|
||||
lists, and in Prometheus `jarl_ratelimit_logged_total{action}` next to
|
||||
named's own `jarl_ratelimit_responses_total` ([metrics.md](metrics.md)).
|
||||
|
||||
You can tune the block like any option (`jarl option set rate-limit '{
|
||||
responses-per-second 20; window 15; exempt-clients { 192.0.2.53; }; }'
|
||||
--view external`); the BIND ARM describes every setting.
|
||||
### Settings
|
||||
|
||||
You can tune the block like any option; `option set` replaces the whole
|
||||
block, so copy the current value from `jarl option list --view external`
|
||||
and edit it:
|
||||
|
||||
```sh
|
||||
jarl option set rate-limit '{ responses-per-second 20; window 15; slip 2; exempt-clients { 192.0.2.53; }; log-only yes; }' --view external
|
||||
```
|
||||
|
||||
named counts **identical responses** to the same **client network** (a
|
||||
/24 for IPv4, a /56 for IPv6) over a **window**, and limits each kind of
|
||||
response separately. These are the settings (BIND 9.20; the ARM has the
|
||||
full text):
|
||||
|
||||
| Setting | Default | What it does | When to change it |
|
||||
|---------|---------|--------------|-------------------|
|
||||
| `responses-per-second` | 0 (off) | Answers with data for the same name and type, per client network. Wildcard answers count as the zone's apex. This is the main limit; Jarl's fix sets 10 | Raise it if a legitimate network shows up in log-only mode, e.g. a large shared resolver (mobile carriers, public resolvers) asking for your popular names |
|
||||
| `nxdomains-per-second` | same as `responses-per-second` | NXDOMAIN answers (names that don't exist), counted together for a domain whatever the name asked | `0` turns NXDOMAIN limiting off, for zones that legitimately get many lookups of missing names |
|
||||
| `nodata-per-second` | same as `responses-per-second` | Empty answers (the name exists, the type doesn't), counted together whatever the type | Rarely |
|
||||
| `referrals-per-second` | same as `responses-per-second` | Referrals to child zones you delegate | Only if you delegate subdomains to other servers |
|
||||
| `errors-per-second` | same as `responses-per-second` | Other errors (REFUSED, SERVFAIL, FORMERR), counted together whatever the name | Rarely. REFUSED and SERVFAIL can't be truncated, so slipped ones still go out at the slip rate |
|
||||
| `all-per-second` | 0 (off) | All UDP answers to a client network, of any kind, like a firewall rate limit; over it, answers are only **dropped** (`slip` doesn't apply) | Usually leave off; if you use it, ISC says at least 4 times the other limits |
|
||||
| `window` | 15 seconds (1–3600) | How far back named counts. A client over the limit stays limited until its rate over the window falls again | Longer windows remember attackers longer and also punish short legitimate bursts longer |
|
||||
| `slip` | 2 (0–10) | Of the limited answers, every n-th "slips": instead of being dropped it gets a short reply asking the client to retry: truncated (TC) so it retries over TCP, or, when the query carried a DNS cookie, BADCOOKIE with a server cookie that lets it through on its retry. `0` drops all, `1` slips all | `1` if you'd rather every real client gets a retry hint; `0` drops all (spoofed victims see nothing, but real clients just time out) |
|
||||
| `ipv4-prefix-length` | 24 | The size of the client network answers are counted for (IPv4) | `32` counts each address on its own: fairer to neighbours, more memory |
|
||||
| `ipv6-prefix-length` | 56 | The same for IPv6 | `64` if one /56 holds many independent clients; `48` to treat a whole site as one |
|
||||
| `exempt-clients` | none | Address match list (addresses, prefixes, [ranges](concepts.md#model-views-zones-records-options), ACLs) that is never limited. Jarl's fix puts your secondaries here | Add monitoring, other servers of yours, and anything legitimate that log-only mode shows |
|
||||
| `log-only` | no | Count and log what would be limited, answer everyone normally | Jarl starts with `yes`; the "start enforcing" fix removes it |
|
||||
| `qps-scale` | off | When the total query rate is above this, all limits shrink in proportion (at a rate of 1000 with `qps-scale 250`, a limit of 20 becomes 5) | Only on busy servers that see attacks spread over many networks |
|
||||
| `max-table-size`, `min-table-size` | min 500 entries | The table of client networks named tracks (40–80 bytes per entry) | Only on busy servers |
|
||||
|
||||
What Jarl checked against real named: TCP answers are never limited;
|
||||
`nxdomains-per-second` falls back to `responses-per-second` and `0`
|
||||
turns it off; NXDOMAIN answers for different missing names in a zone
|
||||
share one limit; `all-per-second` only drops; with `slip 1`, clients
|
||||
without DNS cookies get truncated answers, and clients with cookies (dig
|
||||
sends them by default) get through on their retry with the server's
|
||||
cookie; `exempt-clients` is never limited; in log-only mode nothing is
|
||||
limited and only the log shows what would be.
|
||||
|
||||
Rate limiting is per view: put it in the external view (`--view
|
||||
external`). Set in the server options, it applies to every view that has
|
||||
none of its own, your internal resolver included, which RRL isn't meant
|
||||
for.
|
||||
|
||||
## Confirming a change that opens a view up
|
||||
|
||||
|
||||
Reference in new issue
Block a user