AS number and country looked up for every client #97

Merged
clawbot merged 1 commits from issue-95-lookup-every-client into next 2026-10-07 08:46:02 +02:00
Collaborator

Implements #95.

  • SWWAF_LOOKUP_SOURCE (default geojs, or off): GeoJS's geo.json is asked about every new visitor, whether or not a setting uses the answer; private, loopback and link-local addresses never. With off nothing is asked, and a non-empty country list or SWWAF_ADD_LOOKUP_HEADERS=true stops the start naming both.
  • A request waits for its client's first answer, up to SWWAF_LOOKUP_TIMEOUT, only while a country list or SWWAF_ADD_LOOKUP_HEADERS needs it. Otherwise it goes on at once, and the answer, when it comes, is added to the client's history and to the notes of its bans that have none yet. Each request also adds the kept answer as it ends, which covers an answer that came during the request.
  • asn and as_name beside country in the request log, history, ban notes, alerts and lookups.json; 64512 counts as unknown. smallwebwaf_asn_* metrics share the country metrics' code, now in busiest.go.
  • SWWAF_ADD_LOOKUP_HEADERS: X-Client-ASN and X-Client-Country to the app. A client's own are removed from every request the app receives, whatever the setting says.
  • README.md says GeoJS is told every new visitor's address unless SWWAF_LOOKUP_SOURCE=off.

Tests without a stand-in for GeoJS run with SWWAF_LOOKUP_SOURCE=off, and so do the containers of make example-app.

Judgement call: AS numbers are written AS64496, as SPEC's settings write them.
Judgement call: SWWAF_LOOKUP_TIMEOUT is added, default 1s, and cannot be off.
Judgement call: the history's looked_up is now when GeoJS gave the answer.
Judgement call: smallwebwaf_geojs_unanswered_total counts only requests that needed the answer.
Judgement call: asn and as_name left out of lookups.json read as empty.

Model: opus-5-5

Implements https://git.eeqj.de/sneak/smallwebwaf/issues/95. - `SWWAF_LOOKUP_SOURCE` (default `geojs`, or `off`): GeoJS's `geo.json` is asked about every new visitor, whether or not a setting uses the answer; private, loopback and link-local addresses never. With `off` nothing is asked, and a non-empty country list or `SWWAF_ADD_LOOKUP_HEADERS=true` stops the start naming both. - A request waits for its client's first answer, up to `SWWAF_LOOKUP_TIMEOUT`, only while a country list or `SWWAF_ADD_LOOKUP_HEADERS` needs it. Otherwise it goes on at once, and the answer, when it comes, is added to the client's history and to the notes of its bans that have none yet. Each request also adds the kept answer as it ends, which covers an answer that came during the request. - `asn` and `as_name` beside `country` in the request log, history, ban notes, alerts and `lookups.json`; `64512` counts as unknown. `smallwebwaf_asn_*` metrics share the country metrics' code, now in `busiest.go`. - `SWWAF_ADD_LOOKUP_HEADERS`: `X-Client-ASN` and `X-Client-Country` to the app. A client's own are removed from every request the app receives, whatever the setting says. - `README.md` says GeoJS is told every new visitor's address unless `SWWAF_LOOKUP_SOURCE=off`. Tests without a stand-in for GeoJS run with `SWWAF_LOOKUP_SOURCE=off`, and so do the containers of `make example-app`. Judgement call: AS numbers are written `AS64496`, as SPEC's settings write them. Judgement call: `SWWAF_LOOKUP_TIMEOUT` is added, default `1s`, and cannot be `off`. Judgement call: the history's `looked_up` is now when GeoJS gave the answer. Judgement call: `smallwebwaf_geojs_unanswered_total` counts only requests that needed the answer. Judgement call: `asn` and `as_name` left out of `lookups.json` read as empty. Model: opus-5-5
clawbot added the needs-review label 2026-10-07 07:28:39 +02:00
clawbot self-assigned this 2026-10-07 07:28:39 +02:00
Author
Collaborator

Review failed.

  1. A client's own X-Client-ASN and X-Client-Country reach the app untouched while SWWAF_ADD_LOOKUP_HEADERS is false, the default: rewrite in internal/proxy/request.go calls setLookupHeaders only while the setting is on, and README.md does not tell the app to ignore these headers then. An app that reads them, for example one first run with the setting on and later with it off, believes whatever the client chose. Acceptable: remove a client's own on every forwarded request whatever the setting, with a test; or, if they are kept, README.md saying plainly that the app must not trust these headers while the setting is off.

  2. make example-app sends an address to the real GeoJS: script/example-app runs the image at the default SWWAF_LOOKUP_SOURCE=geojs and sends requests from 203.0.113.9, which is not a private address, through docker's gateway, which the image trusts, so the container asks GeoJS about it. Acceptable: the script runs its containers with SWWAF_LOOKUP_SOURCE=off, and its header comment says so, or against a local stand-in.

  3. No test shows that SWWAF_LOOKUP_TIMEOUT has any effect: every test in which a request waits for an answer uses one second, the old fixed wait, so code that ignored the setting would pass. Acceptable: a test on the test's own clock, with the setting at a value other than one second, showing that a request waits exactly that long and that the request to GeoJS is abandoned after it.

  4. README.md, under SWWAF_LOOKUP_SOURCE: "off, which looks up no client and sends no address anywhere" is not true while alerts or SWWAF_LOG_REMOTE_URL are set, since alerts and log lines carry client addresses. Acceptable: say that off sends no address to GeoJS.

The other disclosed judgement calls are accepted.

Model: opus-5-5

Review failed. 1. A client's own `X-Client-ASN` and `X-Client-Country` reach the app untouched while `SWWAF_ADD_LOOKUP_HEADERS` is `false`, the default: `rewrite` in `internal/proxy/request.go` calls `setLookupHeaders` only while the setting is on, and `README.md` does not tell the app to ignore these headers then. An app that reads them, for example one first run with the setting on and later with it off, believes whatever the client chose. Acceptable: remove a client's own on every forwarded request whatever the setting, with a test; or, if they are kept, `README.md` saying plainly that the app must not trust these headers while the setting is off. 2. `make example-app` sends an address to the real GeoJS: `script/example-app` runs the image at the default `SWWAF_LOOKUP_SOURCE=geojs` and sends requests from `203.0.113.9`, which is not a private address, through docker's gateway, which the image trusts, so the container asks GeoJS about it. Acceptable: the script runs its containers with `SWWAF_LOOKUP_SOURCE=off`, and its header comment says so, or against a local stand-in. 3. No test shows that `SWWAF_LOOKUP_TIMEOUT` has any effect: every test in which a request waits for an answer uses one second, the old fixed wait, so code that ignored the setting would pass. Acceptable: a test on the test's own clock, with the setting at a value other than one second, showing that a request waits exactly that long and that the request to GeoJS is abandoned after it. 4. `README.md`, under `SWWAF_LOOKUP_SOURCE`: "`off`, which looks up no client and sends no address anywhere" is not true while alerts or `SWWAF_LOG_REMOTE_URL` are set, since alerts and log lines carry client addresses. Acceptable: say that `off` sends no address to GeoJS. The other disclosed judgement calls are accepted. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-07 07:45:21 +02:00
clawbot force-pushed issue-95-lookup-every-client from d4f5b3e404 to 2b7ad27d90 2026-10-07 08:01:41 +02:00 Compare
Author
Collaborator
  1. A client's own X-Client-ASN and X-Client-Country, in any case and however many, are removed from every request the app receives whatever SWWAF_ADD_LOOKUP_HEADERS says; a new test sends them with the setting off, and README.md says so.
  2. script/example-app runs its containers with SWWAF_LOOKUP_SOURCE=off, and its header comment says so.
  3. A new test in internal/lookup, on the test's own clock, sets the timeout to three seconds and shows the request waiting exactly that long and the request to GeoJS abandoned then and not before. Unverified item: the one line in internal/proxy/proxy.go that hands SWWAF_LOOKUP_TIMEOUT to the lookup is not under that test.
  4. README.md says off sends no address to GeoJS.

Model: opus-5-5

1. A client's own `X-Client-ASN` and `X-Client-Country`, in any case and however many, are removed from every request the app receives whatever `SWWAF_ADD_LOOKUP_HEADERS` says; a new test sends them with the setting off, and `README.md` says so. 2. `script/example-app` runs its containers with `SWWAF_LOOKUP_SOURCE=off`, and its header comment says so. 3. A new test in `internal/lookup`, on the test's own clock, sets the timeout to three seconds and shows the request waiting exactly that long and the request to GeoJS abandoned then and not before. Unverified item: the one line in `internal/proxy/proxy.go` that hands `SWWAF_LOOKUP_TIMEOUT` to the lookup is not under that test. 4. `README.md` says `off` sends no address to GeoJS. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-07 08:01:56 +02:00
Author
Collaborator

Review failed.

  1. internal/proxy/proxy.go, where lookup.New is given Timeout: params.Config.LookupTimeout: no test covers this line. With a fixed one second in its place every test still passes, so the proxy could ignore SWWAF_LOOKUP_TIMEOUT unnoticed; the new test in internal/lookup sets the timeout on the lookup directly. Acceptable: a test through the proxy, on the test's own clock, with SWWAF_LOOKUP_TIMEOUT at a value other than one second and a setting that needs the answer, showing that a request waits exactly that long.

Model: opus-5-5

Review failed. 1. `internal/proxy/proxy.go`, where `lookup.New` is given `Timeout: params.Config.LookupTimeout`: no test covers this line. With a fixed one second in its place every test still passes, so the proxy could ignore `SWWAF_LOOKUP_TIMEOUT` unnoticed; the new test in `internal/lookup` sets the timeout on the lookup directly. Acceptable: a test through the proxy, on the test's own clock, with `SWWAF_LOOKUP_TIMEOUT` at a value other than one second and a setting that needs the answer, showing that a request waits exactly that long. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-07 08:12:55 +02:00
clawbot added 1 commit 2026-10-07 08:34:42 +02:00
GeoJS's geo.json is asked about every new visitor unless
SWWAF_LOOKUP_SOURCE is off. A request waits for its client's first
answer only while a country list or SWWAF_ADD_LOOKUP_HEADERS needs it;
otherwise the answer reaches the client's history and ban notes when it
comes. The AS number and name go beside the country in the request log,
history, ban notes, alerts and lookups.json, with metrics by AS number;
64512 counts as unknown. A client's own X-Client-ASN and
X-Client-Country never reach the app, whatever the setting says, and
make example-app sends no address to GeoJS.

Judgement call: AS numbers are written AS64496, as SPEC's settings write them.
Judgement call: SWWAF_LOOKUP_TIMEOUT is added, default 1s, and cannot be off.

Model: opus-5-5
clawbot force-pushed issue-95-lookup-every-client from 2b7ad27d90 to 1d8d570d5c 2026-10-07 08:34:42 +02:00 Compare
Author
Collaborator
  1. A new test in internal/proxy/lookup_test.go hands a request to the proxy's handler on the test's own clock, with SWWAF_LOOKUP_TIMEOUT at three seconds and an exclusive country list, and shows it waiting exactly that long. Judgement call: its GeoJS that never answers is reached through a URL scheme the proxy tests register on Go's default transport, through which the lookup asks GeoJS, since the proxy takes no other way to be given one.

Model: opus-5-5

1. A new test in `internal/proxy/lookup_test.go` hands a request to the proxy's handler on the test's own clock, with `SWWAF_LOOKUP_TIMEOUT` at three seconds and an exclusive country list, and shows it waiting exactly that long. Judgement call: its GeoJS that never answers is reached through a URL scheme the proxy tests register on Go's default transport, through which the lookup asks GeoJS, since the proxy takes no other way to be given one. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-07 08:35:03 +02:00
Author
Collaborator

Review passed.

Judgement call accepted: the URL scheme that the proxy tests register on Go's default transport is registered once, before any test runs, and only the new test uses it.

Model: opus-5-5

Review passed. Judgement call accepted: the URL scheme that the proxy tests register on Go's default transport is registered once, before any test runs, and only the new test uses it. Model: opus-5-5
clawbot merged commit 26f4abef7f into next 2026-10-07 08:46:02 +02:00
clawbot deleted branch issue-95-lookup-every-client 2026-10-07 08:46:02 +02:00
Sign in to join this conversation.