fix: Ensure x-forwarded-port header is used in Forwarded header #115
+47
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What I'm Changing
This PR ensures that a
x-forwarded-portheader is used when constructing theforwardedheader.Backstory
We have been experiencing an issue in a Kubernetes environment where Links were being written with
hrefvalues with incorrect origins. To be specific, they would point tolocalhost:8001rather thanlocalhost, wherelocalhostis the public-facing host and:8001is the port of the internal upstream STAC API. The network layout was such that we had a Traefik proxy in front of the STAC Auth Proxy. That proxy sets thex-forwarded-portheader on requests that were sent to the STAC Auth Proxy. However, the request did not contain aforwardedheader, so we would create one. The problem was that our current logic would not make use of thex-forwarded-portwhen created theforwardedheader. Despite us forwarding thex-forwarded-port, the upstream STAC API would defer to theforwardedheader and thus ignore the providedx-forwarded-port. This meant that the upstream STAC API would generate links forhttp://localhost:8001. Digging throughstac-fastapicode, we can see that the port first is read from thehostheader and then possibly overridden by the value inforwarded:https://github.com/stac-utils/stac-fastapi/blob/3b24f86bc538b8c1d6b86008845d5541f4f481e8/stac_fastapi/api/stac_fastapi/api/middleware.py#L87-L106
The current problematic flow looks something like this:
sequenceDiagram autonumber participant Client as Client participant Traefik as Traefik Proxy participant Auth as STAC Auth Proxy participant STAC as STAC API Client->>Traefik: HTTP request Note left of Traefik: host: http://localhost Traefik->>Auth: Forward request Note left of Auth: host: http://localhost Note left of Auth: x-forwarded-for: 192.168.65.1 Note left of Auth: x-forwarded-host: localhost Note left of Auth: x-forwarded-port: 80 Note left of Auth: x-forwarded-proto: http Note left of Auth: x-forwarded-server: 26a4cc50fa1a Auth->>STAC: Forward request (proxied) Note left of STAC: host: http://stac:8001 Note left of STAC: x-forwarded-for: 192.168.65.1 Note left of STAC: x-forwarded-host: localhost Note left of STAC: x-forwarded-port: 80 Note left of STAC: x-forwarded-proto: http Note left of STAC: x-forwarded-server: 26a4cc50fa1a Note left of STAC: via: 1.1 stac-auth-proxy Note left of STAC: forwarded: for=192.168.65.1 host=localhost proto=http path=/stac STAC-->>Auth: Response document Note left of Auth: links point to http://localhost:8001/... Auth-->>Client: Response (unchanged body)Unfortunately, our link rewriting middleware would miss these links as it was looking for the internal upstream url
stac:8001and notlocalhost:8001. This is maybe besides the point, as the link rewriting middleware is really about cleaning up paths and in an ideal world we expect the upstream STAC API to properly make use of theforwardedheader to properly construct links (which stac-fastapi-pgstac does decently well).some more thoughts about
x-forwarded-portReading the MDN docs on the
forwardedheader[^1], we see:The lack of mention of
x-forwarded-portled me to believe that theX-forwarded-Hostincluded the port. However, that doesn't not seem accurate when reviewing Traefik behavior.How I did it
The fix was pretty simple: ensure that the
hostwithin theforwardedheader contained the x-forwarded port.How you can test it
Docker image of this build available here: https://github.com/developmentseed/stac-auth-proxy/releases/tag/v0.10.2-rc2