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

V2: reverse proxy transparency #2873

Closed
sosodev opened this issue Nov 9, 2019 · 21 comments
Closed

V2: reverse proxy transparency #2873

sosodev opened this issue Nov 9, 2019 · 21 comments
Labels
feature

Comments

@sosodev
Copy link

@sosodev sosodev commented Nov 9, 2019

1. What would you like to have changed?

In Caddy V1 you could specify transparent with the proxy directive to set the appropriate headers for an app running behind the reverse proxy. In Caddy V2 this seems to be missing meaning you have to set the headers manually, just a little inconvenient.

2. Why is this feature a useful, necessary, and/or important addition to this project?

It makes running an app behind a reverse proxy with Caddy, something that's already pretty easy, even easier! Most apps respond to the forwarding headers correctly and that means a lot of reduced headache for devs using Caddy V2.

3. What alternatives are there, or what are you doing in the meantime to work around the lack of this feature?

As mentioned before you can just add the headers yourself like

reverse_proxy {
    header_up X-Forwarded-Proto https
    etc
}

so it's not critical by any means just some QOL

@sosodev sosodev added the feature label Nov 9, 2019
@mholt mholt added the v2 label Nov 10, 2019
@mholt mholt added this to the 2.0 milestone Nov 10, 2019
@mholt
Copy link
Member

@mholt mholt commented Nov 10, 2019

Hm, yeah, I guess this would be nice to have huh.

In v1, the transparent shortcut does the following:

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

Do you like what behavior it hides from you?

@Immortalin
Copy link

@Immortalin Immortalin commented Nov 10, 2019

@mholt random question, does the reverse-proxy command in Caddy V2 include WebSockets?

@pascalgn
Copy link
Contributor

@pascalgn pascalgn commented Nov 10, 2019

I thought about this feature when implementing #2801 but in the end decided against it. IMO it's better to specify the headers manually. It would be a good thing to add this to the documentation, though, especially to help people who are coming from v1

@mholt
Copy link
Member

@mholt mholt commented Nov 11, 2019

@Immortalin Yes websockets work without needing any extra config, because all headers from downstream are copied into the upstream.

@Immortalin
Copy link

@Immortalin Immortalin commented Nov 12, 2019

@mholt thanks!

@atonse
Copy link

@atonse atonse commented Nov 14, 2019

I'm trying to figure this out at the moment setting up Caddy 2 and all I'm finding that the original, elegant configuration of Caddy seems to be replaced with this unnecessary new config system that just looks no different from apache (at this point nginx is more elegant, and it was always more elegant than apache). Is there really any benefit to all this new config? What happened to the elegant one-liners? That was the whole appeal of Caddy, curated and well-thought-out defaults.

The documentation only shows JSON but it is very hard for those of us who want the terse and very simple best-practice based config and don't want to define everything.

I've got this:

mysite.com {
  reverse_proxy * {
    to localhost:3000
  }
}

But that's not really working and is giving me a 502 gateway error even though I can easily access localhost:3000 using curl.

Update: I got this working by restarting instead of reloading. I'm not sure reload is working properly. The config above is what was not getting picked up in the reload. Should I create a separate Issue?

@Immortalin
Copy link

@Immortalin Immortalin commented Nov 14, 2019

TOML would be a good choice of a config language

@mholt
Copy link
Member

@mholt mholt commented Nov 14, 2019

@atonse

I'm trying to figure this out at the moment setting up Caddy 2 and all I'm finding that the original, elegant configuration of Caddy seems to be replaced with this unnecessary new config system that just looks no different from apache (at this point nginx is more elegant, and it was always more elegant than apache). Is there really any benefit to all this new config? What happened to the elegant one-liners? That was the whole appeal of Caddy, curated and well-thought-out defaults.

The documentation only shows JSON but it is very hard for those of us who want the terse and very simple best-practice based config and don't want to define everything.

Please be patient as we build new documentation for v2. What you are seeing is not the final product. We are still in beta, remember. That said, I am glad you are trying Caddy 2 -- thank you for using it while it's still in beta.

I can assure you that Caddy 2 will preserve the same easy-to-use-ness and good defaults as Caddy 1, but with many improvements and enhancements.

You should be able to simplify your config to:

mysite.com
reverse_proxy localhost:3000

which is simpler than in Caddy 1.

You don't even need a config file for this:

$ caddy reverse-proxy --from mysite.com --to localhost:3000

(I think, I haven't tested this CLI command as much yet. But you might try it out)

@Immortalin

TOML would be a good choice of a config language

Feel free to contribute a config adapter! Just like @iamd3vil did here for YAML: #2876 (comment) -- it'd be like 20 lines of code.

@atonse
Copy link

@atonse atonse commented Nov 14, 2019

Thank you @mholt – yes it's good to remind me that it's a beta. :-)

I agree that the main issue is probably more on the doc side, since it focuses on JSON configuration.

Regarding not needing a config file, I'm eventually going to run about 9 different sites (as 9 docker containers) as reverse proxies and I didn't really want to run 9 copies of Caddy (and 9 systemd units), which is why I didn't go the command line route.

@aeroxy
Copy link

@aeroxy aeroxy commented Jan 31, 2020

How can we achieve header_upstream Host {host} in V2, this doesn't seem to work:

caddy.com:443 {
  tls /etc/certs/caddy.crt /etc/certs/caddy.key
  reverse_proxy /caddy 127.0.0.1:8443 {
    header_up Host {host}
    transport http {
      tls
    }
  }
}

@pascalgn
Copy link
Contributor

@pascalgn pascalgn commented Jan 31, 2020

Possibly try

    header_up Host {http.request.hostport}

@aeroxy
Copy link

@aeroxy aeroxy commented Jan 31, 2020

Possibly try

    header_up Host {http.request.hostport}

hostport sounds like, hostport

Did you mean http.request.host?

@pascalgn
Copy link
Contributor

@pascalgn pascalgn commented Jan 31, 2020

I think in most cases both will work, but to be completely safe, Host should contain hostname + port: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host ({http.request.hostport} will resolve to e.g. example.com:8080)

@DoTheEvo
Copy link

@DoTheEvo DoTheEvo commented Feb 26, 2020

yes, please add transparent proxy keyword... I am writing some basic how-to caddy with examples, and bam suddenly nice readable config has shitload of boilerplate code if there is desire to forward stuff, which mostly is.

@mholt mholt removed this from the 2.0 milestone Feb 27, 2020
@mholt mholt added this to the v2.0.0-beta.15 milestone Feb 27, 2020
@mholt
Copy link
Member

@mholt mholt commented Feb 27, 2020

Done

@mholt mholt closed this as completed Feb 27, 2020
@mholt
Copy link
Member

@mholt mholt commented Feb 27, 2020

Actually, I was too hasty.

"Transparent mode" is the default in v2 already: the Host header will go to the upstream unmodified. X-Forwarded-For is also added for you. Other headers like X-Real-Ip and X-Forwarded-Proto can be added manually... for now, that's how it is anyway.

The idea is that, by default, Caddy 2 passes headers thru, allowing you to more easily make any changes without first having to undo Caddy's hidden changes.

I'm going to revert that commit, since transparent mode is default already, so the transparent keyword is mostly useless. If you need the other headers, you can just add them yourself. But not all apps need those.

If you want the upstream Host header to be the actual upstream's host, you can do:

header_up Host {http.reverse_proxy.upstream.hostport}

Which is more like the v1 proxy's default.

@athei
Copy link

@athei athei commented Jul 15, 2020

It is nice and all that this headers are automatically added. But there seems no way to remove them. This for example does not work:

reverse_proxy http://127.0.0.1:8989 {
    header_up -X-Forwarded-For
    header_up -X-Forwarded-Proto
}

@francislavoie
Copy link
Member

@francislavoie francislavoie commented Jul 15, 2020

@athei Thanks for pointing that out, could you please open a new issue for this?

@athei
Copy link

@athei athei commented Jul 16, 2020

@athei Thanks for pointing that out, could you please open a new issue for this?

#3584

@NightMachinery
Copy link

@NightMachinery NightMachinery commented Jul 28, 2020

Actually, I was too hasty.

"Transparent mode" is the default in v2 already: the Host header will go to the upstream unmodified. X-Forwarded-For is also added for you. Other headers like X-Real-Ip and X-Forwarded-Proto can be added manually... for now, that's how it is anyway.

The idea is that, by default, Caddy 2 passes headers thru, allowing you to more easily make any changes without first having to undo Caddy's hidden changes.

I'm going to revert that commit, since transparent mode is default already, so the transparent keyword is mostly useless. If you need the other headers, you can just add them yourself. But not all apps need those.

If you want the upstream Host header to be the actual upstream's host, you can do:

header_up Host {http.reverse_proxy.upstream.hostport}

Which is more like the v1 proxy's default.

@mholt Is X-Forwarded-For set to the HTTP request’s originating IP or does it use the same header of the request? I’m asking because I am relying on the X-Forwarded-For to show the real IP of the request in my backend, and the original request’s X-Forwarded-For can be easily spoofed by the requester.

@francislavoie
Copy link
Member

@francislavoie francislavoie commented Jul 28, 2020

Both. Caddy appends the originating IP to the header if it already exists.

https://github.com/caddyserver/caddy/blob/e9b1d7d/modules/caddyhttp/reverseproxy/reverseproxy.go#L472-L480

For next time, please ask your questions on the forums instead of on old closed issues. https://caddy.community

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

No branches or pull requests

10 participants