Caddy: Transparent proxy not appending existing X-Forwarded-For header

Created on 16 Nov 2017  路  9Comments  路  Source: caddyserver/caddy

1. What version of Caddy are you using (caddy -version)?

Caddy 0.10.10 (non-commercial use only)

2. What are you trying to do?

Use Caddy as a transparent proxy, passing all the IP addresses along the proxy chain to the web app.

3. What is your entire Caddyfile?

https://example.net {
        log     syslog
        errors  syslog
        gzip
        proxy   /        127.0.0.1:8080 {
                transparent
        }
}

4. How did you run Caddy (give the full command and describe the execution environment)?

Caddy is started with the systemd service.

5. Please paste any relevant HTTP request(s) here.

Execute this on machine 3.3.3.3

curl -H "X-Forwarded-For: 1.1.1.1,2.2.2.2" https://example.net/print-headers

6. What did you expect to see?

The actual web app should receive:

X-Forwarded-For: 1.1.1.1,2.2.2.2,3.3.3.3

7. What did you see instead (give full error messages and/or log)?

The web app received instead:

X-Forwarded-For: 3.3.3.3

8. How can someone who is starting from scratch reproduce the bug as minimally as possible?

  1. Set up a simple web server that logs HTTP headers on port 8080 (actually a simple netcat -lp8080 will do).
  2. HTTPS should not affect this issue, so change the Caddyfile to use HTTP only
  3. Replace example.net with localhost
bug

Most helpful comment

PR time #2105

All 9 comments

I haven't tested it, but I think you might be able to fix this by doing:

header_upstream +X-Forwarded-For {remote}

Where the + will append to the header instead. This probably means that you can't use transparent though because it already has a rule in there. transparent is just a shorthand. So altogether, replace transparent with:

header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream +X-Forwarded-For {remote}
header_upstream X-Forwarded-Proto {scheme}

Do know that technically that can be insecure, because any malicious request can set X-Forwarded-For headers and here, you would be "trusting" those IP addresses... so make sure that only trusted requests can get routed to your server.

@mholt helped me find the relevant code for this issue:

https://github.com/mholt/caddy/blob/master/caddyhttp/proxy/proxy.go#L348

At a glance, I think it should work for your case, but I'm not sure why it doesn't.

I think this is indeed a bug.

First we will append X-Forwarded-For header if any at here,
then if we use transparent shorthand, it will mutate the upstream header before roundtrip,
so it will ignore previous X-Forwarded-For header we set above because we just use the rule replacing the header at here.

I suggest we could just remove X-Forwarded-For rule from the transparent shorthand, because we always set X-Forwarded-For here.

Proposed solution looks good. When can we see it implemented and released?

@MOZGIII As soon as someone submits a pull request or a customer purchases extended support to expedite its completion -- I probably can't get to this for a while myself.

Here's my "poor man's PR", as a starting point.

Hey, can I tackle this using @tw4452852 recommendation?

Yes

PR time #2105

Was this page helpful?
0 / 5 - 0 ratings

Related issues

klaasel picture klaasel  路  3Comments

lorddaedra picture lorddaedra  路  3Comments

dafanasiev picture dafanasiev  路  3Comments

mikolysz picture mikolysz  路  3Comments

mholt picture mholt  路  3Comments