Open jim3ma opened 6 years ago
When browse https://web.plus, caddy gives the vhost web.plus
which should be proxy.plus
.
The code: https://github.com/mholt/caddy/blob/master/caddyhttp/httpserver/server.go#L385
Thanks for the report! I am not sure when I'll be able to dive into this issue, and PRs are always welcome.
When browse https://web.plus, caddy gives the vhost
web.plus
which should beproxy.plus
. IIRC, vhost is determined byHost
header, which isweb.plus
.
The problem is most likely that Caddy receives:
CONNECT web.plus HTTP/1.1
Host: web.plus
which is proxying request that should have internally went to proxy.plus
, but Caddy matches it to web.plus
and sends it there for processing. Then the standard web.plus
chain of middleware won't know what to do with this wierd request. The fix will probably involve changes to the Caddy itself, I am not quite sure what would be an elegant solution.
/cc @mholt
P.S. as a temporary workaround you can try using PAC files, to make browser use DIRECT
connection to web.plus
and not send CONNECT requests to Caddy.
@jim3ma, what client software are you using?
@bemasc just Chrome with SwitchyOmega. @mholt can you consider to extend some config for caddy to match host customize ?
I think I know why this is happening. Caddy is programmed to handle requests by Host header, to choose the middleware chain it follows. For any Host that doesn't match one defined in the Caddyfile, it routes to a forwardproxy chain, if configured. But in this case, Caddy has a site defined for the Host name you're trying to access via a proxy.
How would Caddy know which middleware chain to use?
We could send all CONNECT
requests into middleware chain with forwardproxy
, but that doesn't integrate very well into current host matching logic of Caddy.
As an aside, here's another temporary workaround: add forwardproxy
to all your chains.
@mholt When chrome uses forwardproxy, chrome dials proxy.plus
with tls
. The tls connection knows the right host is proxy.plus
with SNI
, so when match vhost, Caddy should consider the SNI hostname
.
BTW, each vhost has the supported methods like POST, GET, DELETE. When match vhost, the supported methods should be considered.
@sergeyfrolov add forwardproxy to all chains
seems not work for proxy directive.
Caddy should consider the SNI hostname
Webservers generally don't do this, and there are setups that rely on this not being the case. Among other more general network configurations, the fact that webservers don't prioritize SNI in vhost matching is how Domain Fronting censorship circumvention technique works.
BTW each vhost has the supported methods like POST, GET, DELETE. supported methods should be considered
If supported methods are known for each vhost, then this might work. Currently, when forwardproxy
loads, it sets the chain it's in to be a fallback for unmatched hosts. We can disable CONNECTs on all vhosts but forwardproxy
ing one and allow CONNECT requests to be handled by fallback. As an added advantage, we would be able use FallbackHost
only for unmatched CONNECT requests, as opposed to current state of things in which all and every unmatched request goes into forwardproxy
ing chain.
How about a flag like -sni-first
that tells Caddy to try matching a site based on the SNI name and then, if there are no matches, to use the Host header instead?
The sni-first option is okay. So we did not hack the match method which always move traffic to forwardproxy.
e.g: We have a forwardproxy for https://proxy.plus
on host A
, and a web site https://web.plus ( different from proxy.plus )on the same host
with caddy. P.S. enable tls always.When browse the https://web.plus via https://proxy.plus proxy, chrome says "ERR_TUNNEL_CONNECTION_FAILED".
Other web sites work okay via https://proxy.plus.