# 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. A setting set to a value its entry does not allow stops the start. ## 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, an optional host and a port. The host stays empty. - `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`): the most bans `smallwebwaf` made that are kept, a whole number above zero. ## Tokens - `SWWAF_ADMIN_TOKEN` (default unset): the token for the ban endpoints and `/_smallwebwaf/clients/`. 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 whose clients are refused only for a size or time limit or a missing or wrong token, such as your monitoring. - `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. ## 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`. - `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 is refused. ## 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 of `AS:` lines, one to a line. 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 for a rule match, a trap path, a Core Rule Set match or a failed token check. 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:` 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 `.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:` 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 a repeat of an alert is 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. Needs a lookup source. - `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 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`: ```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 ``` 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.