OpenSSL/3.1.4: error:0A000438:SSL routines::tlsv1 alert internal error

1. The problem I’m having:

I’m attempting to install caddy and get the below error message.

2. Error messages and/or full log output:

[admin@desktop caddy]$ curl -vL https://192.168.0.169
*   Trying 192.168.0.169:443...
* Connected to 192.168.0.169 (192.168.0.169) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* TLSv1.3 (IN), TLS alert, internal error (592):
* OpenSSL/3.1.4: error:0A000438:SSL routines::tlsv1 alert internal error
* Closing connection
curl: (35) OpenSSL/3.1.4: error:0A000438:SSL routines::tlsv1 alert internal error

3. Caddy version:

v2.7.5 h1:HoysvZkLcN2xJExEepaFHK92Qgs7xAiCFydN5x5Hs6Q=

4. How I installed and ran Caddy:

docker compose up -d

a. System environment:

Archlinux. Docker.

c. Service/unit/compose file:

version: "3.7"
services:
  caddy:
    image: lucaslorentz/caddy-docker-proxy:ci-alpine
    container_name: caddy
    ports:
      - 80:80
      - 443:443
    environment:
      - CADDY_INGRESS_NETWORKS=caddy
    networks:
      - caddy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - caddy_data:/data
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
    restart: unless-stopped

networks:
  caddy:
    external: true

volumes:
  caddy_data: {}

d. My complete Caddy config:

{
        debug
}
192.168.0.169 {
        respond / "Hello World" 200
        tls internal
}

5. Links to relevant resources:

Yes, when you use tls internal Caddy issues a cert using its own CA, so nothing will trust it by default. See the docs: Keep Caddy Running — Caddy Documentation

When I enter that command I get.

invalid output path: directory "/usr/local/share/ca-certificates" does not exist

I also tried importing the root.crt into firefox. Still the same results.

When I run. docker exec -w /etc/caddy caddy caddy trust, I get.

{"level":"info","ts":1700065113.9854255,"msg":"root certificate is already trusted by system","path":"localhost:2019/pki/ca/local"}

Edit:

I did a little digging and found the right folder and command for Archlinux.

sudo docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt /etc/ca-certificates/trust-source/anchors/root.crt && sudo update-ca-trust

I get.

✔ caddy copy caddy:/data/caddy/pki/authorities/local/root.crt to /etc/ca-certificates/trust-source/anchors/root.crt Copied

Still getting.

[admin@desktop caddy]$ curl -vL https://192.168.0.169
*   Trying 192.168.0.169:443...
* Connected to 192.168.0.169 (192.168.0.169) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* TLSv1.3 (IN), TLS alert, internal error (592):
* OpenSSL/3.1.4: error:0A000438:SSL routines::tlsv1 alert internal error
* Closing connection
curl: (35) OpenSSL/3.1.4: error:0A000438:SSL routines::tlsv1 alert internal error

I suggest you use a domain name instead of an IP address (and if you don’t use a real domain, put it in your /etc/hosts). Or use *.localhost which resolves to localhost if running both on the same machine.

The problem is that IP addresses aren’t sent via TLS-SNI, so cert selection uses the remote address, and that’s not necessarily going to match the Host on the original request if it goes through a TCP proxy layer (sometimes Docker enables its userland-proxy), so Caddy is likely trying to find a certificate for a different IP address and not finding one because it wasn’t configured for that IP.

You can enable the debug global option in Caddy to see more details about failed TLS handshakes, you’ll probably see it’s trying to find a cert for a different IP address.

I decided to buy a domain and try Caddy with the DNS challenge.