Lower the default request and byte limits (closes #193)
check / check (push) Waiting to run

Requests: 120 a minute, 1,500 an hour, 6,000 a day. Bytes: no minute
limit, 50G an hour, 100G a day. The README, SPEC.md, docs/settings.md
and docs/gitea.md give the new defaults and the reasons for them. The
README examples no longer raise the byte limits for gitea, and the
static-site example sits below the new request defaults.

Model: opus-5-5
This commit is contained in:
2026-11-06 17:55:06 +00:00
parent 6deb9d7581
commit ac4162c5d4
7 changed files with 86 additions and 97 deletions
+16 -22
View File
@@ -26,10 +26,10 @@ It protects against:
- Scrapers that fetch every page of a site, all day. Each client gets a limit on
requests and on bytes per minute, per hour and per day. The defaults leave
room for programmatic use of an API, such as an automation fleet, and catch a
client firing requests as fast as it can within seconds. A client over a limit
is refused and banned: for a while at first, for three times as long at each
repeat, and permanently when it keeps at it.
room for a person reading a site for hours. They catch a scraper that keeps up
one request every 2 seconds within an hour. A client over a limit is refused
and banned: for a while at first, for three times as long at each repeat, and
permanently when it keeps at it.
- Scanners that probe for secrets, such as `/.env` or `/.git/config`. The
default rule file bans such a client at its first probe, and its next request
during the ban makes the ban permanent. Your own rules, or a list of trap
@@ -237,13 +237,13 @@ Every setting the code reads, with its default:
| `SWWAF_ALLOW_NETS` | empty | Netblocks whose clients skip every check, such as your monitoring. |
| `SWWAF_RATE_LIMIT_EXEMPT_NETS` | empty | Netblocks whose clients the request and byte limits neither count nor refuse. |
| `SWWAF_DENY_NETS` | empty | Netblocks whose clients are refused. |
| `SWWAF_RATE_LIMIT_PER_MINUTE` | `500` | The most requests a client may make in a minute, a count or `off`; one more bans it. |
| `SWWAF_RATE_LIMIT_PER_HOUR` | `20000` | The most requests a client may make in an hour, a count or `off`; one more bans it. |
| `SWWAF_RATE_LIMIT_PER_DAY` | `300000` | The most requests a client may make in a day, a count or `off`; one more bans it. |
| `SWWAF_RATE_LIMIT_PER_MINUTE` | `120` | The most requests a client may make in a minute, a count or `off`; one more bans it. |
| `SWWAF_RATE_LIMIT_PER_HOUR` | `1500` | The most requests a client may make in an hour, a count or `off`; one more bans it. |
| `SWWAF_RATE_LIMIT_PER_DAY` | `6000` | The most requests a client may make in a day, a count or `off`; one more bans it. |
| `SWWAF_RATE_LIMIT_EXEMPT_PATHS` | empty | Path prefixes whose requests the request and byte limits neither count nor refuse, such as `/assets/`. |
| `SWWAF_BYTES_LIMIT_PER_MINUTE` | `4G` | The most bytes a client's requests may carry in a minute, a size or `off`; the request that takes a client past any byte limit bans it. |
| `SWWAF_BYTES_LIMIT_PER_HOUR` | `20G` | The most bytes a client's requests may carry in an hour, a size or `off`. |
| `SWWAF_BYTES_LIMIT_PER_DAY` | `200G` | The most bytes a client's requests may carry in a day, a size or `off`. |
| `SWWAF_BYTES_LIMIT_PER_MINUTE` | `off` | The most bytes a client's requests may carry in a minute, a size or `off`; the request that takes a client past any byte limit bans it. |
| `SWWAF_BYTES_LIMIT_PER_HOUR` | `50G` | The most bytes a client's requests may carry in an hour, a size or `off`. |
| `SWWAF_BYTES_LIMIT_PER_DAY` | `100G` | The most bytes a client's requests may carry in a day, a size or `off`. |
| `SWWAF_BYTES_COUNT` | `both` | Which body bytes the byte limits count: `response`, `request` or `both`. |
| `SWWAF_ERROR_BURST_THRESHOLD` | `30` | The most refusals by a rule file, a trap path or the Core Rule Set a client may get in a minute, a count or `off`; one more bans it. |
| `SWWAF_BAN_RESPONSE` | `403` | How a refused client is answered: `403`, `429` or `close`, which drops the connection. |
@@ -408,10 +408,10 @@ services:
SWWAF_RATE_LIMIT_EXEMPT_NETS: 203.0.113.0/24,198.51.100.7
# A netblock that sends nothing wanted.
SWWAF_DENY_NETS: 198.51.100.128/25
# Tighter limits for everyone else: a site with no API.
SWWAF_RATE_LIMIT_PER_MINUTE: "120"
SWWAF_RATE_LIMIT_PER_HOUR: "3000"
SWWAF_RATE_LIMIT_PER_DAY: "30000"
# Tighter limits for everyone else: a small static site.
SWWAF_RATE_LIMIT_PER_MINUTE: "60"
SWWAF_RATE_LIMIT_PER_HOUR: "600"
SWWAF_RATE_LIMIT_PER_DAY: "3000"
# Hosting networks and one country get a share of those limits.
SWWAF_ASN_LIMIT_PERCENT: AS14061:50,AS16276:25
SWWAF_COUNTRY_LIMIT_PERCENT: cn:25
@@ -432,10 +432,9 @@ volumes:
gitea behind traefik, set up for a code forge:
- the upload limits raised, in size and in time;
- the response size limit and the byte limits raised, for clones over 1 GiB;
- the response size limit raised, for clones over 1 GiB;
- the Actions runners exempt from counting;
- the default request limits kept, since they already leave room for API
clients.
- the default request and byte limits kept.
`traefik` is the network traefik is on, made outside this file.
@@ -489,11 +488,6 @@ services:
SWWAF_INSTANCE_NAME: fsn1/servewaf
# The Actions runners ask for work all day; never count them.
SWWAF_RATE_LIMIT_EXEMPT_NETS: 10.0.4.0/24
# Raised with rproxy's response limit, to four times the default
# each, so that one clone of that size breaks no byte limit.
SWWAF_BYTES_LIMIT_PER_MINUTE: 16G
SWWAF_BYTES_LIMIT_PER_HOUR: 80G
SWWAF_BYTES_LIMIT_PER_DAY: 800G
# gitea never serves these; a request for one bans the client.
SWWAF_TRAP_PATHS: /wp-login.php,/xmlrpc.php,/wp-admin/
volumes: