fix: move routing from CBC nginx to application nginx#549
Conversation
d7387b7 to
3ccdfc0
Compare
|
Thanks for the PR @SuperVK! I am currently reviewing it, however, we need to know the new IP(s) for the Traefik proxy before we can deploy: we need it for gewisdb/module/Database/src/Module.php Line 609 in 89965ff Currently, we use two WAF ranges ( |
The join.gewis.nl and member.gewis.nl server blocks include a snippet that was never committed, which is a fatal error on NGINX startup. Add it and use it for the database.gewis.nl block as well.
Behind the join/member hop PHP sees REMOTE_ADDR=127.0.0.1, which must be a trusted proxy for the X-Forwarded-For resolution to run at all. Otherwise every join/member visitor resolves to localhost and the July campus-only subscribe check rejects everyone.
The `$host` maps only ever defined a default, so they were constants with indirection, and moving the `add_header` directives into a snippet split the values from their use. Inline the literal values and drop the maps.
`proxy_set_header` is inherited all-or-nothing per level and every proxying location defines its own set, so these http-level directives never apply. Keeping them is misleading next to proxy-to-backend.conf, where `X-Forwarded-Proto` deliberately does not use $scheme.
Keep only what the config cannot express itself: why the loopback hop exists and why the forwarded headers must not be rebuilt from local variables. This also drops the incorrect claim that no FastCGI equivalent exists for `session.cookie_domain`.
Production resolves the client from X-Forwarded-For; the X-Real-IP default was stale and misleading. Behind the new proxy chain X-Real-IP does not reliably hold the client (an intermediate hop overwrites it), so chain resolution is the mechanism of record. Also document which hops belong in PROXY_IPS.
Setting it from $remote_addr records the previous proxy instead of the client. Unset headers are passed through unchanged, so the values from the edge already reach the backend; the X-Forwarded-Proto and X-Forwarded-Port lines were no-op pass-throughs and are dropped too.
|
Once again thank you for the PR. It did need a few functional fixes though (running The join and member server blocks include The loopback hop set The remaining commits are cleanup: the security header values are inlined in the snippet since the maps only defined defaults, the unused http-level
There is no need to test in production. I verified locally that Note that this config and the current CBC proxy cannot run together. The CBC proxy rewrites URLs before proxying and those rewritten forms are not in the whitelists, so this image behind the old proxy breaks renewal links and the checkout redirects, while the old image behind Traefik serves the full application with a broken cookie domain. The merge therefore has to land in the same window as the proxy migration, and a revert of the migration also means rolling back this image. In the same window |
There was a problem hiding this comment.
Pull request overview
This PR shifts host-based routing responsibilities from the CBC’s nginx layer into the application’s own nginx configuration, enabling join/member vhosts to re-proxy to the main application and rewrite cookie domains (to support Traefik at the edge).
Changes:
- Add dedicated
join.gewis.nlandmember.gewis.nlserver blocks that proxy to a loopback backend and applyproxy_cookie_domain. - Extract shared nginx concerns into snippets (security headers, security.txt proxying, backend proxying) and simplify global proxy settings.
- Update default proxy header configuration in
.env.distto align withX-Forwarded-Forusage and the extra loopback hop.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
docker/nginx/snippets/securitytxt.conf |
Adds centralized proxying of /.well-known/security.txt from gewis.nl. |
docker/nginx/snippets/security-headers.conf |
Centralizes common security headers previously embedded in nginx.conf. |
docker/nginx/snippets/proxy-to-backend.conf |
Defines the loopback proxy settings used by join/member vhosts to reach the main app. |
docker/nginx/proxy.conf |
Removes globally forced forwarded headers to avoid incorrect values on re-proxied requests. |
docker/nginx/nginx.conf |
Introduces join/member server blocks and refactors security/security.txt behavior into snippets. |
.env.dist |
Adjusts proxy header defaults to X-Forwarded-For and documents multi-hop trusted proxy configuration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Description
The CBC is trying to move to Traefik proxying instead of nginx. Traefik does not support proxying the cookie domain (without plugins), but from the CBC we also rather have that the ABC projects manage this complex routing themselves. I helped out a bit, this should work. Do you want me see if I can test this locally? Or is possible to quickly test this in production? Reverting back should be able without any hassle.
Related issues/external references
Types of changes