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

Only the first visited https domain resolves correctly. #66

Closed
thenbe opened this issue Jun 7, 2024 · 5 comments
Closed

Only the first visited https domain resolves correctly. #66

thenbe opened this issue Jun 7, 2024 · 5 comments

Comments

@thenbe
Copy link

thenbe commented Jun 7, 2024

https://foo.tailf123a.ts.net {
	bind tailscale/foo
	reverse_proxy localhost:3000
}

https://bar.tailf123a.ts.net {
	bind tailscale/bar
	reverse_proxy localhost:5000
}

Two domains are declared in the previous caddyfile. After starting caddy, only the first domain I visit will resolve correctly. The second one will never resolve. For example:

  1. Start caddy.
  2. Go to https://foo.tailf123a.ts.net
  3. Caddy does its tls thing and I'm able to connect.
  4. Now go to https://bar.tailf123a.ts.net.
  5. Caddy this time tries to do a http-01 challenge. This always fails. We are unable to connect https://bar.tailf123a.ts.net.

If we restart caddy, and visit https://bar.tailf123a.ts.net first, then it works. But then we can never conenct to https://foo.tailf123a.ts.net because that will do a http-01 challenge which fails.

If we declare 3 tailscale https domains in the caddyfile, the first one we visit will resolve correctly and the other 2 always fail.

@willnorris
Copy link
Member

I'll work on testing and reproducing, but I'm curious what happens if you manually specify the tailscale cert manager for each site:

https://foo.tailf123a.ts.net {
	bind tailscale/foo
	tls {
		get_certificate tailscale
	}
	reverse_proxy localhost:3000
}

https://bar.tailf123a.ts.net {
	bind tailscale/bar
	tls {
		get_certificate tailscale
	}
	reverse_proxy localhost:5000
}

Since you have the full hostname you shouldn't actually need that, but given that it's falling back to an http-01 challenge, it seems like the tailscale cert manager isn't getting used.

@willnorris
Copy link
Member

willnorris commented Jun 7, 2024

Okay, I can definitely reproduce and I see the same http-01 challenge for the second site. It doesn't appear that manually setting the cert manager helps, which is weird. The simplest complete config I've got to reproduce the error:

{
  debug
  tailscale {
    ephemeral # create all nodes as ephemeral
  }
}

:443 {
  bind tailscale/caddytest
  tls {
    get_certificate tailscale
  }
  respond "Hello from caddytest"
}

:443 {
  bind tailscale/caddytest2
  tls {
    get_certificate tailscale
  }
  respond "Hello from caddytest2"
}

Debug output shows caddy trying to do http-01 then tls-apln-01 challenges. This looks like a caddy bug, but I'm still digging into it.

/cc @mholt @mohammed90 as fyi

@thenbe
Copy link
Author

thenbe commented Jun 7, 2024

Yup I get the same results you did when I specify the tailscale cert manager for each site.

Meanwhile, if anyone else encounters this issue they can use this workaround for now:

{
  auto_https off
}

:80 {
	bind tailscale/foo
	reverse_proxy localhost:3000
}

:443 {
	bind tailscale+tls/foo
	reverse_proxy localhost:3000
}

:80 {
	bind tailscale/bar
	reverse_proxy localhost:5000
}

:443 {
	bind tailscale+tls/bar
	reverse_proxy localhost:5000
}

@willnorris
Copy link
Member

willnorris commented Jun 7, 2024

okay, I've found the problem. While the localAPIDialer I added does correctly find the right tsnet server to connect to, it's only ever dialed on first connection (tscert only builds a single client).

We could possibly have localAPIDialer return a net.Conn that muxes reads and writes to the correct backend, but there's no context to mux on at that point. So I'm not immediately sure how I'll fix this 😕

Edit: instead of having a muxing net.Conn, I went the other way and added support to tscert to allow overriding the http.Transport.

willnorris added a commit to tailscale/tscert that referenced this issue Jun 7, 2024
This allows callers an alternative to overriding the tailcaled dialer.

Updates tailscale/caddy-tailscale#66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit that referenced this issue Jun 7, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Updates #19
Updates #53
Updates #66
willnorris added a commit that referenced this issue Jun 7, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66
willnorris added a commit that referenced this issue Jun 7, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit that referenced this issue Jun 7, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit that referenced this issue Jun 7, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit that referenced this issue Jun 7, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit to tailscale/tscert that referenced this issue Jun 8, 2024
This allows callers an alternative to overriding the tailcaled dialer.

Updates tailscale/caddy-tailscale#66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit to tailscale/tscert that referenced this issue Jun 8, 2024
This allows callers an alternative to overriding the tailcaled dialer.

Updates tailscale/caddy-tailscale#66

Signed-off-by: Will Norris <will@tailscale.com>
willnorris added a commit to willnorris/caddy that referenced this issue Jun 8, 2024
The latest tscert allows callers to provide a custom http.Transport for
calling Tailscale's local API.

Updates tailscale/caddy-tailscale#66
willnorris added a commit that referenced this issue Jun 8, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66

Signed-off-by: Will Norris <will@tailscale.com>
mholt pushed a commit to caddyserver/caddy that referenced this issue Jun 10, 2024
The latest tscert allows callers to provide a custom http.Transport for
calling Tailscale's local API.

Updates tailscale/caddy-tailscale#66
willnorris added a commit that referenced this issue Jun 18, 2024
This provides an http.RoundTripper implementation that dynamically
routes requests to the correct tsnet server's LocalAPI based on the
ClientHelloInfo in the context.

Previously, we were just overriding the tscert Dialer. That worked fine
the first time it dialed a LocalAPI, and would correctly dial the right
tsnet server. However, tscert caches the Transport with that Dialer, so
requests that should be routed to different tsnet servers would be
routed incorrectly.

Updates #19
Updates #53
Updates #66

Signed-off-by: Will Norris <will@tailscale.com>
@willnorris
Copy link
Member

I think we can mark this as fixed by #67

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

2 participants