I’m trying to get caddy with mTLS to work correctly. When I provide my client certificate with a trusted_leaf_cert_file directive, the process works without a hitch. If I try to use trust_pool and provide either the root or intermediate CA for the client certificate, validation fails.
2. Error messages and/or full log output:
Browser throws ERR_BAD_SSL_CLIENT_AUTH_CERT when trying to connect in a Caddyfile that only has the trust_pool directive (see configs below).
Took a look at Client cert auth using trust_pool and I’ve verified my files are correct (leafs are leafs, trust pool certs are Root CA and intermediate CA)
I’m not able to replicate your experience. Are you sure the leaf certificate is descendant from the configured intermediate and root?
Moreover, this log message is only possible if you use the trusted_leaf_cert or trusted_leaf_cert_file sub-sub-directives of the tls directive. Those directives aren’t in your config. Are you sure the config you’re running is the same one you think is running?
Thanks for the reply Mohammed. I simplified my config a little to the minimal example that fails (I also removed the acme configuration line for let’s encrypt to not share credentials). But I did take the logging later from my normal configuration which has several trusted_leaf_cert_file which do work.
Most of the TLS logging I saw with debug were regarding picking the server certificate to return to the client. But for the validation of client, I couldn’t find much.
Is there a way to get additional logging on the certificate validation process? Maybe using an xcaddy build?
You say you’re experiencing this via a browser. Browsers are troublesome because they have all kinds of cache. If you can make it fail with curl, that’d be great. The command would be something as follows:
Most browsers nowadays allow you to copy a request line of the Network tab as curl command. While trying curl, check Caddy logs on the other end and share those logs without redactions (except for obvious credentials).
So… This is when computers drive me crazy. I figured out the problem. The curl command really came in handy.
The issue was: if there are any trusted_leaf_cert_file in the client_auth directive, it will ignore the trust_pool directive and only validate against the leaf_cert.
I don’t know if this is intended behavior or a bug. The documentation for tls at tls (Caddyfile directive) — Caddy Documentation doesn’t mention that these two directives are mutually exclusive though.
Thanks @Mohammed90 for your help in figuring this out
They’re not mutually exclusive. They work in layers. The (now deprecated) trusted_leaf_cert_file directive translates to verifier module, which checks the provided certificate in aspects not related to its chain (e.g. revocation, exact match, etc.). The trust_pool is only for certificate chain checks to ensure the submitted cert is anchored to a specific known roots.
We should expand the docs around that to clarify how they’re different.