SSL certificate problem when serving localhost domain from /etc/hosts

1. Caddy version (caddy version):

Version 2.0.0 (docker image)

2. How I run Caddy:

This is my development setup. The issue has not occurred in the production setup because it is likely linked to using the tls internal directive. I run Caddy in a simply docker container to test out the logic first. The end goal is to be able to make requests to a “fictitious” domain in a local network. I have modified the /etc/hosts to include a domain and subdomain (see Caddyfile below for domains)

a. System environment:

I am running this in a docker container. The container is running on an Ubuntu 20.04 LTS operating system running in a Vagrant VM on MacOS. The modified /etc/hosts and curl request is made in a terminal on the Ubuntu OS.

b. Command:

Running caddy with:

docker build -t caddy_test .
docker run -p 80:80 -p 443:443 caddy_test

c. Service/unit/compose file:

Dockerfile:

FROM caddy:2.1.1

COPY Caddyfile /etc/caddy/Caddyfile

d. My complete Caddyfile or JSON config:

Caddyfile:

sub.mydevdomain.com {
    tls internal
    respond "Hey, the subdomain worked!"
}

mydevdomain.com {
    tls internal
    respond "Hey, it worked!"
}

3. The problem I’m having:

After launching the docker container I make a simple curl request to one of the URLs I have setup in the Caddyfile.

I run the following curl command:

curl https://mydevdomain.com

and get the following output:

curl: (60) SSL certificate problem: unable to get local issuer certificate

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Eventually, I would like to be able to at least curl the above domain/subdomain (or similar) over HTTPS. My end goal would be to able to access those domains over in the host machine (ie: MacOS) for development, but I guess that’s a setup that goes a little beyond Caddy and is not the main topic of this issue. However, if you could tell if the TLS is likely to break when bridging from the VM to the host, that would be a nice heads up. Thanks a lot for the help!

4. Error messages and/or full log output:

Caddy log:

{"level":"info","ts":1595340667.7223434,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}

{"level":"info","ts":1595340667.7252204,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["localhost:2019","[::1]:2019","127.0.0.1:2019"]}

{"level":"info","ts":1595340667.7337584,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}

2020/07/21 14:11:07 [INFO][cache:0xc0006bccd0] Started certificate maintenance routine

{"level":"warn","ts":1595340667.7821124,"logger":"pki.ca.local","msg":"installing root certificate (you might be prompted for password)","path":"storage:pki/authorities/local/root.crt"}

2020/07/21 14:11:07 Warning: "certutil" is not available, install "certutil" with "apt install libnss3-tools" or "yum install nss-tools" and try again

2020/07/21 14:11:07 define JAVA_HOME environment variable to use the Java trust

2020/07/21 14:11:07 certificate installed properly in linux trusts

{"level":"info","ts":1595340667.8112118,"logger":"tls","msg":"cleaned up storage units"}

{"level":"info","ts":1595340667.8122373,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["sub.mydevdomain.com","mydevdomain.com"]}

{"level":"info","ts":1595340667.8126667,"msg":"autosaved config","file":"/config/caddy/autosave.json"}

{"level":"info","ts":1595340667.8127985,"msg":"serving initial configuration"}

2020/07/21 14:11:07 [INFO][sub.mydevdomain.com] Obtain certificate; acquiring lock...

2020/07/21 14:11:07 [INFO][sub.mydevdomain.com] Obtain: Lock acquired; proceeding...

2020/07/21 14:11:07 [INFO][sub.mydevdomain.com] Certificate obtained successfully

2020/07/21 14:11:07 [INFO][sub.mydevdomain.com] Obtain: Releasing lock

2020/07/21 14:11:07 [WARNING] Stapling OCSP: no OCSP stapling for [sub.mydevdomain.com]: no OCSP server specified in certificate

2020/07/21 14:11:07 [INFO][mydevdomain.com] Obtain certificate; acquiring lock...

2020/07/21 14:11:07 [INFO][mydevdomain.com] Obtain: Lock acquired; proceeding...

2020/07/21 14:11:07 [INFO][mydevdomain.com] Certificate obtained successfully

2020/07/21 14:11:07 [INFO][mydevdomain.com] Obtain: Releasing lock

2020/07/21 14:11:07 [WARNING] Stapling OCSP: no OCSP stapling for [mydevdomain.com]: no OCSP server specified in certificate

2020/07/21 14:11:24 http: TLS handshake error from 172.17.0.1:36810: local error: tls: bad record MAC

2020/07/21 14:11:29 http: TLS handshake error from 172.17.0.1:36814: local error: tls: bad record MAC

2020/07/21 14:12:30 http: TLS handshake error from 172.17.0.1:36818: local error: tls: bad record MAC

5. What I already tried:

I followed the instructions given by the curl error but I am rather new to SSL and must say I did not understand what steps they recommended to take.

6. Links to relevant resources:

The curl error link: curl - SSL CA Certificates

G’day @SteliosRammos, welcome to the Caddy community!

Here is, I’d wager, the reason for your issue (in conjunction with tls internal).

What curl is telling you here is that it doesn’t have a trusted certificate authority installed for the certificate Caddy gave it. (Most operating systems come with a number of trusted CAs installed by default - the big issuers, basically, third parties that issue certificates trusted globally.) It can’t trust Caddy’s cert because it can’t validate it against any CA files it has.

You can:

  • Disable certificate validation (with the -k flag), OR;
  • Install Caddy’s CA cert

Normally, #2 is done automatically on the local computer. But you’re running Caddy in a Docker container, and that’s where Caddy will have installed its CA (i.e. not the actual host itself).

Any remote host (and the Docker host counts as “remote” to the Docker container itself in this case) will need to install the CA cert manually. That means you’ll need to copy it out of the trust store in the Docker container and add it to your client’s trust store.

The root CA certificate you need to copy out will be in the data directory, the logs tell you where:

#1 is not desirable because it throws away a lot of the security of HTTPS (the verifiability).

3 Likes

Hi Matthew, thanks for the help, you were exactly right!

I modified the docker run command to mount the certificates as a volume shared between the docker container and the VM, as follows:

docker run -p 80:80 -p 443:443 -v /usr/local/share/ca-certificates:/data/caddy/pki/authorities/local caddy_test

So that worked in the VM, but now I am having some trouble getting it to work on MacOS. As I said in the original post the VM runs inside MacOS and for development I need to be able to access the domain from my browser (Opera in this case).

I added the root cert manually to the KeyChain and it shows as trusted in the KeyChain Access but when trying to access the domain in the browser it returns a Privacy Error (see below).

Do you have some idea as to what’s failing?

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