leocalheirosdb1 opened a new issue, #13594: URL: https://github.com/apache/apisix/issues/13594
### Description ## Question We are running APISIX behind a TCP load balancer (TLS passthrough) with Proxy Protocol v2. To handle proxy protocol, we use `proxy_protocol.listen_https_port: 9182` in our config. The problem is that APISIX sends `X-Forwarded-Port: 9182` (the internal listener port) to upstream services instead of `443` (the port clients actually connect to). This causes our upstream (Keycloak) to generate redirect URLs like: ``` Location: https://example.com:9182/admin/master/console/ ``` **What is the recommended way to override `X-Forwarded-Port` in this setup?** ## What we understand In `ngx_tpl.lua`, the generated nginx config sets: ```nginx set $var_x_forwarded_port $server_port; proxy_set_header X-Forwarded-Port $var_x_forwarded_port; ``` Since our proxy protocol listener is on port 9182, `$server_port` resolves to **9182**. The `proxy_set_header` directive then forwards this value to upstream. We also noticed that `http_server_location_configuration_snippet` is injected **before** the `set $var_x_forwarded_port` line in the location block, so any snippet-based override gets overwritten. ## What we tried We attempted several approaches, none of which changed the `X-Forwarded-Port` value received by upstream: ### 1. `serverless-pre-function` (rewrite phase) writing to the nginx variable ```yaml - name: serverless-pre-function enable: true config: phase: rewrite functions: - | return function(conf, ctx) if ctx.var.var_x_forwarded_port == "9182" then ctx.var.var_x_forwarded_port = "443" end end ``` `var_x_forwarded_port` is in the `ngx_var_names` allowlist in `core/ctx.lua`, so this writes directly to `ngx.var`. We expected it to persist since the access phase runs after rewrite-phase `set` directives. **Did not work.** ### 2. `ctx.var.http_x_forwarded_port = "443"` Sets the request header via `ngx.req.set_header()`, but `proxy_set_header` reads `$var_x_forwarded_port` (nginx variable), not `$http_x_forwarded_port`. The template has no `if ($http_x_forwarded_port)` block. **No effect.** ### 3. `proxy-rewrite` plugin with `headers.set.X-Forwarded-Port: "443"` Same mechanism as #2 — sets the request header, overridden by `proxy_set_header`. **No effect.** ### 4. `serverless-pre-function` in balancer phase Balancer runs inside the `upstream {}` block, separate from the `location {}` block where `proxy_set_header` lives. **No effect.** ### 5. `serverless-post-function` (header_filter) rewriting the Location response header ```lua local loc = ngx.header["Location"] if loc then ngx.header["Location"] = loc:gsub(":9182", "") end ``` Fixes the initial 302 redirect header, but the response **body** (HTML, JS, JSON) still contains URLs with `:9182`. Partial workaround only. ### 6. `nginx_config.http_server_location_configuration_snippet` Snippet is injected before `set $var_x_forwarded_port $server_port;` in the template. Any `set` we add runs earlier in the rewrite phase and gets overridden. ## What we need help with We've exhausted the approaches we could find in the docs and issues. We'd appreciate guidance on: - Is there a supported way to override `X-Forwarded-Port` when using `proxy_protocol.listen_https_port`? - Is `ctx.var.var_x_forwarded_port` supposed to work for this use case? If so, what might prevent the write from persisting to `proxy_set_header` evaluation? - Is there a config option or plugin we're missing that handles port translation in proxy protocol setups? ## Minimal Reproduction 1. Deploy APISIX 3.16.0 with TLS enabled and `proxy_protocol.listen_https_port: 9182` 2. Place a TCP load balancer in front that sends Proxy Protocol v2 to port 9182 3. Configure a route to any upstream that uses `X-Forwarded-Port` for URL construction (e.g., Keycloak) 4. Access the service — upstream receives `X-Forwarded-Port: 9182` and generates incorrect redirect URLs ```bash $ curl -svk https://your-domain.com/admin/ 2>&1 | grep -i "location" < location: https://your-domain.com:9182/admin/master/console/ ``` ## Related - #4942 — X-Forwarded-Port rewriting issues - #8226 — Related PR ### Environment - **APISIX version:** 3.16.0 - **Helm chart:** 2.14.0 - **Deployment:** Kubernetes (OKE) with APISIX Ingress Controller CRDs - **Load Balancer:** OCI Load Balancer — TCP listeners (TLS passthrough) with Proxy Protocol v2 - **Architecture:** Client → LB (TCP:443, PP v2) → APISIX (TLS termination on port 9182) → Upstream (HTTP) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
