check / check (push) Waiting to run
- Engine error handling dropped as not built; unknown country and AS number each on its own; observe mode makes no ban of its own. - README no longer restates the request steps, the refusal answers or the design; its step list uses the spec's numbers. - Repeats, misreadable sentences, late verbs and long sentences reworded as the review asks. Model: fable-5-1
331 lines
16 KiB
Markdown
331 lines
16 KiB
Markdown
# Settings
|
|
|
|
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.
|
|
|
|
## Forms of values
|
|
|
|
- A duration is Go's syntax, with `d` for days: `90s`, `15m`, `24h`, `7d`. Zero
|
|
and negative durations are refused.
|
|
- A size is a number of bytes with an optional `K`, `M` or `G`, which are powers
|
|
of 1024, so `1K` is 1024 bytes. Examples: `512K`, `100M`, `5G`.
|
|
- A count is a whole number of requests, such as `1000`.
|
|
- A list is comma separated, with spaces around items ignored. An empty item is
|
|
refused.
|
|
- A netblock is an address and a prefix length, such as `10.0.0.0/8`. A bare
|
|
address stands for itself alone.
|
|
- A country is a two-letter code of ISO 3166-1, in either case: `de` and `DE`
|
|
are the same. `xk` stands for Kosovo. A code that is not a country is refused,
|
|
such as `nk` (North Korea is `kp`) or the withdrawn `su`.
|
|
- An AS number is `AS` and the number, in either case, such as `AS64496`.
|
|
- A percentage is a whole number from 0 to 100.
|
|
- A path prefix starts with `/`, such as `/assets/`.
|
|
|
|
## Core
|
|
|
|
- `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: `:` 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
|
|
printable ASCII characters without a space while `SWWAF_LOG_REMOTE_URL` is set
|
|
and `SWWAF_LOG_REMOTE_APP_NAME` is not.
|
|
- `SWWAF_MODE` (default `enforce`): `enforce` or `observe`.
|
|
- `SWWAF_TRUSTED_PROXIES` (default `10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`):
|
|
the netblocks whose `X-Forwarded-For` is believed. Set but empty, it trusts
|
|
nothing.
|
|
- `SWWAF_IPV6_GROUP_PREFIX` (default `64`): the prefix length of an IPv6
|
|
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`): how many of its own bans `smallwebwaf`
|
|
keeps, a whole number above zero.
|
|
|
|
## Tokens
|
|
|
|
- `SWWAF_ADMIN_TOKEN` (default unset): the token for the ban endpoints and
|
|
`/_smallwebwaf/clients/<ip>`. At least 32 characters.
|
|
- `SWWAF_METRICS_TOKEN` (default unset): the token for `/_smallwebwaf/metrics`.
|
|
At least 32 characters.
|
|
|
|
## State files
|
|
|
|
- `SWWAF_STATE_DIR` (default `/var/lib/smallwebwaf`): the directory of the state
|
|
files, an absolute path that exists and can be written.
|
|
- `SWWAF_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
|
written after a ban is made, lifted or made permanent. A duration.
|
|
- `SWWAF_STATE_COUNTER_INTERVAL` (default `15m`): how often every state file is
|
|
written. A duration.
|
|
|
|
## Logging
|
|
|
|
- `SWWAF_LOG_LEVEL` (default `info`): the least severe of `smallwebwaf`'s own
|
|
messages that are written: `debug`, `info`, `warn` or `error`.
|
|
- `SWWAF_LOG_REQUEST_HEADERS` (default
|
|
`accept,accept-language,accept-encoding,content-type,origin,range`): the
|
|
request headers recorded in the log line, in either case. `Host` and
|
|
`Transfer-Encoding` are refused; the host is the field `host`.
|
|
- `SWWAF_LOG_REMOTE_URL` (default unset): a syslog server that also gets every
|
|
line written to stdout: `syslog+udp://`, `syslog+tcp://` or `syslog+tls://`,
|
|
each with a host and a port and nothing more.
|
|
- `SWWAF_LOG_REMOTE_TLS_CA_FILE` (default unset): a file of PEM certificates
|
|
that a `syslog+tls` server's certificate must chain to, instead of the host's
|
|
own. A file that cannot be read, or holds no certificate, is refused.
|
|
- `SWWAF_LOG_REMOTE_BUFFER` (default `10000`): the most lines held while they
|
|
wait to be sent, a whole number above zero.
|
|
- `SWWAF_LOG_REMOTE_FACILITY` (default `local0`): the syslog facility: `kern`,
|
|
`user`, `mail`, `daemon`, `auth`, `syslog`, `lpr`, `news`, `uucp`, `cron`,
|
|
`authpriv`, `ftp`, or `local0` to `local7`.
|
|
- `SWWAF_LOG_REMOTE_APP_NAME` (default: `SWWAF_INSTANCE_NAME`): the app name in
|
|
each syslog record, 1 to 48 printable ASCII characters without a space.
|
|
|
|
## Metrics
|
|
|
|
- `SWWAF_METRICS_TOP_N` (default `50`): how many AS numbers and how many
|
|
countries get series of their own. A whole number above zero.
|
|
|
|
## Static lists
|
|
|
|
- `SWWAF_ALLOW_NETS` (default empty): netblocks you trust, such as your
|
|
monitoring (see step 3 in [`SPEC.md`](../SPEC.md)).
|
|
- `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 refused (see
|
|
step 3 in [`SPEC.md`](../SPEC.md)).
|
|
|
|
## Request rate limits, per client
|
|
|
|
- `SWWAF_RATE_LIMIT_PER_MINUTE` (default `1000`), `SWWAF_RATE_LIMIT_PER_HOUR`
|
|
(default `10000`) and `SWWAF_RATE_LIMIT_PER_DAY` (default `50000`): the most
|
|
requests a client may make in each window. A count or `off`.
|
|
- `SWWAF_RATE_LIMIT_EXEMPT_PATHS` (default empty): path prefixes exempt from
|
|
rate limiting and the byte limits, such as `/assets/`.
|
|
|
|
## Byte limits, per client
|
|
|
|
- `SWWAF_BYTES_LIMIT_PER_MINUTE` (default `10G`), `SWWAF_BYTES_LIMIT_PER_HOUR`
|
|
(default `20G`) and `SWWAF_BYTES_LIMIT_PER_DAY` (default `50G`): the most
|
|
bytes counted for a client in each window. A size or `off`.
|
|
- `SWWAF_BYTES_COUNT` (default `both`): which body bytes the byte limits count:
|
|
`response`, `request` or `both`.
|
|
|
|
## Size and time limits
|
|
|
|
- `SWWAF_CLIENT_REQUEST_TIMEOUT` (default `60s`): how long a client may take to
|
|
send its request line and headers, and then, from the end of the headers, its
|
|
body. A duration or `off`.
|
|
- `SWWAF_CLIENT_REQUEST_HEADER_MAX_BYTES` (default `32K`): the largest request
|
|
line and headers. A size over `4K`; never `off`.
|
|
- `SWWAF_CLIENT_IDLE_TIMEOUT` (default `120s`): how long a kept-open connection
|
|
may wait for its next request before it is closed. A duration or `off`.
|
|
- `SWWAF_CLIENT_RESPONSE_TIMEOUT` (default `30m`): how long the answer may take
|
|
to reach the client, from the end of the request to the last byte. A duration
|
|
or `off`.
|
|
- `SWWAF_UPSTREAM_REQUEST_TIMEOUT` (default `60s`): how long connecting to the
|
|
app and sending it the whole request may take. A duration or `off`.
|
|
- `SWWAF_UPSTREAM_RESPONSE_TIMEOUT` (default `30m`): how long the app may take
|
|
to send its whole answer. A duration or `off`.
|
|
- `SWWAF_REQUEST_MAX_BYTES` (default `100M`): the largest request body. A size
|
|
or `off`.
|
|
- `SWWAF_RESPONSE_MAX_BYTES` (default `5G`): the largest response body. A size
|
|
or `off`.
|
|
|
|
## Lookup of AS number and country
|
|
|
|
- `SWWAF_LOOKUP_SOURCE` (default `geojs`): `geojs`, `file` or `off`. `off` stops
|
|
the start while a setting that needs a lookup is set:
|
|
- the two country lists;
|
|
- `SWWAF_ADD_LOOKUP_HEADERS`;
|
|
- the four biased threshold lists and `SWWAF_ASN_LIMIT_PERCENT_URL`;
|
|
- `SWWAF_UNKNOWN_LIMIT_PERCENT` below `100`;
|
|
- an anomaly threshold per AS number.
|
|
- `SWWAF_LOOKUP_DB_PATH` (default empty): the IPinfo Lite database file, in its
|
|
`.mmdb` form, for `SWWAF_LOOKUP_SOURCE=file`.
|
|
- `SWWAF_LOOKUP_TIMEOUT` (default `1s`): how long a request waits for its
|
|
client's first answer from GeoJS, and how long a request to GeoJS may take. A
|
|
duration; never `off`.
|
|
- `SWWAF_ADD_LOOKUP_HEADERS` (default `false`): `true` passes the app the
|
|
client's AS number in `X-Client-ASN` and its country in `X-Client-Country`.
|
|
|
|
## Country lists
|
|
|
|
- `SWWAF_DENIED_COUNTRIES` (default empty): countries whose clients are refused,
|
|
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
|
|
stops the start.
|
|
|
|
## Biased thresholds
|
|
|
|
- `SWWAF_ASN_LIMIT_PERCENT` (default empty): a list of AS numbers, each with `:`
|
|
and a percentage, such as `AS14061:50,AS16276:50,AS45102:25`. An AS number
|
|
listed twice is refused.
|
|
- `SWWAF_COUNTRY_LIMIT_PERCENT` (default empty): the same by country, such as
|
|
`cn:25,ru:50`.
|
|
- `SWWAF_ASN_BYTES_PERCENT` and `SWWAF_COUNTRY_BYTES_PERCENT` (default empty):
|
|
the same, for the byte limits alone.
|
|
- `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 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
|
|
|
|
- `SWWAF_RULES_DIR` (default `/etc/smallwebwaf/rules.d`): the directory of the
|
|
rule files.
|
|
- `SWWAF_RULES_ENABLED` (default `true`): `false` reads no rule file.
|
|
- `SWWAF_TRAP_PATHS` (default empty): paths only scanners ask for, such as
|
|
`/wp-login.php,/xmlrpc.php`. Each starts with `/` and holds no `?`.
|
|
- `SWWAF_WAF_MODE` (default `block`): `off`, `detect` or `block`.
|
|
- `SWWAF_WAF_PARANOIA_LEVEL` (default `1`): the Core Rule Set's paranoia level,
|
|
from 1 to 4.
|
|
- `SWWAF_WAF_ANOMALY_THRESHOLD` (default `5`): the score at which a request is a
|
|
match. A whole number above zero, or `off`.
|
|
- `SWWAF_WAF_DISABLED_RULES` (default
|
|
`920340,920420,920440,920640,930130,930140`): the ids of Core Rule Set rules
|
|
to switch off. Each a whole number above zero. An id from 900000 to 900999 is
|
|
refused: those are the rules that set the Core Rule Set up, and
|
|
`smallwebwaf`'s own.
|
|
- `SWWAF_WAF_EXEMPT_PATHS` (default empty): path prefixes the Core Rule Set does
|
|
not inspect.
|
|
- `SWWAF_WAF_BODY_LIMIT` (default `off`): `off`, or how much of a request body
|
|
the Core Rule Set reads, a size of at most `1G`.
|
|
- `SWWAF_ERROR_BURST_THRESHOLD` (default `30`): the most refusals of one client
|
|
in a minute (see "Attack detection" in `SPEC.md`). A count or `off`.
|
|
|
|
## Ban lengths, response and scope
|
|
|
|
- `SWWAF_BAN_RESPONSE` (default `403`): `403`, `429` or `close`.
|
|
- `SWWAF_LIMIT_BAN_DURATION` (default `1h`): the ban for a first broken limit. A
|
|
duration.
|
|
- `SWWAF_LIMIT_BAN_REPEAT_WINDOW` (default `24h`): the time after a ban ends
|
|
within which breaking a limit again lengthens the next ban. A duration.
|
|
- `SWWAF_MAX_BAN_DURATION` (default `7d`): the longest ban for a broken limit;
|
|
one that would be longer is permanent. A duration.
|
|
- `SWWAF_ATTACK_BAN_DURATION` (default `7d`): the ban for a first clear sign of
|
|
attack. A duration.
|
|
- `SWWAF_BAN_SCOPE_V4_PREFIX` (default `32`): how much a ban on an IPv4 client
|
|
covers: the prefix length of its netblock, from 0 to 32.
|
|
|
|
## Reputation
|
|
|
|
- `SWWAF_BLOCKLIST_URLS` (default empty): blocklists to fetch, such as
|
|
`https://www.spamhaus.org/drop/drop.txt`. Each an `http` or `https` URL
|
|
without a user or a fragment. A URL listed twice is refused.
|
|
- `SWWAF_BLOCKLIST_REFRESH` (default `24h`): how long a list waits after its
|
|
last try before it is fetched again. A duration of `1h` or more.
|
|
- `SWWAF_BLOCKLIST_ACTION` (default `deny`): `deny`, `limit:<percent>` or `log`.
|
|
- `SWWAF_DNSBL_ZONES` (default empty): the DNS blocklists to ask, such as
|
|
`dnsbl.dronebl.org`. Each a DNS name of at most 189 characters. A Spamhaus
|
|
zone carries its key, as in `<key>.xbl.dq.spamhaus.net`. A zone listed twice
|
|
is refused, whatever its case or key.
|
|
- `SWWAF_DNSBL_RESOLVER` (default unset): the resolver to ask the zones through,
|
|
such as `192.0.2.53` or `[2001:db8::53]:5353`. An IP address with an optional
|
|
port, 53 when none is given. Unset, the host's resolver is used.
|
|
- `SWWAF_ABUSEIPDB_KEY` (default unset): the key of your AbuseIPDB account. A
|
|
control character in it is refused.
|
|
- `SWWAF_ABUSEIPDB_MIN_SCORE` (default `75`): the least abuse confidence score,
|
|
from 0 to 100, that is a hit.
|
|
- `SWWAF_ABUSEIPDB_DAILY_BUDGET` (default `900`): the most checks made in a day,
|
|
a whole number above zero. AbuseIPDB's free accounts may make 1,000.
|
|
- `SWWAF_CROWDSEC_LAPI_URL` (default unset): the local API of a CrowdSec engine
|
|
you run, such as `http://172.17.0.1:8080`. An `http` or `https` URL without a
|
|
user or a fragment; its decision list is at `v1/decisions` under it. Set
|
|
without the key, it is refused. So is a decision list URL that is also in
|
|
`SWWAF_BLOCKLIST_URLS`, or that is `SWWAF_ASN_LIMIT_PERCENT_URL`.
|
|
- `SWWAF_CROWDSEC_LAPI_KEY` (default unset): the key the engine gave for
|
|
`smallwebwaf`, as `cscli bouncers add smallwebwaf` prints it. Set without the
|
|
URL, it is refused.
|
|
- `SWWAF_REPUTATION_ACTION` (default `limit:25`): `deny`, `limit:<percent>` or
|
|
`log`, for DNS blocklist and AbuseIPDB hits.
|
|
- `SWWAF_REPUTATION_CACHE_TTL` (default `24h`): how long a zone's verdict or
|
|
AbuseIPDB's score is used. A duration.
|
|
- `SWWAF_REPUTATION_TIMEOUT` (default `2s`): how long a query to a zone or a
|
|
check with AbuseIPDB may take. A duration.
|
|
|
|
## Alerting
|
|
|
|
- `SWWAF_ALERT_WEBHOOK_URL` (default unset): the webhook that receives each
|
|
alert as a JSON object. An `http` or `https` URL without a user or a fragment.
|
|
- `SWWAF_ALERT_WEBHOOK_HEADERS` (default empty): headers sent with each post,
|
|
such as `Authorization:Bearer 0123456789abcdef`. A list of name, `:` and
|
|
value. A value cannot hold a comma.
|
|
- `SWWAF_ALERT_SLACK_WEBHOOK_URL` (default unset): the Slack incoming webhook
|
|
that receives each alert as a message, checked as the webhook URL is.
|
|
- `SWWAF_ALERT_NTFY_URL` (default unset): the ntfy topic that receives each
|
|
alert, as the topic's full URL, such as `https://ntfy.sh/my-alerts`, checked
|
|
as the webhook URL is.
|
|
- `SWWAF_ALERT_NTFY_TOKEN` (default unset): an ntfy access token. A control
|
|
character in it is refused.
|
|
- `SWWAF_ALERT_EVENTS` (default
|
|
`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 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`.
|
|
|
|
## Anomaly thresholds
|
|
|
|
Each scope has four thresholds: the most requests and the most bytes counted in
|
|
a minute and in an hour. Requests are counts, bytes are sizes. Each is `off` by
|
|
default. The four thresholds per client are:
|
|
|
|
- `SWWAF_ANOMALY_CLIENT_REQUESTS_PER_MINUTE`;
|
|
- `SWWAF_ANOMALY_CLIENT_REQUESTS_PER_HOUR`;
|
|
- `SWWAF_ANOMALY_CLIENT_BYTES_PER_MINUTE`;
|
|
- `SWWAF_ANOMALY_CLIENT_BYTES_PER_HOUR`.
|
|
|
|
The other scopes' names have another prefix before the same four endings, such
|
|
as `REQUESTS_PER_MINUTE`:
|
|
|
|
- `SWWAF_ANOMALY_NET_...`: per netblock around a client. Two settings give the
|
|
netblock's length:
|
|
- `SWWAF_ANOMALY_NET_V4_PREFIX` (default `24`, from 0 to 32) for an IPv4
|
|
client;
|
|
- `SWWAF_ANOMALY_NET_V6_PREFIX` (default `48`, from 0 to 128) for an IPv6
|
|
client.
|
|
- `SWWAF_ANOMALY_ASN_...`: per AS number.
|
|
- `SWWAF_ANOMALY_TOTAL_...`: the whole service.
|
|
- `SWWAF_WATCH_...`: each netblock in `SWWAF_WATCH_NETS`, as a whole.
|
|
`SWWAF_WATCH_NETS` (default empty) is a list of name, `=` and netblock, such
|
|
as `office=203.0.113.0/24,scraper-x=198.51.100.0/22`. An item without `=` or a
|
|
name, or with a bad netblock, is refused. So is a name used twice.
|
|
|
|
## Settings given as files
|
|
|
|
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
|
|
openssl rand -hex 32 > /srv/app/tokens/metrics
|
|
chown 65532:65532 /srv/app/tokens/metrics
|
|
chmod 0400 /srv/app/tokens/metrics
|
|
```
|
|
|
|
Then mount its directory into the container read-only, and name the file:
|
|
|
|
```sh
|
|
docker run \
|
|
-v /srv/app/tokens:/etc/smallwebwaf/tokens:ro \
|
|
-e SWWAF_METRICS_TOKEN_FILE=/etc/smallwebwaf/tokens/metrics \
|
|
...
|
|
```
|
|
|
|
## Fixed limits
|
|
|
|
A few limits are fixed rather than settings:
|
|
|
|
- at most 100,000 GeoJS answers are kept;
|
|
- at most 100,000 DNS blocklist verdicts and 100,000 AbuseIPDB scores are kept;
|
|
- at most 1,000 DNS blocklist queries are under way at once;
|
|
- at most 20,000 anomaly counters are kept;
|
|
- each alert destination's queue holds at most 1,000 alerts.
|