Caddy: Self signed certificate handling broken in >=0.11.1 resulting in not serving certificates

Created on 2 Jan 2019  路  13Comments  路  Source: caddyserver/caddy

1. What version of Caddy are you using (caddy -version)?

Caddy 0.11.1 (non-commercial use only)
And when testing further also using Caddy 0.11.1 (unofficial).

2. What are you trying to do?

Use Caddy server with self-signed certificate (because it's going to be deployed in local environment and therefore generally unsuitable for Let's Encrypt, etc.)
Also the CN of the self-signed certificate is different from the hostname of the machine.

3. What is your entire Caddyfile?

:80 {
    tls off

    root /front
}

# using self-signed certificate!
:443 {
    tls /etc/ssl/private/cert.pem /etc/ssl/private/key.pem

    root /front
}

4. How did you run Caddy (give the full command and describe the execution environment)?

Run it as docker image installed from getcaddy.com, as

RUN apk --no-cache add curl bash openssh-client git tar gnupg \
    && curl https://getcaddy.com \
    | bash -s personal http.git

Later examined the docker images from https://hub.docker.com/r/abiosoft/caddy and I could easily reproduce the same issue there when using 0.11.1 version.
Note that with 0.11.0 version the certificate is being served fine.

5. Please paste any relevant HTTP request(s) here.

Just accessing the site in browser, i.e.:
https://localhost/
http://localhost/ (and tested without HTTPS to see that :80 works fine)

6. What did you expect to see?

Content of the index.html file located in the /front directory. (The only reason I am mentioning the directory is the fact that the same directory is used in the Caddyfile above.)

7. What did you see instead (give full error messages and/or log)?

Secure Connection Failed

An error occurred during a connection to localhost. Peer reports it experienced an internal error. Error code: SSL_ERROR_INTERNAL_ERROR_ALERT 

Actually this seem pretty much identical to https://github.com/mholt/caddy/issues/2078.

8. How can someone who is starting from scratch reproduce the bug as minimally as possible?

Just using the Caddyfile provided above, any accessing the URL.

Furthermore I am attaching the process logs below.
Attached log from 0.11.0:

2019/01/02 15:58:20 [WARNING] Stapling OCSP: no OCSP stapling for [sodat analytics]: no OCSP server specified in cert
2019/01/02 15:58:20 [INFO] Successfully loaded TLS assets from /etc/ssl/private/cert.pem and /etc/ssl/private/key.pem
Activating privacy features... done.
http://
2019/01/02 15:58:20 http://
https://
2019/01/02 15:58:20 https://

Attached log from 0.11.1:

2019/01/02 16:07:09 [WARNING] Stapling OCSP: no OCSP stapling for [sodat analytics]: no OCSP server specified in cert
2019/01/02 16:07:09 [INFO] Successfully loaded TLS assets from /etc/ssl/private/cert.pem and /etc/ssl/private/key.pem
Activating privacy features... done.
http://
2019/01/02 16:07:09 http://
https://
2019/01/02 16:07:09 https://
2019/01/02 16:07:15 http: TLS handshake error from 172.17.0.1:44576: no certificate available for localhost

The last error message makes a bit sense as the self-signed certificate specified in the Caddyfile actually doesn't have localhost specified. Could this be related to SNI, i.e., trying to serve a certificate based on host, and not falling back to serve the self-signed certificate?

bug

Most helpful comment

Interesting reading @mholt, that's surely the culprit (and feels that blaiming SNI from the beginning wasn't a completely blind guess).
To resolve the issue eventually, is there a way to disable SNI for Caddy? I don't seem to see this in the documentation.

In my particular case the hostname enumeration is definitely not relevant attack, and I would (in such case) definitely rather serve the same SSL certificate to all requests coming to 443 port, than failing with "secure connection failed" error.

All 13 comments

I also encountered such a problem, I can't use caddy from the visa book, which is very bad.

Please try with the latest master and let me know if it fixes it. Release going out in a few hours if no further issues reported.

Hi @mholt, tested now with version 0.11.2, no change with regard to this issue.
And then built it from master (latest commit at that point a7aeb979be5a59ae82fac0783fe54b83c7fc57fd), again with no improvement!

# caddy -version
Caddy 0.11.2 (+a7aeb97) (unofficial)

Still getting "secure connection failed" errors with SSL_ERROR_INTERNAL_ERROR_ALERT meaning that the certificates are not served.
Logs from Caddy:

2019/01/22 20:00:41 [WARNING] Stapling OCSP: no OCSP stapling for [sodat analytics]: no OCSP server specified in certificate
2019/01/22 20:00:41 [INFO] Successfully loaded TLS assets from /etc/ssl/private/cert.pem and /etc/ssl/private/key.pem
Activating privacy features... done.
http://
2019/01/22 20:00:41 http://
https://
2019/01/22 20:00:41 https://
2019/01/22 20:00:42 [WARNING] Sending telemetry (attempt 1): Post https://telemetry.caddyserver.com/v1/update/44b55065-29da-4006-998d-18ad17afd459: x509: certificate signed by unknown authority - backing off and retrying
2019/01/22 20:00:43 http: TLS handshake error from 172.17.0.1:50104: no certificate available for localhost

Note that I now also updated the issue title to reflect that it affects now more versions than one.

What are the names on your self-signed certificate?

In fact there is not really much info in the self-signed certificate, only:

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            95:e8:f1:8b:64:13:56:41
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = CZ, O = My Unit With No Name, CN = Here Comes Project Name
        Validity
            Not Before: Sep 19 07:38:13 2018 GMT
            Not After : Sep 18 07:38:13 2023 GMT
        Subject: C = CZ, O = My Unit With No Name, CN = Here Comes Project Name
        Subject Public Key Info:
        ...

(obtained from openssl x509 -in cert.pem -noout -text)

So there are no SANs on the certificate? What is the full output please.

Indeed, there are no SANs.


Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            95:e8:f1:8b:64:13:56:41
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = CZ, O = My Unit With No Name, CN = Here Comes Project Name
        Validity
            Not Before: Sep 19 07:38:13 2018 GMT
            Not After : Sep 18 07:38:13 2023 GMT
        Subject: C = CZ, O = My Unit With No Name, CN = Here Comes Project Name
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:a3:65:f5:c9:b4:6f:cc:89:68:d1:be:62:6b:6a:
                    11:65:cb:a8:94:69:ee:04:ec:2b:81:cd:a6:f5:99:
                    11:82:7b:9a:37:fc:41:97:5b:ca:25:3e:33:0d:8b:
                    ...
                    2d:82:c1:e9:a7:d0:31:ac:52:8d:12:f3:89:67:b0:
                    bd:39:4a:a7:b1:6d:85:96:e7:fe:3c:07:3c:6c:55:
                    da:51:bf
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         58:5e:0c:a2:ad:65:5e:69:2a:8c:6f:79:11:29:98:ad:96:7b:
         c8:5d:25:b6:63:ad:80:d2:c6:b1:d7:65:9f:1f:e2:8a:eb:98:
         d1:ff:36:c2:c8:9e:85:67:65:d3:07:9e:99:66:d5:41:04:55:
         ...

Probably missed the -extensions when I generated the certificate in a first place.

The certificate must of course have the names on it for which it is certifying. I don't think this is a Caddy bug.

Could you be more specific on the "_of course_" part of why a certificate needs to contain SANs? AFAIK SAN is only an extension to provide alternatives to CN. Obviously some consider CN deprecated when it comes to HTTPS.. though I can't seem to fine any RFC which would actually say so.

And referring to the "_not bug_" part, how it comes this exact certificate works fine in 0.11.0?

Obviously some consider CN deprecated when it comes to HTTPS.. though I can't seem to fine any RFC which would actually say so.

Caddy also honors CommonName currently, but I won't guarantee for how long. The TODOs in the code indicate its deprecation and support could be removed at any time. If localhost is in your CommonName or SAN, Caddy will serve it up.

And referring to the "not bug" part, how it comes this exact certificate works fine in 0.11.0?

If the certificate's name is sodat analytics or Here Comes Project Name then Caddy will serve the certificate for those SNI values, but not localhost. To do so otherwise would permit hostname enumeration. I was against the change to enforce this, as I don't fully acknowledge hostname enumeration from this vector as a grave threat, but I was forced to make Caddy act this way, so that's how it is. If this frustrates you, we can find a different solution or feel free to blame the "researchers" who are trying to fix the Internet's problems the wrong way.

Interesting reading @mholt, that's surely the culprit (and feels that blaiming SNI from the beginning wasn't a completely blind guess).
To resolve the issue eventually, is there a way to disable SNI for Caddy? I don't seem to see this in the documentation.

In my particular case the hostname enumeration is definitely not relevant attack, and I would (in such case) definitely rather serve the same SSL certificate to all requests coming to 443 port, than failing with "secure connection failed" error.

From the absolutist standpoint (and according to a very narrow threat model, which a very vocal minority holds), we can't respond with a certificate that the client has not explicitly asked for, even if there is only one certificate, it exposes which site that server is serving, and apparently some people want to hide that, even though all the names and certificates are public. :roll_eyes:

Open to solutions, but hopefully without inciting riots again.

This issue seems to be mainly about existing self signed certificates.

I just ran into this when using the directive tls self_signed in combination with listening on 0.0.0.0:8443, which doesn't work. Caddyfile:

0.0.0.0:8443
tls self_signed

When listening on localhost:8443 it works.

As 0.0.0.0 is a wildcard for listening on, but not a valid address for a client, does it make sense if Caddy would log a warning here? Generating some certs, but you won't be able to connect with "localhost" or something. Does it generate certs in this case at all? For which names/addresses?

Using the abiosoft/caddy Docker image, caddy --version: Caddy 0.11.5 (unofficial)

Was this page helpful?
0 / 5 - 0 ratings