Reverse proxy: use upstream HTTPS proxy

1. The problem I’m having:

I have an upstream HTTPS proxy. How can I make a reverse_proxy to some website through this HTTPS proxy?
The goal is to have a reverse proxy to a website, which can’t be accessed directly, but can be accessed through another forward proxy.

2. Error messages and/or full log output:

None, my attempts just don’t proxy anything at all and return blank page.

3. Caddy version:

v2.7.4 h1:J8nisjdOxnYHXlorUKXY75Gr6iBfudfoGhrJ8t7/flI=

… with plugin github.com/caddyserver/forwardproxy@caddy2

4. How I installed and ran Caddy:

xcaddy build --with github.com/caddyserver/forwardproxy@caddy2

a. System environment:

PopOS

b. Command:

sudo ./caddy run --watch

d. My complete Caddy config:

localhost:8888 {
	route {
		forward_proxy {
			upstream https://USERNAME:PASSWORD@IP:PORT
		}
	}
}

localhost {
	reverse_proxy https://localhost:8888 {
		header_up Host wikidot.com
	}
}

Howdy @gardspirito, welcome to the Caddy community.

I’m sorry to say I don’t see how this would work, based on my understanding of the functionality involved.

It seems to me that the forward proxy chain should work just fine if you were to, for example, configure your browser to use it. Your browser knows how to control a forward proxy. The reverse proxy module, however, does not. I simply don’t think that functionality is accounted for.

From a technical perspective, my understanding is that a forward proxy client (e.g. your browser) operates by issuing a CONNECT command to the configured forward proxy, instructing it to open a tunnel to the desired resource. Once the tunnel is open, the client can issue HTTP verbs to the resource. I don’t think that Caddy’s reverse_proxy can be configured to follow this procedure, it’s simply not designed or implemented behaviour.

All the other moving parts - the localhost sites, the TLS management and trust, all of that seems to be working just fine. It’s just that the localhost site is sending a GET to the localhost:8888, but localhost:8888 is not configured to serve a website, only to act as a forward proxy, so I imagine it probably just sends blank 200 OK responses (because that’s Caddy’s default unconfigured behaviour).

1 Like

Thank you for your respond. Yeah, I actually expected this not to work, but what now? Can I substitute reverse_proxy with a hand-written plugin?

That’s not how forward_proxy works. You need to set the relevant environmental variables HTTP_PROXY and HTTPS_PROXY. reverse_proxy will automatically use proxy this way.

2 Likes
HTTP_PROXY=https://USERNAME:PASSWORD@IP:PORT HTTP_PROXY=https://USERNAME:PASSWORD@IP:PORT sudo ./caddy run --watch
2 Likes

So, if I understand it right - I’ve been informed the Go standard lib supports those env vars for its HTTP client - so essentially you could ditch the forward proxy component and instead reverse proxy directly to the “inaccessible” website, and set the HTTPS_PROXY variable to the upstream forward proxy (rather than the local forward proxy, no need to chain it), and the reverse proxy should use the forward proxy when making its upstream request, just like that. Weidi’s given you the usage.

I haven’t done this myself or seen it, so if you give it a shot, do let me know if it works!

Sorry for late response.

The idea with HTTP_PROXY might be great, but not all requests should be routed through this exact proxy.

If I want to modify Caddy source code or write a custom plugin to support this, where should I start? Should I make custom transport?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.