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

Automatic HTTPS redirects inconsistent in combination with bindings #5660

Open
jorams opened this issue Jul 29, 2023 · 3 comments
Open

Automatic HTTPS redirects inconsistent in combination with bindings #5660

jorams opened this issue Jul 29, 2023 · 3 comments
Labels
bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed
Milestone

Comments

@jorams
Copy link

jorams commented Jul 29, 2023

What I want to achieve: For Caddy to serve some public sites to the internet over HTTPS with an automatic redirect from HTTP, and some private sites to a Tailscale (Headscale) network over plain HTTP.

I first tried to set it up like the following. (I've simplified the configuration a lot for local testing, but the problem is the same.)

# Public site
test.example {
	bind 127.0.0.1
	tls internal
	respond "Hello"
}

# Private site
http://test2.example {
	bind 100.64.0.6
	respond "World"
}

The result is Caddy listening on port 80 on 100.64.0.6, and port 443 on 127.0.0.1. The listener on port 80 will redirect to https://test.example.

Expand for test commands
# Not listening to port 80 on 127.0.0.1
$ curl --insecure --include --connect-to test.example:80:127.0.0.1:80 http://test.example/
curl: (7) Failed to connect to 127.0.0.1 port 80 after 0 ms: Couldn't connect to server

# Listening and redirecting on 100.64.0.6
$ curl --insecure --include --connect-to test.example:80:100.64.0.6:80 http://test.example/
HTTP/1.1 308 Permanent Redirect
...

This feels like a bug, but it can be explained based on the warning in the documentation for default_bind. The solution offered there (Also discussed in #5309) is to add an http:// site, like this:

# Public site
test.example {
	bind 127.0.0.1
	tls internal
	respond "Hello"
}

# Private site
http://test2.example {
	bind 100.64.0.6
	respond "World"
}

# Fix
http:// {
	bind 127.0.0.1
	respond "Fix"
}

Whether this solves the problem here is unpredictable every time Caddy gets restarted. The listener for the automatic redirects appears to be selected at random. (caddy adapt consistently returns the same JSON for this Caddyfile, so the inconsistency is not in the adaptation.)

Expand for test commands
# Start Caddy with the above Caddyfile

# 200 OK on 127.0.0.1
$ curl --insecure --include --connect-to test.example:80:127.0.0.1:80 http://test.example/
HTTP/1.1 200 OK
...
Fix

# 308 Permanent Redirect on 100.64.0.6
$ curl --insecure --include --connect-to test.example:80:100.64.0.6:80 http://test.example/
HTTP/1.1 308 Permanent Redirect
...

# Restart Caddy a few times without changing the Caddyfile

# 308 Permanent Redirect on 127.0.0.1
$ curl --insecure --include --connect-to test.example:80:127.0.0.1:80 http://test.example/
HTTP/1.1 308 Permanent Redirect
...

# 200 OK on 100.64.0.6 (but unrelated to the new catch-all http:// site)
$ curl --insecure --include --connect-to test.example:80:100.64.0.6:80 http://test.example/
HTTP/1.1 200 OK
...

My first attempted configuration did not specify bind for the public sites. I thought the warning about inconsistent binding in the documentation for bind could apply, but as you can see above specifying a non-overlapping binding does not fix it.

@mholt
Copy link
Member

mholt commented Jul 31, 2023

Thanks; I wonder if we're using a map somewhere and we lose the ordering. Will have to look into that.

@mholt mholt added bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed labels Jul 31, 2023
@mholt
Copy link
Member

mholt commented Jul 31, 2023

Thanks again for a thoroughly-researched issue. So my comment on the linked issue says:

This might suck, but maybe we should find all the addresses that use the HTTPS port and add the host portion of each of those addresses to the auto-redir server. i.e. a server configured to listen on "104.244.78.176:443", "127.0.0.1:443", "[2605:6400:30:f1ca::1]:443", "[::1]:443" would result in the auto-redir server listening on "104.244.78.176:80", "127.0.0.1:80", "[2605:6400:30:f1ca::1]:80", "[::1]:80".

We might need to do that 😬

Is it OK if we don't slide this into 2.7? Maybe 2.7.1... unless someone wants to whip up a PR for it, but I'm not sure if this would be easy or not.

@mholt mholt added this to the v2.7.1 milestone Jul 31, 2023
@jorams
Copy link
Author

jorams commented Aug 2, 2023

We might need to do that

That indeed seems like a good solution.

Is it OK if we don't slide this into 2.7?

Fine by me! I've worked around the issue with manual redirects.

@mholt mholt modified the milestones: v2.7.1, v2.7.2 Aug 3, 2023
@francislavoie francislavoie modified the milestones: v2.7.2, v2.7.3 Aug 3, 2023
@mholt mholt modified the milestones: v2.7.3, v2.7.4 Aug 3, 2023
@mholt mholt modified the milestones: v2.7.4, 2.7.5 Aug 14, 2023
@francislavoie francislavoie modified the milestones: v2.7.5, v2.9.0 Oct 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants