diff --git a/CHANGELOG.md b/CHANGELOG.md index e4f2552..2d4fdff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `docker-compose.yml` is a sample to start from, ipx alone on SQLite with its folders beside the file, instead of a copy of the author's server (#208). - The source is a Cargo workspace: the daemon in `crates/ipx`, feed fetching and parsing in `crates/feed`. `cargo build --release` still makes `target/release/ipx` (#202). +### Fixed + +- Signing in through Cloudflare Access works behind ipx-web: Caddy took the tunnel's address for someone else's and dropped its sign-in headers (#209). + ## [0.12.0] - 2026-10-11 ### Added diff --git a/web/Caddyfile b/web/Caddyfile index dc8f25d..e0f85a1 100644 --- a/web/Caddyfile +++ b/web/Caddyfile @@ -2,7 +2,7 @@ # so the session cookie, live updates and Cloudflare Access work as they did when ipx served it. # IPX_UPSTREAM where ipx is, host:port (ipx:8099) # WEB_BIND where to listen (:8080) -# TUNNEL_PEER the one address whose Cf-Access-* headers are passed on: where cloudflared's +# TUNNEL_PEER the one IPv4 address whose Cf-Access-* headers are passed on: where cloudflared's # requests come from. Nobody else's are, so nobody else can claim to be signed in # by Cloudflare. Unset passes none. { @@ -13,8 +13,10 @@ http://{$WEB_BIND::8080} { root * {$WEB_ROOT:/srv} - # Before anything else, so no page or API call sees them: only ipx sets these. - @forged not remote_ip {$TUNNEL_PEER:255.255.255.255} + # Before anything else, so no page or API call sees them: only ipx sets these. Both forms of + # the peer: Caddy listens dual-stack, so an IPv4 peer arrives as ::ffff:a.b.c.d, which the + # plain address does not match, and the tunnel's headers were stripped too (#209). + @forged not remote_ip {$TUNNEL_PEER:255.255.255.255} ::ffff:{$TUNNEL_PEER:255.255.255.255} request_header @forged -Cf-Access-Authenticated-User-Email request_header @forged -Cf-Access-Jwt-Assertion