docs: caddy-waf is registered in Caddy's package registry (#122)

The module was claimed on 2026-07-28 at v0.3.5, once the RegisterModule scan
fix landed. README.md, docs/installation.md and docs/add-package-guide.md all
still told users the install path did not exist and would return HTTP 400.

CADDY_MODULE_REGISTRATION.md keeps the root-cause writeup so the &Middleware{}
pattern is not reintroduced, and adds maintenance notes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
fab
2026-07-28 12:11:37 +02:00
committed by GitHub
parent e5c5cc11e5
commit bb8fa2de56
6 changed files with 122 additions and 117 deletions

View File

@@ -1,85 +1,55 @@
# Caddy Module Registration — Status
Tracks whether `github.com/fabriziosalmi/caddy-waf` is registered in Caddy's
Tracks the registration of `github.com/fabriziosalmi/caddy-waf` in Caddy's
package registry, which is what makes the module appear on
<https://caddyserver.com/download> and installable with `caddy add-package`.
## Current status: NOT REGISTERED
## Current status: REGISTERED
Verified 2026-07-28 against the build service endpoint that `add-package` calls:
Claimed 2026-07-28 at 10:05:52 UTC, at version `v0.3.5`. Verified against the
build service endpoint that `add-package` calls:
```console
$ curl -s "https://caddyserver.com/api/download?p=github.com%2Ffabriziosalmi%2Fcaddy-waf&os=linux&arch=amd64"
{"status_code":400,"error":{"message":"github.com/fabriziosalmi/caddy-waf is not a registered Caddy module package path","id":"aed165cf-9d85-4b97-9b65-c5404988d648"}}
$ curl -s -o caddy -w "HTTP %{http_code} bytes=%{size_download}\n" \
"https://caddyserver.com/api/download?p=github.com%2Ffabriziosalmi%2Fcaddy-waf&os=linux&arch=amd64"
HTTP 200 bytes=48586914
```
Until this returns a build, `caddy add-package github.com/fabriziosalmi/caddy-waf`
fails and users must build with `xcaddy`. See [docs/installation.md](docs/installation.md).
## Module readiness: verified ready
The registry validates a package by resolving it from the Go module proxy and
building it. That exact path was reproduced end to end on 2026-07-28 against the
**published** module — not a local `replace` — and it succeeds:
and in the registry index:
```console
$ xcaddy build --with github.com/fabriziosalmi/caddy-waf@v0.3.4
go: downloading github.com/fabriziosalmi/caddy-waf v0.3.4
[INFO] Build complete: ./caddy
$ ./caddy version
v2.11.4 h1:XKxkMTgNSizEvKG6QHue6cAsFOteU2qA61w2tKkCWi0=
$ ./caddy list-modules | grep waf
http.handlers.waf
$ curl -s "https://caddyserver.com/api/packages?q=caddy-waf"
{
"path": "github.com/fabriziosalmi/caddy-waf",
"published": "2026-07-28T10:05:52.532759Z",
"listed": true,
"available": true,
"modules": [{"name": "http.handlers.waf", ...}]
}
```
Checked alongside it:
The module documentation rendered on caddyserver.com is extracted from the
doc comment on the `Middleware` struct in [types.go](types.go). Editing that
comment changes what users read on Caddy's site.
| Requirement | Status |
|---|---|
| Module path matches `go.mod` (`github.com/fabriziosalmi/caddy-waf`) | OK |
| Semantic import versioning (`/vN` suffix required only at v2+; this module is v0.x) | Not applicable |
| Resolvable on `proxy.golang.org` at the latest tag | OK — `v0.3.4` |
| Builds against current Caddy from the proxy | OK — Caddy v2.11.4 |
| Registers module ID `http.handlers.waf` at runtime | OK |
| Cross-compiles for linux/amd64, linux/arm64, windows/amd64 | OK |
## Do not reintroduce `&Middleware{}`
Note that CI builds with `xcaddy build --with github.com/fabriziosalmi/caddy-waf=./`,
a local `replace`. That verifies the working tree but **not** that the published
module resolves and builds from the proxy, which is what the registry does. When
diagnosing a registration failure, always reproduce with `@<tag>` rather than `=./`.
## What is left
Registration is a web form behind a GitHub login; there is no API for it.
1. Sign in at <https://caddyserver.com/account>.
2. Click **Register package**.
3. Package import path: `github.com/fabriziosalmi/caddy-waf`
4. Version: `v0.3.4` (the field is optional; the registry resolves the latest tag otherwise).
5. Re-run the `curl` above. A `200` with a binary means it is live; a `400` with a
fresh error `id` means it still failed — quote that id when asking the Caddy
maintainers, since it is what lets them find the server-side log.
## Root cause of the earlier failures — fixed in v0.3.5
Registering a package does more than resolve and build the module: the registry
runs a **static analyzer** over the source to discover which Caddy modules the
package registers. That analyzer is deliberately simple, and it only accepts two
forms as the argument to `caddy.RegisterModule`:
Registering a package makes the registry run a **static analyzer** over the
source to discover which Caddy modules it registers. That analyzer is
deliberately simple and accepts only two forms as the argument to
`caddy.RegisterModule`:
- a composite literal — `caddy.RegisterModule(Foo{})`
- `new()``caddy.RegisterModule(new(Foo))`
Anything else fails. Until v0.3.4 this module used:
Until v0.3.4 this module used:
```go
caddy.RegisterModule(&Middleware{}) // parses as ast.UnaryExpr -> rejected
```
`&Middleware{}` is a `*ast.UnaryExpr` wrapping the literal, not a literal, so the
scan aborts and the portal reports the generic:
`&Middleware{}` is a `*ast.UnaryExpr` wrapping the literal, not a literal, so
the scan aborted and the portal reported only:
```
Sorry, something went wrong:
@@ -87,21 +57,45 @@ unable to scan modules in package github.com/fabriziosalmi/caddy-waf
Please include this error ID if reporting: <uuid>
```
That message never names the offending line, which is why the earlier attempts
That message never names the offending line, which is why earlier attempts
(error ids `d9ae3bd6-bc8f-4f8a-a0de-dcff0399e7a9` and
`2b782e50-057d-4dac-bbd5-4cd1c1188669`, logged while the module was at v0.0.6)
were never diagnosed. The same failure and its resolution are documented in the
Caddy community thread [Unable to register module in the
`2b782e50-057d-4dac-bbd5-4cd1c1188669`, logged at v0.0.6) went undiagnosed for
so long and were wrongly assumed to be transient server-side faults. The same
failure and its resolution are documented in the Caddy community thread
[Unable to register module in the
portal](https://caddy.community/t/unable-to-register-module-in-the-portal/33572),
where Matt Holt identifies the underlying analyzer error:
where Matt Holt quotes the underlying analyzer error:
> `unexpected argument to RegisterModule(): &ast.UnaryExpr{...} - expect either composite literal or new()`
**v0.3.5 switches both `caddy.RegisterModule` and `ModuleInfo.New` to `new(Middleware)`.**
The forms are semantically identical — each allocates a zeroed `Middleware` and
yields a pointer — so there is no behavioural change; it only makes the source
legible to the scanner. `Middleware` must stay a pointer here: `CaddyModule` has a
pointer receiver, and the struct carries mutexes that must not be copied.
v0.3.5 switched both `caddy.RegisterModule` and `ModuleInfo.New` to
`new(Middleware)`. The forms are semantically identical — each allocates a
zeroed `Middleware` and yields a pointer — so there is no behavioural change.
The pointer is required either way: `CaddyModule` has a pointer receiver and
`Middleware` carries mutexes that must not be copied.
Do not reintroduce `&Middleware{}` in either place, or registration will break
again on the next version bump.
`TestRegisterModuleArgumentIsScannable` in
[module_registration_test.go](module_registration_test.go) parses the package's
own AST and fails the build if this regresses. Do not delete it.
## Maintenance
- **New releases are picked up automatically**; the registry resolves the latest
tag. Use **Rescan** on <https://caddyserver.com/account> to force a refresh —
for example after changing the `Middleware` doc comment, since that is what
the module documentation page shows.
- **Verifying a release is installable**, before announcing it:
```console
$ xcaddy build --with github.com/fabriziosalmi/caddy-waf@vX.Y.Z
$ ./caddy list-modules | grep waf
http.handlers.waf
```
Use `@vX.Y.Z`, not `=./`. CI builds with `--with github.com/fabriziosalmi/caddy-waf=./`,
a local `replace`, which verifies the working tree but **not** that the
published module resolves and builds from the Go proxy — which is the path the
registry actually exercises.
- **If a future registration or rescan fails**, capture the error `id` verbatim
and quote it when asking the Caddy maintainers; it is what lets them find the
server-side log. The portal message alone is not diagnostic.

View File

@@ -18,9 +18,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `TestRegisterModuleArgumentIsScannable` — parses the package's own AST and asserts the `caddy.RegisterModule` argument stays a composite literal or `new()`, so the registry constraint cannot silently regress on a future edit. Verified to fail against the v0.3.4 pattern and pass against the fix.
### Changed
- Rewrote `CADDY_MODULE_REGISTRATION.md`, which was stale (referenced v0.0.6 and Caddy v2.9.1) and speculated that the failures were server-side and "may resolve automatically". It now records the verified root cause, the readiness evidence, and the remaining manual step.
- Rewrote `CADDY_MODULE_REGISTRATION.md`, which was stale (referenced v0.0.6 and Caddy v2.9.1) and speculated that the failures were server-side and "may resolve automatically". It now records the verified root cause and the maintenance notes.
- Bumped version constant `wafVersion` to `v0.3.5`.
### Registered
With the scan fixed, `github.com/fabriziosalmi/caddy-waf` was claimed in Caddy's package registry on 2026-07-28 at 10:05:52 UTC, at `v0.3.5`. The build service now serves it (`GET /api/download?p=github.com%2Ffabriziosalmi%2Fcaddy-waf` returns a binary instead of HTTP 400), so `caddy add-package github.com/fabriziosalmi/caddy-waf` works and the module is selectable on <https://caddyserver.com/download>. `README.md`, `docs/installation.md` and `docs/add-package-guide.md` updated accordingly — they previously documented the install path as unavailable.
Note the module documentation shown on caddyserver.com is extracted from the doc comment on the `Middleware` struct in `types.go`.
## [v0.3.4] - 2026-07-28
### Security

View File

@@ -115,7 +115,14 @@ xcaddy build --with github.com/fabriziosalmi/caddy-waf=./
### `caddy add-package`
This module is **not registered** in Caddy's official package registry; `caddy add-package github.com/fabriziosalmi/caddy-waf` will fail with `HTTP 400: ... is not a registered Caddy module package path`. Use one of the build options above. See [`docs/add-package-guide.md`](docs/add-package-guide.md) for details.
The module is registered in Caddy's package registry, so an existing Caddy v2.7+ binary can pull it in without a Go toolchain:
```bash
caddy add-package github.com/fabriziosalmi/caddy-waf
caddy list-modules | grep waf # expect: http.handlers.waf
```
It is also selectable on [caddyserver.com/download](https://caddyserver.com/download). See [`docs/add-package-guide.md`](docs/add-package-guide.md) for version pinning, removal, and when to prefer `xcaddy` instead.
---
@@ -176,7 +183,7 @@ A fully annotated example is provided in [`Caddyfile`](Caddyfile) and [`caddyfil
| [`docs/scripts.md`](docs/scripts.md) | Helper Python scripts for rule and blacklist generation. |
| [`docs/testing.md`](docs/testing.md) | Running the bundled `test.py` suite. |
| [`docs/docker.md`](docs/docker.md) | Building and running with Docker / Docker Compose. |
| [`docs/add-package-guide.md`](docs/add-package-guide.md) | Status of `caddy add-package` registration. |
| [`docs/add-package-guide.md`](docs/add-package-guide.md) | Installing with `caddy add-package`. |
| [`docs/caddytest.md`](docs/caddytest.md) | The `caddytest.py` traffic-generation tool. |
---

View File

@@ -38,7 +38,7 @@ A first-time reader is recommended to follow this sequence:
| [testing.md](testing.md) | Running `test.py` against a live WAF. |
| [caddytest.md](caddytest.md) | Traffic generator for benchmarks and rule validation. |
| [docker.md](docker.md) | Building and running the supplied `Dockerfile` / `docker-compose.yml`. |
| [add-package-guide.md](add-package-guide.md) | Status of `caddy add-package` registration. |
| [add-package-guide.md](add-package-guide.md) | Installing with `caddy add-package`. |
## Bundled rule files

View File

@@ -1,94 +1,89 @@
# `caddy add-package` — Status and Reference
# `caddy add-package`
> **Important.** This module is **not** registered in Caddy's official package registry at `caddyserver.com`. Attempting to install it with `caddy add-package` returns:
>
> ```
> Error: download failed: HTTP 400: github.com/fabriziosalmi/caddy-waf is not a registered Caddy module package path
> ```
>
> Use one of the supported installation methods documented in [installation.md](installation.md) instead:
>
> - [Build with `xcaddy`](installation.md#method-1--build-with-xcaddy-recommended) (recommended)
> - [Quick script](installation.md#method-2--quick-script)
> - [Build from source](installation.md#method-3--build-from-source)
`github.com/fabriziosalmi/caddy-waf` is registered in Caddy's package registry
(since 2026-07-28), so it can be added to an existing Caddy binary without a Go
toolchain. It is also selectable on <https://caddyserver.com/download>.
This page is retained as a reference in case the module is registered in the future. Until then, every command shown below will fail.
For registration status and history see
[`CADDY_MODULE_REGISTRATION.md`](../CADDY_MODULE_REGISTRATION.md).
## Prerequisites (if registration ever completes)
## Requirements
- Caddy v2.7 or newer (the `add-package` command was introduced in 2.7).
- Caddy v2.7 or newer (`add-package` was introduced in 2.7).
- Network access from the Caddy host to `caddyserver.com`.
- Permission to replace the running Caddy binary.
## Hypothetical install
## Install
```bash
caddy add-package github.com/fabriziosalmi/caddy-waf
```
If the registration succeeds, the command would:
This will:
1. Detect the currently running Caddy and its module set.
2. Send a build request to the Caddy build service.
3. Download a new binary that includes the existing modules **plus** `caddy-waf`.
4. Back up the current Caddy binary (deleted unless `--keep-backup` is passed).
3. Download a new binary containing the existing modules **plus** `caddy-waf`.
4. Back up the current binary (deleted unless `--keep-backup` is passed).
5. Replace the Caddy binary in place.
Verify:
```bash
caddy list-modules | grep waf
# Expected: http.handlers.waf
# expect: http.handlers.waf
```
## Hypothetical version pinning
## Pin a version
```bash
caddy add-package github.com/fabriziosalmi/caddy-waf@vX.Y.Z
caddy add-package github.com/fabriziosalmi/caddy-waf@v0.3.5
```
`vX.Y.Z` is any tag from the [GitHub Releases](https://github.com/fabriziosalmi/caddy-waf/releases) page.
Any tag from the [Releases](https://github.com/fabriziosalmi/caddy-waf/releases)
page works. Without a version the build service uses the latest tag.
## Hypothetical removal
Note that v0.3.4 and earlier carry a high-severity denial-of-service
(GHSA-gfj3-cmff-q8wh); do not pin below v0.3.4.
## Remove
```bash
caddy remove-package github.com/fabriziosalmi/caddy-waf
```
## Why `add-package` does not work today
## When to build with xcaddy instead
The Caddy build service maintains an allow-list of registered package paths. Until the maintainer of `caddy-waf` registers `github.com/fabriziosalmi/caddy-waf` through `https://caddyserver.com/account/register-package`, the build service refuses requests for it. The registration history and prior error references are tracked in [`CADDY_MODULE_REGISTRATION.md`](../CADDY_MODULE_REGISTRATION.md).
## Use this instead
The recommended flow on a host that already has `xcaddy` (and hence Go) installed:
`add-package` replaces a binary in place using a remote build service. Prefer
[`xcaddy`](installation.md#option-1--build-with-xcaddy-recommended) when you
need to build from a fork or an untagged commit, pin the Caddy version itself,
build in an air-gapped environment, or produce reproducible artifacts in CI:
```bash
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
xcaddy build --with github.com/fabriziosalmi/caddy-waf
./caddy version
./caddy list-modules | grep waf
```
If Go is not available, run the bundled `install.sh` (see [installation.md](installation.md#method-2--quick-script)) which installs Go and `xcaddy` on first use.
## Troubleshooting
### `command not found: caddy add-package`
You are running Caddy older than 2.7. Update Caddy and retry — but note the registration warning above still applies.
You are running Caddy older than 2.7. Update Caddy.
### `permission denied`
The new binary cannot replace the existing one. Re-run with `sudo`, or run `add-package` from a directory where the user has write access and copy the resulting binary into place manually.
The new binary cannot replace the existing one. Re-run with `sudo`, or run
`add-package` from a directory the user can write to and move the resulting
binary into place manually.
### `Error: download failed: HTTP 400: ... is not a registered Caddy module package path`
Expected. Use one of the build paths from [installation.md](installation.md).
Check the import path for typos. Go module paths are not URLs, so no `https://`
prefix and no trailing slash. If the path is correct and the error persists, the
registration may have been removed — see
[`CADDY_MODULE_REGISTRATION.md`](../CADDY_MODULE_REGISTRATION.md).
## References
- Caddy command line documentation: <https://caddyserver.com/docs/command-line>
- Caddy command line: <https://caddyserver.com/docs/command-line>
- Extending Caddy: <https://caddyserver.com/docs/extending-caddy>
- `xcaddy`: <https://github.com/caddyserver/xcaddy>
- Module registration tracker: [`CADDY_MODULE_REGISTRATION.md`](../CADDY_MODULE_REGISTRATION.md)

View File

@@ -63,13 +63,17 @@ The `=./` form of `--with` instructs `xcaddy` to use the local checkout rather t
## Method 4 — `caddy add-package`
This module is **not registered** in Caddy's official package registry. Attempting `caddy add-package github.com/fabriziosalmi/caddy-waf` returns:
The module is registered in Caddy's package registry, so an existing Caddy v2.7+ binary can pull it in without a Go toolchain:
```
Error: download failed: HTTP 400: github.com/fabriziosalmi/caddy-waf is not a registered Caddy module package path
```bash
caddy add-package github.com/fabriziosalmi/caddy-waf
```
Use Method 1, 2, or 3 above. Background and the registration checklist are in [add-package-guide.md](add-package-guide.md) and [`CADDY_MODULE_REGISTRATION.md`](../CADDY_MODULE_REGISTRATION.md).
This asks the Caddy build service for a binary containing your current module set plus `caddy-waf`, then replaces the binary in place (backing up the old one unless `--keep-backup` is passed). Pin a version with `@v0.3.5` if needed.
The module is also selectable on <https://caddyserver.com/download>.
See [add-package-guide.md](add-package-guide.md) for the full flow, removal, and troubleshooting.
## Verifying the build