CN and SAN for tls internal

1. My Caddy version (caddy version):

v2.0.0-rc.3 h1:z2H/QnaRscip6aZJxwTbghu3zhC88Vo8l/K57WUce4Q=

2. How I run Caddy:

    image: caddy:alpine
    container_name: caddy
      - ./compose/caddy/Caddyfile:/tmp/Caddyfile:ro
      - 80:80
      - 443:443
    entrypoint: caddy run --environ --adapter caddyfile --config /tmp/Caddyfile

a. System environment:

docker: 19.03.8-ce

b. Command:

docker-compose up -d

c. Service/unit/compose file:

See above

d. My complete Caddyfile or JSON config:

eycloak.localhost {
    reverse_proxy http://keycloak:8080 {
        header_up X-Forwarded-Proto {http.request.scheme}
        header_up X-Forwarded-For {}
    tls internal

photoz.localhost {
    reverse_proxy http://photoz:8080
    tls internal

3. The problem I’m having:

I can’t get the tls certs signed by caddy to have the configured CN and SAN.

Is there any way to get caddy to sign the self-signed certs with the internal CA using keycloak.localhost and photoz.localhost as configured in the Caddyfile?

When running Caddy in Docker, it’s important to use a volume for the /data directory so to not lose any certificate data!

Also it’s unnecessary to set the X-Forwarded-For header, Caddy already does that for you in v2. And on the current master branch (i.e. next release) it will also handle X-Forwarded-Proto for you.

It’s unclear to me what exactly the issue is you’re asking about though, what are you seeing instead of what you expect? Could you clarify?

Thanks for your help!

Here’s the output when I use openssl to try and connect to caddy

I’m expecting something more like, say if we use the same command on,

I get something like

 0 s:C = US, ST = California, L = Sunnyvale, O = Oath Inc, CN = *
   i:C = US, O = DigiCert Inc, OU =, CN = DigiCert SHA2 High Assurance Server CA
 1 s:C = US, O = DigiCert Inc, OU =, CN = DigiCert SHA2 High Assurance Server CA
   i:C = US, O = DigiCert Inc, OU =, CN = DigiCert High Assurance EV Root CA

Where the CN says

If I generate a certificate with

openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt -days 365 -subj "/CN=cas.localhost" -addext "subjectAltName=DNS:cas.localhost" -nodes

I can get a cert that, if inspected with openssl

openssl x509 -text -noout -in tls.crt

Shows something like this


Issuer: CN = cas.localhost


X509v3 Subject Alternative Name:

Would that be possible with caddy?

The error from openssl is just saying that it doesn’t trust the issuer, so Caddy’s root isn’t installed in your trust store, it seems. (That’s probably because it’s running in a docker container and not on your host system.) So, I think that is expected.

I checked again in a docker container, where the trust store is set up, it does return a cert with the SAN set correctly!

        X509v3 Subject Alternative Name: critical

The CN is still not set

depth=2 CN = Caddy Local Authority - 2020 ECC Root
verify return:1
depth=1 CN = Caddy Local Authority - ECC Intermediate
verify return:1
verify return:1

But I think that’s ok, because if the SAN is set, the CN is not checked, according to

Thanks so much!

ps: thanks for the advice on setting the X-Forwarded-For header! It was surprising to me that the docs said X-Forwarded-Proto will be set when it isn’t (yet) set, so I decided to explicitly set both to be sure.


Sounds good! Glad it’s working for you!

You can always install Caddy’s root cert on your host machine if you want to. (Make sure you’re persisting Caddy’s storage like Francis warned!)

The CommonName field has been deprecated for years, so Caddy doesn’t set that field on its certificates.

The docs might be slightly ahead of the tagged release at the moment, should only be that way for another week or so! That header will be set automatically with the next release.

1 Like

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