Rename the settings whose names do not say what they control (closes #234)
check / check (push) Waiting to run
check / check (push) Waiting to run
Applies the setting renames of the naming audit under the SWW_WAF_ and SWW_RPROXY_ prefixes, with sneak's names for the IP reputation cache time and the two time limits, which now take milliseconds. The rproxy log field default_disposition becomes waf_backend_no_answer, and config.Config and config.FromEnvironment become config.WAF and config.WAFFromEnvironment. Go fields, test names and prose follow. No aliases; nothing reads the old names. Model: opus-5-5
This commit is contained in:
1 parent
3304beca46
commit
4d4ae61abf
100 files changed
+2261
-2019
No files matched your search
+69
-62
@@ -12,6 +12,8 @@ chooses between the two (see "The image's command" below).
|
||||
|
||||
- A duration is Go's syntax, with `d` for days: `90s`, `15m`, `24h`, `7d`. Zero
|
||||
and negative durations are refused.
|
||||
- A time in milliseconds is a whole number above zero, such as `2000`. Its
|
||||
setting's name ends in `_MS`.
|
||||
- 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`.
|
||||
@@ -55,9 +57,9 @@ chooses between the two (see "The image's command" below).
|
||||
- `SWW_WAF_STATE_DIR` (default `/var/lib/sww`): the directory of the state
|
||||
files, an absolute path that can be written. The image's `run` script makes
|
||||
it.
|
||||
- `SWW_WAF_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
||||
- `SWW_WAF_BANS_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
||||
written after a ban is made, lifted or made permanent. A duration.
|
||||
- `SWW_WAF_STATE_COUNTER_INTERVAL` (default `15m`): how often every state and
|
||||
- `SWW_WAF_STATE_WRITE_INTERVAL` (default `15m`): how often every state and
|
||||
cache file is written. A duration.
|
||||
- `SWW_WAF_CACHE_DIR` (default `/var/cache/sww`): the directory of the cache
|
||||
files, an absolute path that can be written. The image's `run` script makes
|
||||
@@ -77,8 +79,8 @@ chooses between the two (see "The image's command" below).
|
||||
- `SWW_WAF_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.
|
||||
- `SWW_WAF_LOG_REMOTE_BUFFER` (default `10000`): the most lines held while they
|
||||
wait to be sent, a whole number above zero.
|
||||
- `SWW_WAF_LOG_REMOTE_BUFFER_LINES` (default `10000`): the most lines held while
|
||||
they wait to be sent, a whole number above zero.
|
||||
- `SWW_WAF_LOG_REMOTE_FACILITY` (default `local0`): the syslog facility: `kern`,
|
||||
`user`, `mail`, `daemon`, `auth`, `syslog`, `lpr`, `news`, `uucp`, `cron`,
|
||||
`authpriv`, `ftp`, or `local0` to `local7`.
|
||||
@@ -87,8 +89,9 @@ chooses between the two (see "The image's command" below).
|
||||
|
||||
## Metrics
|
||||
|
||||
- `SWW_WAF_METRICS_TOP_N` (default `50`): how many AS numbers and how many
|
||||
countries get series of their own. A whole number above zero.
|
||||
- `SWW_WAF_METRICS_BUSIEST_COUNTRIES_AND_ASNS` (default `50`): how many AS
|
||||
numbers and how many countries get series of their own. A whole number above
|
||||
zero.
|
||||
|
||||
## Static lists
|
||||
|
||||
@@ -134,10 +137,10 @@ cut off; the client is banned.
|
||||
- `SWW_WAF_BYTES_LIMIT_PER_MINUTE` (default `off`),
|
||||
`SWW_WAF_BYTES_LIMIT_PER_HOUR` (default `50G`) and
|
||||
`SWW_WAF_BYTES_LIMIT_PER_DAY` (default `100G`): the most bytes counted for a
|
||||
client in each window, a size or `off`. `SWW_WAF_BYTES_COUNT` says which bytes
|
||||
count: response bodies, request bodies or both. The request that passes the
|
||||
limit is not cut off, and the client is banned when its response ends.
|
||||
- `SWW_WAF_BYTES_COUNT` (default `both`): what the byte limits and the byte
|
||||
client in each window, a size or `off`. `SWW_WAF_BYTES_COUNTED` says which
|
||||
bytes count: response bodies, request bodies or both. The request that passes
|
||||
the limit is not cut off, and the client is banned when its response ends.
|
||||
- `SWW_WAF_BYTES_COUNTED` (default `both`): what the byte limits and the byte
|
||||
anomaly thresholds count: `response`, the app's response bodies; `request`,
|
||||
the visitors' request bodies; or `both`. What the visitor sent over a
|
||||
WebSocket counts as request bytes, and what the app sent as response bytes.
|
||||
@@ -151,13 +154,13 @@ cut off; the client is banned.
|
||||
- `SWW_WAF_TAG_DENY` or `SWW_WAF_TAG_LIMIT_PERCENT` naming a `country=` tag,
|
||||
or an `asn=` tag while `SWW_WAF_ROUTEWATCH_URL` is unset;
|
||||
- the two byte percentage lists and `SWW_WAF_ASN_LIMIT_PERCENT_URL`;
|
||||
- `SWW_WAF_UNKNOWN_LIMIT_PERCENT` below `100`;
|
||||
- `SWW_WAF_UNKNOWN_COUNTRY_LIMIT_PERCENT` below `100`;
|
||||
- an anomaly threshold per AS number.
|
||||
- `SWW_WAF_LOOKUP_DB_PATH` (default empty): the IPinfo Lite database file, in
|
||||
its `.mmdb` form, for `SWW_WAF_LOOKUP_SOURCE=file`.
|
||||
- `SWW_WAF_LOOKUP_TIMEOUT` (default `800ms`): 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`.
|
||||
- `SWW_WAF_ASN_AND_COUNTRY_LOOKUP_TIMEOUT_MS` (default `800`): how long a
|
||||
request waits for its client's first answer from GeoJS, and how long a request
|
||||
to GeoJS may take. A time in milliseconds; never `off`.
|
||||
- `SWW_WAF_ADD_LOOKUP_HEADERS` (default `false`): `true` has `rproxy` pass the
|
||||
app the client's AS number in `X-Client-ASN` and its country in
|
||||
`X-Client-Country`.
|
||||
@@ -206,22 +209,23 @@ tag that no request can get stops the start. A request can get only these:
|
||||
- a `dnsbl=` tag of a zone in `SWW_WAF_DNSBL_ZONES`, in lower case, with a key
|
||||
masked as the `reputation` field shows it;
|
||||
- `abuseipdb`, while `SWW_WAF_ABUSEIPDB_KEY` is set;
|
||||
- `exploitsignature`, in `SWW_WAF_TAG_DENY` only, while `SWW_WAF_RULES_ENABLED`
|
||||
is `true`, or while neither `SWW_WAF_CORE_RULE_SET_MODE` nor
|
||||
`SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD` is `off`.
|
||||
- `exploitsignature`, in `SWW_WAF_TAG_DENY` only, while
|
||||
`SWW_WAF_RULE_FILES_ENABLED` is `true`, or while neither
|
||||
`SWW_WAF_CORE_RULE_SET_MODE` nor `SWW_WAF_CORE_RULE_SET_SCORE_THRESHOLD` is
|
||||
`off`.
|
||||
|
||||
`crowdsec` stops the start in both settings, because a CrowdSec decision refuses
|
||||
the request first.
|
||||
|
||||
## Biased thresholds
|
||||
|
||||
- `SWW_WAF_ASN_BYTES_PERCENT` and `SWW_WAF_COUNTRY_BYTES_PERCENT` (default
|
||||
empty): a percentage of the byte limits alone, for the AS numbers or countries
|
||||
listed, such as `AS14061:50` or `cn:25`. It takes the place of the percentage
|
||||
`SWW_WAF_TAG_LIMIT_PERCENT` gives their `asn=` or `country=` tag. An AS number
|
||||
or country listed twice is refused.
|
||||
- `SWW_WAF_UNKNOWN_LIMIT_PERCENT` (default `100`): the percentage for a client
|
||||
the lookup cannot place.
|
||||
- `SWW_WAF_ASN_BYTES_LIMIT_PERCENT` and `SWW_WAF_COUNTRY_BYTES_LIMIT_PERCENT`
|
||||
(default empty): a percentage of the byte limits alone, for the AS numbers or
|
||||
countries listed, such as `AS14061:50` or `cn:25`. It takes the place of the
|
||||
percentage `SWW_WAF_TAG_LIMIT_PERCENT` gives their `asn=` or `country=` tag.
|
||||
An AS number or country listed twice is refused.
|
||||
- `SWW_WAF_UNKNOWN_COUNTRY_LIMIT_PERCENT` (default `100`): the percentage for a
|
||||
client the lookup cannot place.
|
||||
- `SWW_WAF_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`. Each entry counts like an `asn=` tag in
|
||||
@@ -230,15 +234,15 @@ the request first.
|
||||
|
||||
## Attack detection
|
||||
|
||||
- `SWW_WAF_RULES_DIR` (default `/etc/sww/rules.d`): the directory of the rule
|
||||
files.
|
||||
- `SWW_WAF_RULES_ENABLED` (default `true`): `false` reads no rule file.
|
||||
- `SWW_WAF_RULE_FILES_DIR` (default `/etc/sww/rules.d`): the directory of the
|
||||
rule files.
|
||||
- `SWW_WAF_RULE_FILES_ENABLED` (default `true`): `false` reads no rule file.
|
||||
- `SWW_WAF_TRAP_PATHS` (default empty): paths only scanners ask for, such as
|
||||
`/wp-login.php,/xmlrpc.php`. Each starts with `/` and holds no `?`.
|
||||
- `SWW_WAF_CORE_RULE_SET_MODE` (default `block`): `off`, `detect` or `block`.
|
||||
- `SWW_WAF_CORE_RULE_SET_PARANOIA_LEVEL` (default `1`): the Core Rule Set's
|
||||
paranoia level, from 1 to 4.
|
||||
- `SWW_WAF_CORE_RULE_SET_ANOMALY_THRESHOLD` (default `5`): the score at which a
|
||||
- `SWW_WAF_CORE_RULE_SET_SCORE_THRESHOLD` (default `5`): the score at which a
|
||||
request is a match. A whole number above zero, or `off`.
|
||||
- `SWW_WAF_CORE_RULE_SET_DISABLED_RULES` (default
|
||||
`920340,920420,920440,920640,930130,930140`): the ids of Core Rule Set rules
|
||||
@@ -247,10 +251,10 @@ the request first.
|
||||
`smallwebwaf`'s own.
|
||||
- `SWW_WAF_CORE_RULE_SET_EXEMPT_PATHS` (default empty): path prefixes the Core
|
||||
Rule Set does not inspect.
|
||||
- `SWW_WAF_CORE_RULE_SET_BODY_LIMIT` (default `off`): `off`, or how much of a
|
||||
request body the Core Rule Set reads, a size of at most `64K`. A question
|
||||
carries no more of a body than 64 KiB, and the Core Rule Set reads at most 64
|
||||
KiB less one byte of it, whatever the value (see "The answer" in
|
||||
- `SWW_WAF_CORE_RULE_SET_BODY_INSPECTION_SIZE` (default `off`): `off`, or how
|
||||
much of a request body the Core Rule Set reads, a size of at most `64K`. A
|
||||
question carries no more of a body than 64 KiB, and the Core Rule Set reads at
|
||||
most 64 KiB less one byte of it, whatever the value (see "The answer" in
|
||||
[`SPEC.md`](../SPEC.md)).
|
||||
- `SWW_WAF_CORE_RULE_SET_EXCLUSIONS_FILE` (default unset): a file of Core Rule
|
||||
Set exclusions, written as Coraza directives. It is loaded before the Core
|
||||
@@ -288,9 +292,10 @@ the request first.
|
||||
- a hostname listed twice;
|
||||
- an app listed twice for one hostname;
|
||||
- an entry without a colon.
|
||||
- `SWW_WAF_ERROR_BURST_THRESHOLD` (default `30`): the most refusals a client may
|
||||
get in a minute from a rule file, a trap path or the Core Rule Set, a count or
|
||||
`off`. The next one bans the client (see "Attack detection" in `SPEC.md`).
|
||||
- `SWW_WAF_REFUSALS_LIMIT_PER_MINUTE` (default `30`): the most refusals a client
|
||||
may get in a minute from a rule file, a trap path or the Core Rule Set, a
|
||||
count or `off`. The next one bans the client (see "Attack detection" in
|
||||
`SPEC.md`).
|
||||
|
||||
## Ban lengths, response and scope
|
||||
|
||||
@@ -299,8 +304,8 @@ the request first.
|
||||
A duration.
|
||||
- `SWW_WAF_LIMIT_BAN_REPEAT_WINDOW` (default `24h`): the time after a ban ends
|
||||
within which breaking a limit again lengthens the next ban. A duration.
|
||||
- `SWW_WAF_MAX_BAN_DURATION` (default `7d`): the longest ban for a broken limit;
|
||||
one that would be longer is permanent. A duration.
|
||||
- `SWW_WAF_LIMIT_BAN_PERMANENT_ABOVE` (default `7d`): a ban for a broken limit
|
||||
that would be longer than this is permanent instead. A duration.
|
||||
- `SWW_WAF_ATTACK_BAN_DURATION` (default `7d`): the ban for a first clear sign
|
||||
of attack. A duration.
|
||||
- `SWW_WAF_BAN_SCOPE_V4_PREFIX` (default `32`): how much a ban on an IPv4 client
|
||||
@@ -336,12 +341,12 @@ the request first.
|
||||
- `SWW_WAF_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.
|
||||
- `SWW_WAF_REPUTATION_ACTION` (default `limit:25`): `deny`, `limit:<percent>` or
|
||||
`log`, for DNS blocklist and AbuseIPDB hits.
|
||||
- `SWW_WAF_REPUTATION_CACHE_TTL` (default `24h`): how long a zone's verdict or
|
||||
AbuseIPDB's score is used. A duration.
|
||||
- `SWW_WAF_REPUTATION_TIMEOUT` (default `2s`): how long a query to a zone or a
|
||||
check with AbuseIPDB may take. A duration.
|
||||
- `SWW_WAF_DNSBL_ABUSEIPDB_ACTION` (default `limit:25`): `deny`,
|
||||
`limit:<percent>` or `log`, for DNS blocklist and AbuseIPDB hits.
|
||||
- `SWW_WAF_IP_REPUTATION_CACHE_TTL` (default `24h`): how long a zone's verdict
|
||||
or AbuseIPDB's score is used. A duration.
|
||||
- `SWW_WAF_DNSBL_ABUSEIPDB_TIMEOUT_MS` (default `2000`): how long a query to a
|
||||
zone or a check with AbuseIPDB may take. A time in milliseconds.
|
||||
|
||||
## Alerting
|
||||
|
||||
@@ -369,7 +374,7 @@ the request first.
|
||||
## Anomaly thresholds
|
||||
|
||||
Each scope has four thresholds: the most requests and the most body bytes
|
||||
counted in a minute and in an hour. The bytes are those `SWW_WAF_BYTES_COUNT`
|
||||
counted in a minute and in an hour. The bytes are those `SWW_WAF_BYTES_COUNTED`
|
||||
names. Requests are counts, bytes are sizes. Each is `off` by default. The four
|
||||
thresholds per client are:
|
||||
|
||||
@@ -389,9 +394,10 @@ as `REQUESTS_PER_MINUTE`:
|
||||
client.
|
||||
- `SWW_WAF_ANOMALY_ASN_...`: per AS number.
|
||||
- `SWW_WAF_ANOMALY_TOTAL_...`: the whole service.
|
||||
- `SWW_WAF_WATCH_...`: each netblock in `SWW_WAF_WATCH_NETS`, as a whole.
|
||||
`SWW_WAF_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
|
||||
- `SWW_WAF_ANOMALY_WATCHED_NET_...`: each netblock in
|
||||
`SWW_WAF_ANOMALY_WATCHED_NETS`, as a whole. `SWW_WAF_ANOMALY_WATCHED_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
|
||||
@@ -435,10 +441,11 @@ A few limits are fixed rather than settings:
|
||||
|
||||
## `waf`'s answer and `rproxy`'s wait
|
||||
|
||||
`SWW_WAF_LOOKUP_TIMEOUT` is the longest a question waits on an outside source.
|
||||
Keep it well under `rproxy`'s `SWW_RPROXY_TIMEOUT_MS`, as the default is. No
|
||||
question waits for `SWW_WAF_REPUTATION_TIMEOUT`, since the DNS blocklists and
|
||||
AbuseIPDB are asked in the background (see "Answering in time" under "`waf`" in
|
||||
`SWW_WAF_ASN_AND_COUNTRY_LOOKUP_TIMEOUT_MS` is the longest a question waits on
|
||||
an outside source. Keep it well under `rproxy`'s
|
||||
`SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS`, as the default is. No question waits for
|
||||
`SWW_WAF_DNSBL_ABUSEIPDB_TIMEOUT_MS`, since the DNS blocklists and AbuseIPDB are
|
||||
asked in the background (see "Answering in time" under "`waf`" in
|
||||
[`SPEC.md`](../SPEC.md)).
|
||||
|
||||
## `rproxy`
|
||||
@@ -447,18 +454,17 @@ AbuseIPDB are asked in the background (see "Answering in time" under "`waf`" in
|
||||
start, and an invalid value stops the start. Any can be given as a file, as a
|
||||
`SWW_WAF_` setting can. "`rproxy`" in [`SPEC.md`](../SPEC.md) says what they do.
|
||||
|
||||
A time here is a whole number of milliseconds above zero, such as `2000`.
|
||||
|
||||
- `SWW_RPROXY_WAF_BACKEND` (required, no default): `waf`'s URL. An `http` or
|
||||
`https` URL with a host and an optional port, and nothing more. `rproxy`
|
||||
speaks HTTP/1.1 to it.
|
||||
- `SWW_RPROXY_TIMEOUT_MS` (default `2000`): how long `rproxy` waits for `waf`'s
|
||||
answer, to a question and to a report. A time; never `off`.
|
||||
- `SWW_RPROXY_DEFAULT_DISPOSITION` (default `allow`): what is done with a
|
||||
request when `waf` cannot be connected to, does not answer at all, or does not
|
||||
answer within `SWW_RPROXY_TIMEOUT_MS`. `allow` passes it to the app, and
|
||||
`deny` answers `503`. It does not apply to an answer `waf` gives, such as an
|
||||
error.
|
||||
- `SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS` (default `2000`): how long `rproxy` waits
|
||||
for `waf`'s answer, to a question and to a report. A time in milliseconds;
|
||||
never `off`.
|
||||
- `SWW_RPROXY_WAF_BACKEND_NO_ANSWER_DISPOSITION` (default `allow`): what is done
|
||||
with a request when `waf` cannot be connected to, does not answer at all, or
|
||||
does not answer within `SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS`. `allow` passes it
|
||||
to the app, and `deny` answers `503`. It does not apply to an answer `waf`
|
||||
gives, such as an error.
|
||||
- `SWW_RPROXY_MAX_REQUEST_SIZE` (default `100M`): the largest request body. A
|
||||
size or `off`.
|
||||
- `SWW_RPROXY_MAX_RESPONSE_SIZE` (default `1G`): the largest response body. A
|
||||
@@ -466,11 +472,12 @@ A time here is a whole number of milliseconds above zero, such as `2000`.
|
||||
- `SWW_RPROXY_MAX_REQUEST_TIME_MS` (default `60000`): how long the visitor may
|
||||
take to send its request line and headers. It then also bounds, from the end
|
||||
of the headers, the time until the app has been sent the whole request. A time
|
||||
or `off`.
|
||||
in milliseconds or `off`.
|
||||
- `SWW_RPROXY_MAX_RESPONSE_TIME_MS` (default `1800000`): how long the answer may
|
||||
take, from the end of the request to its last byte reaching the visitor. An
|
||||
answer `rproxy` gives itself always has at least 10 seconds to be sent, and so
|
||||
do the status and headers of the app's answer. A time or `off`.
|
||||
do the status and headers of the app's answer. A time in milliseconds or
|
||||
`off`.
|
||||
- `SWW_RPROXY_LISTEN_ADDR` (default `:8080`): where `rproxy` listens, such as
|
||||
`:9000`.
|
||||
- `SWW_RPROXY_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app. An
|
||||
|
||||
Reference in new issue
Block a user