SPEC: false statements fixed, repeats removed, dropped requirements restored
check / check (push) Waiting to run
check / check (push) Waiting to run
The bounds sentence, the blocklist URL sentence, the deny list sentence, the limit action's scope and the observe mode sentence now say what the code does. Each of the twenty-one requirements the fourth review found twice is stated once, with a link from the other place. The request id header, redirect_uri's case, change 4's reason and the live archive's InRelease files are back. The biased thresholds are defined where they are introduced. The docs files apply the fifth README review's findings and stay identical to the README branch. Model: fable-5-1
This commit is contained in:
+8
-5
@@ -78,11 +78,14 @@ on one line:
|
||||
|
||||
- `instance`: `SWWAF_INSTANCE_NAME`. `time`: when the alert was raised. `event`:
|
||||
one of the events above.
|
||||
- `client`: the address whose request raised the alert. `netblock`: the ban's
|
||||
netblock, the netblock an anomaly counted, or, for the other events, the
|
||||
client as rate limiting counts it: an IPv4 address as a /32, or an IPv6 group.
|
||||
Both are empty for `source_failure` and `file_error`.
|
||||
- `asn`, `as_name` and `country`: the client's as known when the alert was
|
||||
- `client`: the address whose request raised the alert. Empty for
|
||||
`source_failure` and `file_error`.
|
||||
- `netblock`: empty for `source_failure` and `file_error`; otherwise one of:
|
||||
- the ban's netblock;
|
||||
- the netblock an anomaly counted;
|
||||
- for the other events, the client as rate limiting counts it: an IPv4
|
||||
address as a /32, or an IPv6 group.
|
||||
- `asn`, `as_name` and `country`: the client's, as known when the alert was
|
||||
raised. They are empty when GeoJS had not answered yet.
|
||||
- `reason`: a short sentence, such as
|
||||
`requests per minute over the limit of 1000` or `listed by a blocklist`.
|
||||
|
||||
+38
-34
@@ -21,10 +21,10 @@ checked again when gitea or the Core Rule Set changes version.
|
||||
- a release attachment.
|
||||
|
||||
At the defaults, an upload larger than 100 MiB or taking more than 60
|
||||
seconds is cut off, and no one is banned for it. "Size and time limits" in
|
||||
`SPEC.md` gives the answers the client gets. A gitea that takes large
|
||||
uploads needs `SWWAF_REQUEST_MAX_BYTES`, `SWWAF_CLIENT_REQUEST_TIMEOUT` and
|
||||
`SWWAF_UPSTREAM_REQUEST_TIMEOUT` raised to fit.
|
||||
seconds is cut off ("Size and time limits" in `SPEC.md`). A gitea that takes
|
||||
large uploads needs `SWWAF_REQUEST_MAX_BYTES`,
|
||||
`SWWAF_CLIENT_REQUEST_TIMEOUT` and `SWWAF_UPSTREAM_REQUEST_TIMEOUT` raised
|
||||
to fit.
|
||||
|
||||
- Archive download and blame or history pages are what scrapers hammer. The
|
||||
request limits do most of the work there.
|
||||
@@ -63,15 +63,15 @@ toward). The request log names the rule in `waf_rule_ids`, which
|
||||
|
||||
### A query string that reads as an attack
|
||||
|
||||
Most often this is a search. Every query parameter is checked against the Core
|
||||
Rule Set's lists of system files and commands, except the ten named under
|
||||
"Attack detection" in `SPEC.md`. A release attachment uploaded through the API
|
||||
as `docker-compose.yml` is refused the same way. Examples:
|
||||
Most often this is a search. A search term is a query parameter, which the Core
|
||||
Rule Set checks against its lists of system files and commands (see the fourth
|
||||
change under "Attack detection" in `SPEC.md`). A release attachment uploaded
|
||||
through the API as `docker-compose.yml` is refused the same way. Examples:
|
||||
|
||||
- a name on those lists, such as `package.json`, `.gitignore` or
|
||||
`docker-compose.yml`;
|
||||
- text that starts with a command name, or whose first word has one right after
|
||||
a `/`, such as `python3`, `ssh key` or `feat/docker-support`;
|
||||
- text that starts with a command name, such as `python3` or `ssh key`, or has
|
||||
one right after a `/` in its first word, such as `feat/docker-support`;
|
||||
- a shell command with its options or a system path (`ls -la`, `sed -i`,
|
||||
`/bin/sh`), or a command in backticks;
|
||||
- script code (`fetch(`, `${VAR}`, `process.env`), HTML (`<img src=`) or an SQL
|
||||
@@ -81,15 +81,15 @@ as `docker-compose.yml` is refused the same way. Examples:
|
||||
### A branch, tag or file name that starts with a command name
|
||||
|
||||
The Core Rule Set's list of commands (932260) holds names such as `docker-`,
|
||||
`python3`, `ansible`, `base64` and `whoami`. A branch, tag or file name that
|
||||
starts with one is refused. So is one that has such a name right after a `/`,
|
||||
such as `feat/docker-support`, `fix/docker-build` or
|
||||
`python3`, `ansible`, `base64` and `whoami`. A query parameter holding a branch,
|
||||
tag or file name that starts with one is refused. So is one that has such a name
|
||||
right after a `/`, such as `feat/docker-support`, `fix/docker-build` or
|
||||
`renovate/docker-build-push-action-6.x`. gitea's own pages send the name in a
|
||||
query parameter that 930120, 932160 and 932260 still check:
|
||||
|
||||
- `refSubUrl`, the branch or tag of a directory listing. It is sent when the
|
||||
listing asks for its entries' last commits in a second request, which it does
|
||||
whenever gitea takes more than a second to work them out;
|
||||
- `refSubUrl`, the branch or tag of a directory listing. A listing sends it when
|
||||
it asks for its entries' last commits in a second request. It does so whenever
|
||||
gitea takes more than a second to work them out;
|
||||
- `name`, when a branch is deleted or restored on the branches page;
|
||||
- `tag`, when a release is started from a tag;
|
||||
- `template`, the file of an issue template, when an issue is opened from it;
|
||||
@@ -110,9 +110,9 @@ What a visitor sees, for a branch named `docker-build`:
|
||||
### A file name in a query parameter that trips the code rules
|
||||
|
||||
The Core Rule Set's rules for Java, script, PowerShell and SQL find what they
|
||||
look for in some file names. This holds in the parameters `smallwebwaf` leaves
|
||||
out of 930120, 932160 and 932260 too (see the changes to the Core Rule Set under
|
||||
"Attack detection" in `SPEC.md`). Examples:
|
||||
look for in some file names. This holds too in the ten query parameters that
|
||||
930120, 932160 and 932260 do not check (see the fourth change under "Attack
|
||||
detection" in `SPEC.md`). Examples:
|
||||
|
||||
- `runtime` in OpenJDK's `src/java.base/share/classes/java/lang/Runtime.java`
|
||||
(944110);
|
||||
@@ -129,9 +129,9 @@ For such a file, these requests are refused:
|
||||
- the API's call for the contents of files that names it in its query (`body`);
|
||||
- the commit graph of that file alone (`file`);
|
||||
- the hidden lines of its diff (`path`), which stay hidden;
|
||||
- the sign-in page gitea sends a visitor to on the way to a page of the file
|
||||
that needs signing in, such as its edit page (`redirect_to`). The visitor can
|
||||
still sign in by opening the sign-in page itself.
|
||||
- the sign-in page, for a visitor who opens a page of the file that needs
|
||||
signing in, such as its edit page (`redirect_to`). The visitor can still sign
|
||||
in by opening the sign-in page itself.
|
||||
|
||||
### A path
|
||||
|
||||
@@ -143,25 +143,30 @@ For such a file, these requests are refused:
|
||||
`process.env.d.ts` does.
|
||||
- A path with a directory named `...` (930100, 930110), such as `.../notes.txt`.
|
||||
|
||||
For such a file, the page of the file, its raw file, its history, its blame and
|
||||
its edit page are refused. The directory that holds it lists it, and a clone
|
||||
carries it.
|
||||
For such a file, these are refused:
|
||||
|
||||
- the page of the file;
|
||||
- its raw file;
|
||||
- its history and its blame;
|
||||
- its edit page.
|
||||
|
||||
The directory that holds it lists it, and a clone carries it.
|
||||
|
||||
### A container image push that reuses a layer
|
||||
|
||||
A push can reuse a layer of an image docker has pushed to that gitea before.
|
||||
docker then asks gitea to take the layer from that image, naming it in the query
|
||||
parameter `from`, which 932260 checks. The request is refused when the image's
|
||||
owner starts with an entry on the list of commands. So is one whose name after
|
||||
the owner does. Examples are `owner/python3-app`, `owner/docker-base`, and any
|
||||
image of an owner named `ansible` or `docker-team`.
|
||||
owner starts with an entry on the list of commands. It is refused too when the
|
||||
image's name after the owner starts with one. Examples are `owner/python3-app`,
|
||||
`owner/docker-base`, and any image of an owner named `ansible` or `docker-team`.
|
||||
|
||||
What happens next depends on docker's image store. A docker that keeps its
|
||||
images in containerd's image store fails the push, and fails each new try the
|
||||
same way. A new install of Docker Engine 29 does this. A docker that keeps them
|
||||
in its own older image store uploads the layer instead. The push then succeeds
|
||||
after one refusal for each layer it reuses, and each of those refusals counts
|
||||
toward the error burst.
|
||||
toward the error burst ("Attack detection" in `SPEC.md`).
|
||||
|
||||
### Artifact uploads from `actions/upload-artifact@v3`
|
||||
|
||||
@@ -169,9 +174,9 @@ This action sends the header `Content-Range`, which the Core Rule Set refuses
|
||||
(920450). The action sends two files at a time, does not retry a `403`, and
|
||||
sends no further file once one is refused. So an upload is refused once or
|
||||
twice, however many files it holds, and the step fails. One upload does not ban
|
||||
the runner. More than 30 such refusals from its address within a minute, as when
|
||||
many jobs upload at once, ban it through the error burst.
|
||||
`actions/upload-artifact@v4` does not send the header.
|
||||
the runner. The error burst ("Attack detection" in `SPEC.md`) bans it after more
|
||||
than 30 such refusals from its address in a minute, as when many jobs upload at
|
||||
once. `actions/upload-artifact@v4` does not send the header.
|
||||
|
||||
## What body inspection refuses
|
||||
|
||||
@@ -193,8 +198,7 @@ Of the requests above, the script sends:
|
||||
code rules", the API's list of its commits;
|
||||
- for `Runtime.java` alone, the commit graph of that file, the hidden lines of
|
||||
its diff, and the API's call for the contents of files that names it;
|
||||
- the sign-in page gitea sends a visitor to on the way to the edit page of
|
||||
`document.write.js`;
|
||||
- the sign-in page for a visitor who opens the edit page of `document.write.js`;
|
||||
- the pages of `java.lang.String.md`,
|
||||
`META-INF/services/org.apache.commons.logging.LogFactory`, `process.env.d.ts`
|
||||
and `.../notes.txt`;
|
||||
|
||||
+3
-2
@@ -31,6 +31,7 @@ is pinned that way.
|
||||
- nixpkgs: the release file `nixexprs.tar.xz` of
|
||||
`nixos-26.05.11045.774debe7a0d1` on `releases.nixos.org`, named with its
|
||||
SHA-256 hash.
|
||||
- `runsvinit`: the archived repository, unchanged since 2015, at tag `v2.0.0`,
|
||||
by commit hash, with a `go.mod` the build writes.
|
||||
- `runsvinit`: the archived repository, unchanged since 2015, at its last commit
|
||||
(`b4b2c78`, eight commits after `v2.0.0`), by commit hash, with a `go.mod` the
|
||||
build writes.
|
||||
- The Go image that builds `smallwebwaf`: by digest.
|
||||
|
||||
+3
-5
@@ -1,10 +1,8 @@
|
||||
# The metrics
|
||||
|
||||
`GET /_smallwebwaf/metrics` answers in the Prometheus text format. The
|
||||
requirements are under "Metrics endpoint" in [`SPEC.md`](../SPEC.md); this file
|
||||
lists the metrics. Every metric carries the label `instance`, set to
|
||||
`SWWAF_INSTANCE_NAME`; Prometheus keeps it as `exported_instance` unless the
|
||||
scrape sets `honor_labels: true`. No metric carries a client's address.
|
||||
The metrics `GET /_smallwebwaf/metrics` answers with, as "Metrics endpoint" in
|
||||
[`SPEC.md`](../SPEC.md) describes it. Prometheus keeps the `instance` label as
|
||||
`exported_instance` unless the scrape sets `honor_labels: true`.
|
||||
|
||||
## Traffic
|
||||
|
||||
|
||||
+23
-12
@@ -12,9 +12,13 @@ sent to a syslog server. A field that does not apply to a request is left out.
|
||||
|
||||
## Every line
|
||||
|
||||
Every line has `type` (`request`; the process's own messages have `process`),
|
||||
the standard web log fields, `request_id`, `peer_ip`, `client_group`, `asn`,
|
||||
`as_name`, `country`, `action` and `duration_total`.
|
||||
Every line has:
|
||||
|
||||
- `type`: `request` (the process's own messages have `process`);
|
||||
- the standard web log fields;
|
||||
- `request_id`, `peer_ip` and `client_group`;
|
||||
- `asn`, `as_name` and `country`;
|
||||
- `action` and `duration_total`.
|
||||
|
||||
## Standard web log fields
|
||||
|
||||
@@ -28,7 +32,7 @@ the standard web log fields, `request_id`, `peer_ip`, `client_group`, `asn`,
|
||||
## Request detail
|
||||
|
||||
- `request_id`: the `X-Request-ID` a trusted proxy sent, or a new random one of
|
||||
26 letters and digits. It goes to the app in `X-Request-ID`.
|
||||
26 letters and digits.
|
||||
- `peer_ip`: the TCP peer, normally traefik.
|
||||
- `forwarded_for`: the `X-Forwarded-For` header as received.
|
||||
- `client_group`: the client as rate limiting counts it, an IPv4 address as a
|
||||
@@ -73,15 +77,22 @@ the standard web log fields, `request_id`, `peer_ip`, `client_group`, `asn`,
|
||||
rate limits and the setting that lowered it, when one did. `bytes_percent` and
|
||||
`bytes_percent_setting` do the same for the byte limits.
|
||||
- `counts`: the client's totals as rate limiting counts them, this request
|
||||
included. It is left out when rate limiting did not count the request. A count
|
||||
can have a fraction, since each window is counted in two buckets with the
|
||||
earlier one weighted:
|
||||
included. It is left out when rate limiting did not count the request. It
|
||||
holds:
|
||||
- `minute`, `hour` and `day`: requests;
|
||||
- `minute_bytes`, `hour_bytes` and `day_bytes`: bytes.
|
||||
- `limit_hit`: the limit broken: `minute`, `hour` or `day` for a rate limit;
|
||||
`minute_bytes`, `hour_bytes` or `day_bytes` for a byte limit; or
|
||||
`error_burst`. A request whose bytes broke a limit was passed on whole, so its
|
||||
`action` stays `forward`.
|
||||
|
||||
A count can have a fraction (see "Counting method" in
|
||||
[`SPEC.md`](../SPEC.md)).
|
||||
|
||||
- `limit_hit`: the limit broken:
|
||||
- `minute`, `hour` or `day` for a rate limit;
|
||||
- `minute_bytes`, `hour_bytes` or `day_bytes` for a byte limit;
|
||||
- `error_burst`.
|
||||
|
||||
A request whose bytes broke a limit was passed on whole, so its `action`
|
||||
stays `forward`.
|
||||
|
||||
- `rule_ids`: the rule file rules that matched, in order, up to the one that
|
||||
refused.
|
||||
- `waf_score` and `waf_rule_ids`: the Core Rule Set's score and the rules that
|
||||
@@ -91,7 +102,7 @@ the standard web log fields, `request_id`, `peer_ip`, `client_group`, `asn`,
|
||||
- the CrowdSec decision list's URL;
|
||||
- DNS blocklist zones;
|
||||
- `abuseipdb`.
|
||||
- `offence`: the kind of offence recorded, when one was.
|
||||
- `offence`: `limit`, for a request that broke a limit.
|
||||
- `ban_expires`: when the client's ban ends, for a request that made one or was
|
||||
refused under one: a time, or `permanent`.
|
||||
|
||||
|
||||
+17
-18
@@ -2,8 +2,7 @@
|
||||
|
||||
Every setting, its default and the values it takes, in the groups of "Settings"
|
||||
in [`SPEC.md`](../SPEC.md). That section gives the conventions, the settings
|
||||
that take `off`, the `_FILE` form, and what each group does and why. A setting
|
||||
set to a value its entry does not allow stops the start.
|
||||
that take `off`, the `_FILE` form, and what each group does and why.
|
||||
|
||||
## Forms of values
|
||||
|
||||
@@ -27,8 +26,9 @@ set to a value its entry does not allow stops the start.
|
||||
|
||||
- `SWWAF_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app. An `http` or
|
||||
`https` URL with a host and an optional port, and nothing more.
|
||||
- `SWWAF_LISTEN_ADDR` (default `:8080`): where `smallwebwaf` listens, an
|
||||
optional host and a port. The host stays empty.
|
||||
- `SWWAF_LISTEN_ADDR` (default `:8080`): where `smallwebwaf` listens: `:` and a
|
||||
port, such as `:9000`. Leave the host out (see "Ports" in
|
||||
[`SPEC.md`](../SPEC.md)).
|
||||
- `SWWAF_INSTANCE_NAME` (default: the container's host name): the `instance`
|
||||
name in every log line, alert and metric, such as `fsn1app1/gitea`. Valid
|
||||
UTF-8. No control character while `SWWAF_ALERT_NTFY_URL` is set. 1 to 48
|
||||
@@ -42,8 +42,8 @@ set to a value its entry does not allow stops the start.
|
||||
client's group, from 32 to 128.
|
||||
- `SWWAF_MAX_TRACKED_CLIENTS` (default `20000`): the most clients kept, a whole
|
||||
number above zero.
|
||||
- `SWWAF_MAX_BANS` (default `5000`): the most bans `smallwebwaf` made that are
|
||||
kept, a whole number above zero.
|
||||
- `SWWAF_MAX_BANS` (default `5000`): how many of its own bans `smallwebwaf`
|
||||
keeps, a whole number above zero.
|
||||
|
||||
## Tokens
|
||||
|
||||
@@ -90,8 +90,9 @@ set to a value its entry does not allow stops the start.
|
||||
|
||||
## Static lists
|
||||
|
||||
- `SWWAF_ALLOW_NETS` (default empty): netblocks whose clients are refused only
|
||||
for a size or time limit or a missing or wrong token, such as your monitoring.
|
||||
- `SWWAF_ALLOW_NETS` (default empty): netblocks you trust, such as your
|
||||
monitoring. Their clients are refused only for a size or time limit or a
|
||||
missing or wrong token.
|
||||
- `SWWAF_RATE_LIMIT_EXEMPT_NETS` (default empty): netblocks whose clients are
|
||||
exempt from rate limiting and the byte limits.
|
||||
- `SWWAF_DENY_NETS` (default empty): netblocks whose clients are always refused.
|
||||
@@ -150,7 +151,7 @@ set to a value its entry does not allow stops the start.
|
||||
such as `cn,ru,kp`.
|
||||
- `SWWAF_EXCLUSIVELY_ALLOWED_COUNTRIES` (default empty): when set, the only
|
||||
countries whose clients get through, such as `us,de`. A country on both lists
|
||||
is refused.
|
||||
stops the start.
|
||||
|
||||
## Biased thresholds
|
||||
|
||||
@@ -164,8 +165,8 @@ set to a value its entry does not allow stops the start.
|
||||
- `SWWAF_UNKNOWN_LIMIT_PERCENT` (default `100`): the percentage for a client the
|
||||
lookup cannot place.
|
||||
- `SWWAF_ASN_LIMIT_PERCENT_URL` (default unset): the `http` or `https` URL of a
|
||||
text file of `AS<number>:<percent>` lines, one to a line. A URL that is also
|
||||
in `SWWAF_BLOCKLIST_URLS` is refused.
|
||||
text file with one AS number and percentage on each line, such as
|
||||
`AS64496:50`. A URL that is also in `SWWAF_BLOCKLIST_URLS` is refused.
|
||||
|
||||
## Attack detection
|
||||
|
||||
@@ -260,8 +261,8 @@ set to a value its entry does not allow stops the start.
|
||||
`ban,permanent_ban,waf_block,anomaly,reputation_hit,source_failure,file_error`):
|
||||
the event types alerts are sent for, from those in [`alerts.md`](alerts.md)
|
||||
but `summary`. Any other name is refused.
|
||||
- `SWWAF_ALERT_COOLDOWN` (default `15m`): how long a repeat of an alert is held
|
||||
back. A duration or `off`.
|
||||
- `SWWAF_ALERT_COOLDOWN` (default `15m`): how long after an alert is sent its
|
||||
repeats are held back. A duration or `off`.
|
||||
- `SWWAF_ALERT_MAX_PER_HOUR` (default `60`): the most alerts sent in an hour. A
|
||||
whole number above zero, or `off`.
|
||||
|
||||
@@ -294,10 +295,8 @@ as `REQUESTS_PER_MINUTE`:
|
||||
|
||||
## Settings given as files
|
||||
|
||||
Add `_FILE` to a setting's name to read its value from a file:
|
||||
`SWWAF_METRICS_TOKEN_FILE` names the file that holds `SWWAF_METRICS_TOKEN`. To
|
||||
keep a token from the app, make the file on the host, owned by uid 65532 with
|
||||
mode `0400`:
|
||||
To give a token as a file, as "Tokens" under "Deployment" in
|
||||
[`SPEC.md`](../SPEC.md) describes, make the file on the host:
|
||||
|
||||
```sh
|
||||
mkdir -p /srv/app/tokens
|
||||
@@ -306,7 +305,7 @@ chown 65532:65532 /srv/app/tokens/metrics
|
||||
chmod 0400 /srv/app/tokens/metrics
|
||||
```
|
||||
|
||||
Mount its directory into the container read-only, and name the file:
|
||||
Then mount its directory into the container read-only, and name the file:
|
||||
|
||||
```sh
|
||||
docker run \
|
||||
|
||||
+19
-15
@@ -15,8 +15,8 @@ those `smallwebwaf` made. Per entry:
|
||||
- `lifted`: when an admin lifted it, if one did;
|
||||
- `notes`: the notes below.
|
||||
|
||||
To ban a netblock, add an entry with its `netblock`, `start` and `expires`.
|
||||
`reason`, `notes` and `cause` may be left out; the cause is then `admin`:
|
||||
An entry an admin adds needs `netblock`, `start` and `expires`; `reason`,
|
||||
`notes` and `cause` may be left out, and the cause is then `admin`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -32,20 +32,23 @@ To ban a netblock, add an entry with its `netblock`, `start` and `expires`.
|
||||
}
|
||||
```
|
||||
|
||||
To lift a ban, add `"lifted"` with the time you lift it, such as
|
||||
`"lifted": "2026-10-06T13:00:00Z"`. To keep a ban `smallwebwaf` made, set its
|
||||
`cause` to `admin`. To forget a ban, delete its entry.
|
||||
|
||||
The notes:
|
||||
"Bans" in [`SPEC.md`](../SPEC.md) says how an edit lifts, keeps or forgets a
|
||||
ban. The notes:
|
||||
|
||||
- `asn`, `as_name` and `country`: the client's, added when the lookup answers
|
||||
(empty when lookups are off);
|
||||
- what was broken: the rule id and target that matched, or the trap path, or the
|
||||
limit, its window and the count reached;
|
||||
- the client's percentage of the limit, with the setting that gave it;
|
||||
- the reputation sources the client is on;
|
||||
- `request`: the request that caused the ban: time, method, host, path with its
|
||||
query string, status and user agent, each text cut to 256 bytes;
|
||||
- for a broken limit, `kind` (`requests`, `bytes` or `refusals`), `limit`,
|
||||
`window` and `count`: what the limit was on, the limit, its window and the
|
||||
count reached;
|
||||
- `limit_percent` and `limit_percent_setting`: the client's percentage of that
|
||||
limit and the setting that gave it, when a setting lowered it;
|
||||
- for a clear sign of attack, `rule_id` and `target`, or `trap_path`;
|
||||
- `reputation`: the sources the client was on, each with its `source` and, for
|
||||
AbuseIPDB, its `score`;
|
||||
- `request`: the request that caused the ban, each text cut to 256 bytes:
|
||||
- `time`, `method` and `host`;
|
||||
- `path`, with its query string;
|
||||
- `status` and `user_agent`;
|
||||
- `requests` and `refused`: the netblock's requests since it was first seen, and
|
||||
how many this ban has refused so far, kept up to date while the ban lasts;
|
||||
- `earlier_bans`: how many earlier bans the netblock had, by cause.
|
||||
@@ -93,8 +96,9 @@ GeoJS answers, one per line:
|
||||
`SWWAF_MAX_TRACKED_CLIENTS`. Written every 15 minutes, that is under 2 GiB of
|
||||
disk writes a day.
|
||||
- `bans.json`: about 1.2 KiB per ban, at most about 2.5 KiB, so about 6 MiB at
|
||||
the default `SWWAF_MAX_BANS`. With a full file, a hundred new bans a day come
|
||||
to about 600 MiB of writes.
|
||||
the default `SWWAF_MAX_BANS`. Written every 15 minutes, a full file comes to
|
||||
about 600 MiB of writes a day, and a hundred new bans a day add about 600 MiB
|
||||
more.
|
||||
- `lookups.json`: about 150 bytes per answer, under 1.5 GiB of writes a day when
|
||||
full.
|
||||
- `reputation.json` and `alerts.json`: usually a few MiB or less.
|
||||
|
||||
Reference in New Issue
Block a user