SPEC and README: bodies unread by default, one listener, GeoJS by default (closes #6)
Address the third review of the spec update and sneak's two new rulings. By default the Core Rule Set reads the URL, query string and headers but no request body, since a code forge's bodies carry code it takes for attacks; `WAF_BODY_LIMIT` switches body inspection on. `Content-Encoding` is allowed only on unread bodies, and OAuth sign-in from local tools passes. The default rule file bans common probes for secrets, version control, backups and logs at the site root. The spec names the Core Rule Set 4.25.0. One listener answers the sidecar's own endpoints under `/_smallwebwaf/`, behind tokens. GeoJS is the default lookup source. Size suffixes are powers of 1024. Model: opus-5-5
This commit is contained in:
@@ -55,15 +55,16 @@ goes through the candidates one by one.
|
||||
counted by /64 by default.
|
||||
- Size and time limits on requests and responses, both between the client and
|
||||
`smallwebwaf` and between `smallwebwaf` and the app: by default a request may
|
||||
take 60 seconds and 100 MB, a response 30 minutes and 5 GB.
|
||||
take 60 seconds and 100 MiB, a response 30 minutes and 5 GiB.
|
||||
- Rate limits per client on requests per minute, per hour and per day, and on
|
||||
bytes per minute, per hour and per day, on by default and set well above what
|
||||
real visitors need.
|
||||
- Netblocks that bypass rate limiting, netblocks that bypass everything, and
|
||||
netblocks that are always refused.
|
||||
- AS number and country lookup for every client, off until you choose a source:
|
||||
the IPinfo Lite database file, which you download and mount, or the free GeoJS
|
||||
web service (see "Country and AS number lookup" below).
|
||||
- AS number and country lookup for every client, on by default through the free
|
||||
GeoJS web service, which is sent the address of every new visitor. The IPinfo
|
||||
Lite database file, which you download and mount, can be used instead, or
|
||||
lookups switched off (see "Country and AS number lookup" below).
|
||||
- Country lists: `DENIED_COUNTRIES` refuses every request from the countries
|
||||
listed, `EXCLUSIVELY_ALLOWED_COUNTRIES` every request from anywhere else. Such
|
||||
a request gets the answer a banned client gets as soon as the client's address
|
||||
@@ -78,7 +79,9 @@ goes through the candidates one by one.
|
||||
scanning and penetration probes; easy to edit by hand, and picked up while
|
||||
running;
|
||||
- the OWASP Core Rule Set, run by the Coraza engine, refusing the requests
|
||||
it flags;
|
||||
it flags; it reads the URL and headers of every request, and request
|
||||
bodies only once you switch that on, since on a code forge they are full
|
||||
of code it would take for attacks;
|
||||
- trap paths, and a ban for a client that the rule files or the Core Rule
|
||||
Set refuse again and again.
|
||||
- Bans:
|
||||
@@ -102,14 +105,17 @@ goes through the candidates one by one.
|
||||
- Request log: one JSON object per request on stdout with the usual web log
|
||||
fields, the decision taken and why, AS number and country, and timings.
|
||||
Optionally also sent to a remote syslog server.
|
||||
- Prometheus metrics on their own port.
|
||||
- Prometheus metrics, for a scraper that holds the metrics token.
|
||||
- State (bans with their notes, each client's counters and history, the GeoJS
|
||||
answers, the reputation cache, the alerting state) held in memory and kept in
|
||||
readable JSON files, written regularly and at every stop, so a restart loses
|
||||
nothing. Edit a file, or add a rule file, and the running `smallwebwaf` picks
|
||||
up the change. Nothing is read from disk while serving a request.
|
||||
- A small admin endpoint for health checks, listing, adding and lifting bans,
|
||||
and asking why a given address was refused.
|
||||
- Health checks, the metrics, and listing, adding and lifting bans or asking why
|
||||
a given address was refused, all on the one port every request uses: under
|
||||
`/_smallwebwaf/` on the app's own address, through traefik like any other
|
||||
request. The metrics need the metrics token, and the ban management the admin
|
||||
token.
|
||||
|
||||
Not planned: TLS termination, routing for several apps, browser challenges
|
||||
(captcha or proof of work), a web console, or defence against floods large
|
||||
@@ -182,30 +188,32 @@ failure behaviour and the build order.
|
||||
|
||||
## Country and AS number lookup
|
||||
|
||||
AS number and country lookups, and the country lists and biased limits that use
|
||||
them, are off until you choose one of two sources with `LOOKUP_SOURCE`.
|
||||
|
||||
`LOOKUP_SOURCE=file` reads the free IPinfo Lite database (`ipinfo_lite.mmdb`).
|
||||
You download it with your own IPinfo account, mount the directory that holds it
|
||||
into the container, point `LOOKUP_DB_PATH` at the file and refresh it when you
|
||||
choose; `smallwebwaf` never downloads it itself, and reads it again when you
|
||||
replace it. It has to be the directory rather than the file itself: docker does
|
||||
not show a single mounted file being replaced, so a refresh would go unseen.
|
||||
IPinfo releases it under the Creative Commons Attribution-ShareAlike 4.0
|
||||
International License and asks for attribution, in its own words on
|
||||
https://ipinfo.io/lite: "The attribution requirements can be met by giving our
|
||||
service credit as your data source. Simply place a link to IPinfo on the
|
||||
website, application, or social media account that uses our data." Its example
|
||||
of such a credit is a link mentioning "IP address data is powered by IPinfo". A
|
||||
service that uses the database through `smallwebwaf` should carry that link.
|
||||
|
||||
`LOOKUP_SOURCE=geojs` asks the free GeoJS web service instead, with no account
|
||||
and no file. Every new visitor's address is sent to GeoJS. Each answer is kept
|
||||
`smallwebwaf` looks up the AS number and country of every client, for the
|
||||
request log, the metrics and the ban notes, and for the country lists and biased
|
||||
limits when you set them. It works with no setup: by default it asks the free
|
||||
GeoJS web service, which needs no account and no file. This means that, by
|
||||
default, the address of every new visitor is sent to GeoJS. Each answer is kept
|
||||
for seven days, across restarts, and many addresses are asked about in one
|
||||
request. GeoJS publishes no rate limit but may block a caller it thinks asks too
|
||||
much; while it is not answering, new visitors count as coming from an unknown
|
||||
country, which `EXCLUSIVELY_ALLOWED_COUNTRIES` refuses.
|
||||
|
||||
To keep your visitors' addresses on your own host, set `LOOKUP_SOURCE=off`, or
|
||||
use the database file instead of GeoJS: `LOOKUP_SOURCE=file` reads the free
|
||||
IPinfo Lite database (`ipinfo_lite.mmdb`). You download it with your own IPinfo
|
||||
account, mount the directory that holds it into the container, point
|
||||
`LOOKUP_DB_PATH` at the file and refresh it when you choose; `smallwebwaf` never
|
||||
downloads it itself, and reads it again when you replace it. It has to be the
|
||||
directory rather than the file itself: docker does not show a single mounted
|
||||
file being replaced, so a refresh would go unseen. IPinfo releases it under the
|
||||
Creative Commons Attribution-ShareAlike 4.0 International License and asks for
|
||||
attribution, in its own words on https://ipinfo.io/lite: "The attribution
|
||||
requirements can be met by giving our service credit as your data source. Simply
|
||||
place a link to IPinfo on the website, application, or social media account that
|
||||
uses our data." Its example of such a credit is a link mentioning "IP address
|
||||
data is powered by IPinfo". A service that uses the database through
|
||||
`smallwebwaf` should carry that link.
|
||||
|
||||
Neither source can place a private address, so a client on one, such as a
|
||||
visitor on your local network, another container or your monitoring, has no
|
||||
country: `EXCLUSIVELY_ALLOWED_COUNTRIES` refuses it unless you list it in
|
||||
|
||||
Reference in New Issue
Block a user