Caddy - Context deadline exceeded

Fixed the logging issue. Now I see the following when I access jatra.club -

{"level":"debug","ts":1705077331.7863536,"logger":"tls","msg":"certificate issuance denied","ask_endpoint":"http://localhost:5001/caddy/ask","domain":"jatra.club","error":"jatra.club: certificate not allowed by ask endpoint http://localhost:5001/caddy/ask - non-2xx status code 404"}
{"level":"debug","ts":1705077331.7864332,"logger":"http.stdlib","msg":"http: TLS handshake error from 49.36.35.175:57965: certificate is not allowed for server name jatra.club: decision func: jatra.club: certificate not allowed by ask endpoint http://localhost:5001/caddy/ask - non-2xx status code 404"}

Obviously, the endpoint is failing. I am not sure how’d Laravel access that route.

How are your Laravel routes configured? Are they matching by hostname? If so, you’ll need to make your hostname matching also allow localhost for this case.

Regular routing like:

Route::get('/caddy/ask/', [/path/to/controller::class])

It doesn’t seem to work that way, if I change it to https://localhost/caddy/ask.

PS: Shouldn’t it be a common problem with all the installations that if the certificate of the main domain expires, Caddy enters a chicken-egg problem with certificates.

Not sure what’s the way out here.

Addendum: I think the better solution here could be that the main domain’s certificate are handled separately and the subdomains are handled through ask_endpoint. The main domain would be treated as any other regular domain that caddy automatically manages SSL for.

No, most users use an internal route (like localhost:5001 or whatever) for their ask endpoint. And most don’t enable on-demand for their main domain (because you should not enable on-demand for domains that you know ahead of time, only for ones you don’t know).

Are you sure there isn’t somekind of middleware that would cause the request to be rejected? Are you sure jatra.club is actually allowed by your controller?

  1. I need to allow my users to create their own subdomain (and later point their CNAMEs to it). That’s the reason I have on-demand. I save the allowed subdomain in my database and check it via the /caddy/ask endpoint.

  2. The /caddy/ask endpoint isn’t under any middleware. Jatra.club is allowed by my controller. To test, I temporarily changed the ask endpoint to https://google.com (not a good idea) and noticed that subdomains quickly become available: viz. https://community.jatra.club works . But the main https://jatra.club domain still is unavailable.

Is jatra.club in your database? If not, it should be (unless you move that domain to a separate site block which doesn’t have on_demand)

Yes, it’s programmed to return 200 for jatra.club and the allowed subdomains.

Well, clearly it’s returning 404, so something’s wrong in your app. You’ll need to drill down to find the problem.

@francislavoie - Could you please let me know how did you get the non-2xx status code 404 error? I need to reproduce it.

If I hit the route: http://jatra.club/caddy/ask?domain=jatra.club then Caddy automatically redirects it to https://... and throws ERR_SSL_PROTOCOL_ERROR.

Note: I’ve switched back to the /caddy/ask endpoint.

I wish to know if this makes sense:

http://localhost:8080 {
	root * /home/forge/jatra.club/public
	php_fastcgi unix//run/php/php8.2-fpm.sock
}

I am afraid that Laravel will begin creating duplicate routes (and pages) -

  • jatra.club/
  • localhost:8080/

Questions:

  1. Isn’t there a way to handle the main domain (jatra.club) separately and subdomains via the ask_endpoint.

  2. Why is Caddy hitting the ask_endpoint for every request? I guess ask_endpoint is only checked when there is a SSL demand for new subdomain.

PS: I really appreciate your support on this query. It’s driving me nuts and my main site is not available. :frowning:

That’s from your own logs that you showed earlier.

You can test by running curl -v http://localhost:5001/caddy/ask?domain=jatra.club on your server.

That’s not a thing. There’s only one set of route definitions in your Laravel app.

Yes, I’ve said that multiple times, you can make a separate site block for that domain without on-demand enabled.

It’s only hit when Caddy doesn’t have a certificate in cache for that domain.

@francislavoie - I really appreciate your support. I was finally able to fix the issues and get the site working as expected with a few changes.

I added the following lines to the :5001 block:

try_files {path} /index.php?{query}
file_server

I’m pasting my Caddyfile below and would really appreciate it if you could help me optimize it. I wish to know how would you go about configuring the below Caddyfile -

{
	on_demand_tls {
		ask http://localhost:5001/caddy/ask
		interval 2m
		burst 5
	}
	# Global logging settings
	log {
		output file /var/log/caddy/access.log {
			roll_size 100mb # Max size of a log file before it's rolled
			roll_keep 5 # Number of rolled files to keep
			roll_keep_for 720h # Duration to keep rolled files
		}
	}
}

:5001 {
	root * /home/forge/jatra.club/public
	php_fastcgi unix//run/php/php8.2-fpm.sock
	try_files {path} /index.php?{query}
	file_server
}

# Main domain and all subdomains
https://jatra.club, https://*.jatra.club {
	tls {
		on_demand
	}

	root * /home/forge/jatra.club/public
	encode gzip
	file_server
	php_fastcgi unix//run/php/php8.2-fpm.sock
	header {
		# Ensure the header specifying the original host is passed to PHP
		X-Original-Host {host}
	}
}

# Catch-all for any other domain (for your customer's custom domains)
https:// {
	tls {
		on_demand
	}

	root * /home/forge/jatra.club/public
	encode gzip
	file_server
	php_fastcgi unix//run/php/php8.2-fpm.sock
	header {
		# Ensure the header specifying the original host is passed to PHP
		X-Original-Host {host}
	}
}

I don’t think this part is necessary. The php_fastcgi directive already does this. See the docs, which explain how php_fastcgi work.

Also, you shouldn’t need file_server because you’re not going to be serving static files from that server, only PHP. But either way, no harm.

Again, you can remove this, it does absolutely nothing of value. It’s only adding the host to responses (not to requests) being written back to the client. The comment is incorrect, it’s not passing anything to PHP at all.

Thanks. I"ll try removing this and see if works. The real deal, I guess was moving the route to the actual routes.php file and not calling another routes file which contained the path in it. Not sure why’d it fail; but that’s what worked.

Also, do you think this part https://*.jatra.club is necessary in the following block?

# Main domain and all subdomains
https://jatra.club, https://*.jatra.club {

Also, the catch all block https:// { ..} is it adding any value?

Btw, I wish to understand the order of blocks caddy a request will see once the request hits it. My best guess is that, whenever there’s an HTTPS request for the main domain: jatra.club, caddy’s straightway hitting the https:// {..} block and when there’s a request for subdomain, it’s handling it via the global block at the top.

Is that right?

Probably because of middleware (as I mentioned earlier). Check your Kernel & config, some route files have middleware automatically applied.

Probably not. In fact, you probably don’t need that entire site block.

I’ve said this before in a previous thread, but it would be better to use the ACME DNS challenge for your wildcard, because then you’d only have one certificate for all of *.jatra.club instead of an infinite amount (one per subdomain). But of course that adds some complexity to the setup (needing a DNS plugin for Caddy).

Are you only doing subdomains, or are you also doing custom domains? Like, are you allowing your customers/users to register jatra.example.com or whatever? If so then you absolutely do need https:// to catch those.

Site blocks are sorted by specificity, so https:// will always go last.

No, not at all, it hits your jatra.club site block, because it’s the most specific rule for that hostname.

The global options are not a site block. They’re global options. Settings Caddy-wide. It doesn’t handle requests.

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