Client certificate on subdomain ends up counting for all domains

Hi there.

I have a Caddyfile like this:

cognitive.io {
        proxy / localhost:5551 {
            transparent
        }
        root /opt/somefolder                                                                          
        log stdout
        errors stderr
        tls magicalemailhere@flexd.net                                              
}

And this works. And I should be able to add another subdomain here, or another domain entirely.

If I append

        x.rxd.no { 
                proxy / localhost:5551 {
                    transparent
                }
                tls /etc/ssl/caddy/rxd.no.cert.pem /etc/ssl/caddy/rxd.no.key.pem {
                }
        }

to my Caddyfile, that should just point x.rxd.no to the same proxy, and serve the same website, using my own certificate.

That does not work, and tells me there is no such site on :80, or no such site at :443.
Specify https://x.rxd.no I can get it to work, but it still complains about :80.

Am I doing something wrong?

The issue I came here to ask about was that if I specify a client certificate CA there, like so:

            tls /etc/ssl/caddy/rxd.no.cert.pem /etc/ssl/caddy/rxd.no.key.pem {
               clients /etc/ssl/caddy/ca-chain.key.pem
            }

It will successfully require a client certificate, like expected, but it does so for all the domains, even outside that block, i.e in this example it would also require a client side certificate for cognitive.io

Hi @flexd, welcome to the Caddy community.

The reason for this is that Caddy will be serving the site on :2015. This is the default port, and any site that isn’t eligible for Automatic HTTPS is served here unless you specify a different port (as you have implicitly with https://). From the docs:

Caddy automatically enables HTTPS for all your sites, given that some reasonable criteria are met:

  • […]
  • Certificates and keys are not provided by you

Since Automatic HTTPS handles certificate management, defines the ports for a site to be served on, and sets up HTTP->S redirection, you’ll need to take care of those things yourself, e.g.:

http://x.rxd.no {
  redir / https://x.rxd.no{uri}
}
https://x.rxd.no {
  proxy / localhost:5551 {
    transparent
  }
  tls /etc/ssl/caddy/rxd.no.cert.pem /etc/ssl/caddy/rxd.no.key.pem {
    clients /etc/ssl/caddy/ca-chain.key.pem
  }
}

One thing that you might consider useful is that at startup, Caddy will print a list of all the sites it’s serving, to stdout as well as wherever you point the -log flag. It would have printed http://x.rxd.no:2015.

https://caddyserver.com/docs/cli

Okay, that is weird. Why would the Let’s Encrypt automatic TLS take care of all that, but I specify the same option just for a manual certificate and it does not? That is very confusing.

It works now, but the last issue still remains: If I specify the client certificate it now demands a client certificate from every domain in my Caddyfile, not just x.rxd.no. i.e visit https://cognitive.io with this active and it will require a client certificate there too. (this is not active on the website currently, for obvious reasons :))

Sometimes we do observe some friction on this topic. It’s been raised before, here and in the Github issues.

I believe the reason is that Caddy is effectively designed with three main use cases in mind:

  1. Local web devs who want an instant, zero configuration web server
    (i.e. change a file; run caddy browse inside public_html; browse to localhost:2015)
  2. System Administrators who know what they’re doing and want fine-grained control
  3. Users who want their front-facing site security completely taken care of

Making assumptions (such as port to listen on, or automatic redirections) is bad for use cases 1 and 2. If you qualify for use case 3 (that is, if your site is eligible for Automatic HTTPS), that’s when these critical assumptions start kicking in as a take-it-or-leave-it sort of configuration package:

  • You want your site to be available via HTTP on port 80 and HTTPS on port 443
  • You want requests via HTTP be redirected to HTTPS
  • You want Caddy to provision a domain-validated certificate from LetsEncrypt

This seems to be the expected behaviour. From the tls documentation, emphasis mine:

  • clients is a list of space-separated client root CAs used for verification during TLS client authentication. […] Note that this setting applies to the entire listener, not just a single site.

It’s not confusing; if you disable automatic HTTPS then the automatic HTTPS features don’t happen. :face_with_raised_eyebrow:

The client certificate configuration is applied on a per-listener basis, not per-site. There’s an open issue to expand client certificate capabilities, made available only in recent Go versions.

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