Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to prevent caddy from automatically adding X-Forwarded-For header? #3976

Closed
cloudwindy opened this issue Jan 16, 2021 · 17 comments
Closed

Comments

@cloudwindy
Copy link

Quote from https://caddy.community/t/v2-reverse-proxy-transparent/6480/3:
It also adds X-Forwarded-For automatically.

But I don't want caddy to add X-Forwarded-For header, I want it to pass it through as-is. How can I achieve that?

@cloudwindy
Copy link
Author

I tried

reverse_proxy {
    to localhost:8080
    header_up X-Real-IP {remote_host}
    header_up X-Forwarded-For {header.X-Forwarded-For}
}

But that doesn't work.

@cloudwindy
Copy link
Author

cloudwindy commented Jan 16, 2021

Nginx works on localhost:8080 but it's unlikely to modify X-Forwarded-For itself.

My PHP test code:

<?php
echo nl2br('Remote Addr: ' . $_SERVER['REMOTE_ADDR'] . "\n");
echo nl2br('X-Real-IP: ' . $_SERVER['HTTP_X_REAL_IP'] . "\n");
echo nl2br('X-Forwarded-For: ' . $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n");
?>

@cloudwindy
Copy link
Author

Test steps:

  1. Start all related services (caddy2, nginx, php-fpm etc)
  2. Acess test.php from web browser
  3. Remote addr shows 127.0.0.1. That's OK.
  4. X-Real-IP shows your real ip. Works as expected.
  5. X-Forwarded-For also shows your real ip. Wait? I did't send caddy X-Forwarded-For!

My goal:
Only show X-Forwarded-For when you give caddy a X-Forwarded-For.

@mholt
Copy link
Member

mholt commented Jan 16, 2021

I think this happens because X-Forwarded-For has already been manipulated before user-configured header manipulations are applied. This is important so that deleting headers can be done successfully, if desired...

@packeteer
Copy link

can I ask why you want to remove that header?

@cloudwindy
Copy link
Author

can I ask why you want to remove that header?

MediaWiki was confused by X-Forwarded-For header but now it seems to work properly. Removing this header is not needed anymore.

@kbourro
Copy link

kbourro commented Apr 8, 2022

Did you find a way to remove X-Forwarded-For header ?

@mholt
Copy link
Member

mholt commented Apr 8, 2022

@kbourro Why do you need it removed? Good Proxies ™️ generally set it.

@Matchlighter
Copy link

@mholt (I'm running into this too) but bad apps don't process it right or worse trust it implicitly. I frequently use Caddy (or previously Nginx) in front of apps that don't handle auth/forwarded-for headers as I want.

@kbourro I've had success with overriding it like so: header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}. I'd think you could override it to blank and be good.

@francislavoie
Copy link
Member

bad apps don't process it right

What do you mean?

You should probably be filing a bug report with that app, then. Or stop using that app. Or patch it if possible.

or worse trust it implicitly

Well in that case you'll be glad to see that Caddy v2.5.0 doesn't implicitly trust incoming values for those headers. See the release notes.

I frequently use Caddy (or previously Nginx) in front of apps that don't handle auth/forwarded-for headers as I want.

Please be more specific. In what way does it not handle it as you want?

All that said, you can remove the header like this:

header_up -X-Forwarded-For

@Matchlighter
Copy link

I've got no control of some of the apps that I need to deploy, so I use a reverse proxy to handle auth/routing/header manipulation when I can't choose/fix the app. I did figure this out using the header_up and trusted_proxies - my post was meant to explain a use case (slash provide context since it wasn't previously clear why someone would need to do this) and a solution - not to further the question. I should have been more succinct on that!

@xmontero
Copy link

xmontero commented Aug 29, 2024

So at the end... Can we finally force remove the x-forwarded-for header and the like?

At my startup we are calling an API from a provider which is secured by them with an IP-restriction rule, among other mechanisms. So I need to give them a static IP. At the office we have dynamic IP. So in AWS I set a caddy to proxy the requests for that API so they come from an elastic-IP we have registered as "the IP" with the provider. Nevertheles at our startup we are inclined to implement zero-trust, so we treat the provider's API as an untrusted App.

So, to reduce our attack-surface, in aims to limiting the exposure of what's the current IP of the office, which is not needed for the API call, we want to remove it from the x-forwarded-for header.

@xmontero
Copy link

@mohammed90
Copy link
Member

xref https://stackoverflow.com/a/78927869/1315009

Your answer on SO is not accurate. Francis has already mentioned you can drop the header by using:

header_up -X-Forwarded-For

@xmontero
Copy link

Humm... I'm trying to do it from the command line and I get an error:

$ docker run -it --rm -p 7002:80 caddy caddy reverse-proxy --from :80 --to http://checkip.amazonaws.com:80 --change-host-header --header-up "-X-Forwarded-For"
Error: header-up 0: invalid format "-X-Forwarded-For" (expecting "Field: value")

Can this "drop header" be done from the command line?

@mohammed90
Copy link
Member

Can this "drop header" be done from the command line?

This is not currently possible via the command-line. You'll have to use the Caddyfile for such advanced operations.

@xtexChooser
Copy link

xtexChooser commented Sep 7, 2024

header_up -X-Forwarded-For just simply removes the header. Is there any way to keep the XFF from client?
I am in an architecture where there are two reverse-proxy and I have no access to the upper one (which faces users directly). So I have to pass the XFF from the upper RP, through caddy (the lower RP), to the backend.

btw the upper reverse-proxy (which accepts clients and sets XFF) has a dynamic IP behind NAT, so it is a bit hard to set trusted_proxies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants