rust-rpxy
rust-rpxy copied to clipboard
TODO: Support of `Forwarded` header
In addition to X-Forwarded-For, rpxy should support Forwarded extension header in RFC7239.
c.f. https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/
Archive version of nginx docs: https://web.archive.org/web/20240511013834/https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/
So, my first thoughts on configuration options we could add:
- downstream
- trust downstream Forwarded header: y/N
- only with included secret: _______________ (comma-separated list)
- OR from given ips: _______________ (comma-separated list)
- trust any upstreams of above: y/N
- trust downstream Forwarded header: y/N
- upstream
- add/extend Forwarded header: Y/n
- add secret: ______________
- obfuscate "for" parameter: Y/n
- remove malformed entries: Y/n (maybe force-yes this when "add/extend" is enabled above?)
- remove other downstream X-Forwarded-* etc headers when Forwarded header added/present: Y/n
- add/extend Forwarded header: Y/n
WDYT? Too much?
Hello, this seems to not work fully correctly.
Enabling the option I see:
192.168.13.104 - - [07/Jul/2025 15:24:30] "GET / HTTP/1.1" 200 -
ERROR:root:user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
accept: image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5
accept-language: en-US,en;q=0.7,bg;q=0.3
accept-encoding: gzip, deflate, br, zstd
dnt: 1
alt-used: test.example.com
referer: https://test.example.com/
x-forwarded-for: 192.168.13.103
sec-fetch-dest: image
sec-fetch-mode: no-cors
sec-fetch-site: same-origin
priority: u=6
pragma: no-cache
cache-control: no-cache
cookie: PHPSESSID=9cf92ae94de0423045ef7f8311b6698d
x-forwarded-proto: https
x-forwarded-port: 8443
x-real-ip: 192.168.13.103
x-forwarded-ssl: on
x-original-uri: https://test.example.com/favicon.ico
proxy:
host: test.example.com
forwarded: for=192.168.13.103;proto=http;host=test.example.com
I believe it should be proto=https.
And btw, why not enable the feature by default and disable when requested? I think the standard header should be there by default.
P.S. unrelated question, should proxy header be empty?
Hi @akostadinov
I believe it should be proto=https.
Nice catch! Yes, you are right. I made a mistake that the "upstream" protocol has been referred to fill the proto param.
https://github.com/junkurihara/rust-rpxy/blob/f0a6e7aa77e3a5098177c5495e74ab6a6b57ff96/rpxy-lib/src/message_handler/utils_headers.rs#L132
I will fix this shortly.
And btw, why not enable the feature by default and disable when requested? I think the standard header should be there by default.
The reasons why I didn't enable this by default are:
- The
forwardedheader is not widely used yet at backend applications, and the de-facto standard is stillx-forwarded-*as far as I know. - The
forwardedheader generation yields extra computational cost in the process of request forwarding. - The header generation might has bug (and you found a bug in fact...), and it also lacks the functionality of
by-param generation.
I actually hope to enable this by default in future release. But from the above reasons, I kept this an opt-in option.
P.S. unrelated question, should proxy header be empty?
This actually came from the nginx-proxy default setting, for mitigation of httpoxy attack.
https://github.com/nginx-proxy/nginx-proxy/blob/8f0c7ec6b15222d0965d08ae27f7aaf923986b1d/nginx.tmpl#L569C3-L571
So, the mitigation is done by unsetting the Proxy value.