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

3 second timeout for requests when using listener_wrappers tls sending requests to reverse_proxy #274

Closed
Monviech opened this issue Dec 6, 2024 · 8 comments · Fixed by #282
Labels
bug Something isn't working

Comments

@Monviech
Copy link

Monviech commented Dec 6, 2024

Downstream report: opnsense/plugins#4384

The issue is, that when something is going through the layer4 listener_wrappers to the tls directive into the reverse proxy, there is a timeout of 3 seconds after which the context gets canceled.

  • It does NOT happen with only the "reverse_proxy" proxying the request
  • It does NOT happen with only the layer4 modules "proxy" proxying the request

As example, there is an API endpoint in OPNsense that could take anywhere from 10 to 30 seconds to respond, depending on different factors. After exactly 3 seconds this context gets canceled by the client (Caddy) using this Caddyfile:

{
	servers {
		protocols h1 h2 h3
		listener_wrappers {
			layer4 {
			}
			tls
		}
	}
}

:80 {
}
:443 {
}

opn.example.com {
	handle {
		reverse_proxy https://172.16.0.254:4444 {
			transport http {
				tls_insecure_skip_verify
			}
		}
	}
}

Relevant error can be seen in downstream report.
I have tested this and can reproduce it.

@mholt
Copy link
Owner

mholt commented Dec 6, 2024

Hmm I'm wondering if there's a timer of 3 sec set anywhere in the code. Can look more into it soon!

@Monviech
Copy link
Author

Monviech commented Dec 6, 2024

The only default I found with exactly 3 seconds was dial_timeout but that was a caddyserver directive in http_transport

(solely looking at the documentation)

@mohammed90
Copy link
Collaborator

It's this

const MatchingTimeoutDefault = 3 * time.Second

which is injected here

lw.compiledRoute = lw.Routes.Compile(lw.logger, time.Duration(lw.MatchingTimeout), listenerHandler{})

and set here:

caddy-l4/layer4/routes.go

Lines 122 to 123 in 3c6cc2c

// timeout matching to protect against malicious or very slow clients
err := cx.Conn.SetReadDeadline(deadline)

@mholt
Copy link
Owner

mholt commented Dec 6, 2024

Good find. Yeah, so it sounds like after 3 seconds, matchers are being cancelled. I wonder if that's because there are no matchers configured?

@mohammed90
Copy link
Collaborator

matchers are being cancelled. I wonder if that's because there are no matchers configured?

My understanding is the timeout of the matchers is wrongly passed to the connection read deadline. The timeout deadline isn't updated after matching.

@mohammed90
Copy link
Collaborator

I take it back. It's reset here.

err = cx.Conn.SetReadDeadline(time.Time{})

I don't know why it isn't taking effect.

@WeidiDeng
Copy link
Contributor

@Monviech Can you test if this fixes it?

@Monviech
Copy link
Author

Monviech commented Jan 2, 2025

@WeidiDeng I confirm it's working. Thank you for your fix. 👍

@mholt mholt closed this as completed in #282 Jan 2, 2025
@mholt mholt added the bug Something isn't working label Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants