Does it make sense to offer finer control for strict_sni_host?

I’ll let smarter folks respond to the rest of your post, but if you’re mainly interested in keeping your logs clean, you can get a similar result with something like this:

{
	auto_https disable_redirects
}

*.example.com {
	tls internal
	abort
}

foo.example.com {
	log
	respond "Foo Site"
}

http://foo.example.com {
	redir https://{host}{uri} 308
}

http:// {
	abort
}
  • auto_https disable_redirects disables automatic HTTP-to-HTTPS redirects

  • The *.example.com block is just for obtaining the wildcard certificate. It doesn’t serve any data. I’m using tls internal here as an example. Use whatever tls directive you need.

  • foo.example.com is the only site actually serving content and logging requests.

  • The http://foo.example.com block (optional) handles HTTP-to-HTTPS redirection for foo.example.com. You can skip it if you don’t need that redirect.

  • The final http:// block drops all other HTTP traffic.

With this setup, unless someone specifically knows about foo.example.com, they won’t get anything meaningful from the server and your logs stay clean.

$ curl http://example.com
curl: (52) Empty reply from server

$ curl https://example.com
curl: (35) TLS connect error: error:0A000438:SSL routines::tlsv1 alert internal error

$ curl http://foo.example.com -I
HTTP/1.1 308 Permanent Redirect
Location: https://foo.example.com/
Server: Caddy
Date: Sun, 08 Feb 2026 04:35:28 GMT

$ curl https://foo.example.com
Foo Site

$ curl http://bar.example.com
curl: (52) Empty reply from server

$ curl https://bar.example.com
curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

$ curl http://localhost
curl: (52) Empty reply from server

$ curl https://localhost
curl: (35) TLS connect error: error:0A000438:SSL routines::tlsv1 alert internal error

The only one that ends up in the logs is:

curl https://foo.example.com

I’ve actually been using this setup well before Caddy 2.10.x. Back then, to get the same result, the config looked like this:

{
	auto_https disable_redirects
}

*.example.com {
	tls internal
	log

	@foo header host foo.example.com
	handle @foo {
		respond "Foo Site"
	}

	handle {
		log_skip
		abort
	}
}

http://foo.example.com {
	redir https://{host}{uri} 308
}

http:// {
	abort
}

This would serve and log only foo.example.com, while dropping everything else. The handle block catches unmatched requests and prevents log clutter, and the wildcard cert covers the domain.

3 Likes