mirror of
https://github.com/fabriziosalmi/caddy-waf.git
synced 2026-07-30 06:15:57 -04:00
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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
11
README.md
11
README.md
@@ -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. |
|
||||
|
||||
---
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user