rust-rpxy icon indicating copy to clipboard operation
rust-rpxy copied to clipboard

TODO: Support of `Forwarded` header

Open junkurihara opened this issue 2 years ago • 1 comments

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/

junkurihara avatar Dec 07 '23 02:12 junkurihara

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
  • 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

WDYT? Too much?

xkr47 avatar Nov 01 '24 22:11 xkr47

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?

akostadinov avatar Jul 07 '25 12:07 akostadinov

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 forwarded header is not widely used yet at backend applications, and the de-facto standard is still x-forwarded-* as far as I know.
  • The forwarded header 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.

junkurihara avatar Jul 08 '25 01:07 junkurihara