fastly — an edge ACL at Fastly

Blocks at the Fastly edge by managing entries in an Edge ACL via the Fastly API. The service's VCL decides what happens to matching clients; the kur manages ACL membership only, one entry per banned IP, effective as soon as the API call lands (edge ACL updates do not need a service deploy).

[kur.web]
backend = "fastly"

[kur.web.options]
token   = "the-api-token"
service = "SU1Z0isxPaozGVKXdv0eY"
acl     = "6tUXdegLTf5BCig0zGFrU3"

Fastly-side setup — required first

if (client.ip ~ my_banned_acl) {
  error 403 "banished";
}

Requirements

Settings

Options

| option | default | what | |------------|--------------|------------------------------------------| | token | (required) | API token, sent as the Fastly-Key header | | service | (required) | the service ID | | acl | (required) | the ACL ID | | timeout | 30 | HTTP timeout in seconds | | insecure | 0 | skip TLS certificate verification |

What each operation does

Base URL: https://api.fastly.com/service/<service>/acl/<acl>:

| operation | API traffic | |------------|--------------------------------------------------------------------------| | init | GET .../entries?per_page=1 — verifies token, service, and ACL | | ban | POST .../entry with {"ip":"<ip>","subnet":32} (128 for IPv6) | | unban | GET .../entries to find the entry's ID, then DELETE .../entry/<id> | | list | no API call — the kur's own ban book | | check | same probe as init | | flush | the lookup+DELETE per banned IP | | re_init | teardown (best effort), init, re-POST every banned IP | | teardown | the lookup+DELETE per banned IP (ban book kept) |

An entry already removed at Fastly by hand is treated as already unbanned.

self_heal

check verifies the token still reads the ACL — not the entries, and not that any VCL consults it. Hand-removed entries stay gone until re_init.

Gotchas