Tls interal still yields ERR_SSL_PROTOCOL_ERROR

1. Caddy version (caddy version):

> command docker exec -it caddy caddy version
v2.2.1 h1:Q62GWHMtztnvyRU+KPOpw6fNfeCD3SkwH7SfT1Tgt2c=

2. How I run Caddy:

On Raspberry Pi 3 with docker.

a. System environment:

Raspberry pi 3, docker,

b. Command:

docker-compose -f caddy/docker-compose.yml up -d

c. Service/unit/compose file:

version: "3.8"
services:
  caddy:
    image: caddy
    container_name: caddy
    hostname: caddy
    env_file: ../.env
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - DOMAIN
      - DOMAIN_LOCAL
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config

networks:
  default:
    external:
      name: $NETWORK

d. My complete Caddyfile or JSON config:

{
    # acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

# External
portainer.{$DOMAIN} {
    reverse_proxy {$IP_PORTAINER}:9000
}

home.{$DOMAIN} {
    reverse_proxy {$IP_HOMEASSISTANT}:8123
}


# Internal
portainer.{$DOMAIN_LOCAL} {
    tls internal
    reverse_proxy {$IP_PORTAINER}:9000
}

home.{$DOMAIN_LOCAL} {
    tls internal
    reverse_proxy {$IP_HOMEASSISTANT}:8123
}

3. The problem I’m having:

I want to access some applications running on local home servers from devices on my network. I have a DNS server set up with custom entries for home.localdomain and portainer.localdomain and they both go to the machine running my caddy reverse proxy.

The reverse proxy is working great when i access them externally via their real domain names home.MYDOMAIN.net and portainer.MYDOMAIN.net, presumably because i have REAL SSL certificates that caddy got for me from Let’s Encrypt.

When i navigate to home.localdomain or portainer.localdomain on my macbook my brower (chrome) gives me ERR_SSL_PROTOCOL_ERROR.

4. Error messages and/or full log output:

{"level":"info","ts":1603668418.2922635,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
{"level":"info","ts":1603668418.316451,"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":1603668418.3181965,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x30c6dc0"}
{"level":"info","ts":1603668418.3364673,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1603668418.3367465,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"warn","ts":1603668418.8076007,"logger":"pki.ca.local","msg":"installing root certificate (you might be prompted for password)","path":"storage:pki/authorities/local/root.crt"}
2020/10/25 23:26:58 Warning: "certutil" is not available, install "certutil" with "apt install libnss3-tools" or "yum install nss-tools" and try again
2020/10/25 23:26:58 define JAVA_HOME environment variable to use the Java trust
2020/10/25 23:26:59 certificate installed properly in linux trusts
{"level":"info","ts":1603668419.18305,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["portainer.MYDOMAIN.net","home.MYDOMAIN.net","portainer.localdomain","home.localdomain"]}
{"level":"info","ts":1603668419.2108123,"logger":"tls","msg":"cleaned up storage units"}
{"level":"warn","ts":1603668419.223545,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [portainer.localdomain]: no OCSP server specified in certificate"}
{"level":"warn","ts":1603668419.2345653,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [home.localdomain]: no OCSP server specified in certificate"}
{"level":"info","ts":1603668419.2359545,"msg":"autosaved config","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1603668419.236042,"msg":"serving initial configuration"}

5. What I already tried:

I was following this guide:

to get them working using tls internal

I tried uncommenting the line my caddyfile
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
but it didn’t help, i still get the same error. To be honest I don’t know what this line is for, i just kept it in from a tutorial (that also had it commented out). I assume it’s telling Caddy what to use to sign certificates but idk why the tutorial i used kept it commented out.

I tried using tls self_signed but that looks like its depcrecated.

6. Links to relevant resources:

Side question:

Is there a way to get a wildcard cert with caddy for *.lan.mydomain.net WITHOUT exposing anything on *.lan.mydomain.net to the internet? That way in my caddy file instead of using home.localdomain i can use home.lan.mydomain.net?

Yes, with the ACME DNS challenge:

How do i enable this with the caddy docker image?

Follow the instructions for building Caddy with plugins from here: Docker Hub

cool, thank you. That will help if i want to go down that route. Though i’m not sure my DNS provider (i suppose namecheap since thats where the domain is from) is able to do this, and i’m not sure how to switch really.

I think you’ll need to use GitHub - caddy-dns/lego-deprecated: (DEPRECATED) DNS modules so Caddy can solve the ACME DNS challenge with over 75 providers for namecheap for the time being. Configuration is done via environment variables. See the README.

Thanks for the info! It also looks possible for me to switch my DNS server for the namecheap doman to cloudflare. Looks like I got some work to do to get this wildcard cert working.

This still leaves me wondering why my internal certificate wasn’t working on chrome.

If you’re running in Docker, then Caddy won’t be able to install its root CA cert in your system’s trust store, because it’s isolated from the host. You’ll need to do that manually. You can find the cert in /data/pki/authorities/local/root.crt I believe.

Also, try with Firefox as well, Chrome tends to be finicky with this sort of thing.

I see, I’m a little confused though. Does it need to install the cert in the machine running the docker caddy or the machine accessing it (they are different)?

I copied he root.crt to my macbook and added it manually and hit “trust all” but chrome still yielded this error.

It needs to be installed on the machine accessing the site. It needs to be added to your system’s trust store so that it can trust connections to servers using certificates signed by that CA.

Chrome might be caching the TLS result, you might need to close it completely and/or clear its storage for it to take. Like I said, Chrome can be finicky.

Gotcha, thanks for the info. I am going to spend more time pursuing the wildcard cert route since that will work on any device.

out of curiosity, if i want to get a wiidcard cert for *.lan the traditional way (http instead of dns) what are the requirements? I’ve never got a wildcard cert before. Do i need to add a CNAME record in my DNS provider with *.lan and point it to the IP of my server?

That domain needs to be publicly resolvable, and point to your server running Caddy, and you must have ports 80 and 443 open and publicly accessible. It’s all covered in here:

I just read that over again and i see that wildcards require dns-01 challenge, even if I had the *.lan record in my namecheap dns provider entries; so there isn’t any point in trying to get a wildcard working without it.

I think the easiest option is for me to move my nameservers for the domain to cloudflare and use the module that some nice people have already written. It allows everything i want: 1) wildcard cert for *.lan.mydomain.com 2) domain does not need to be publicly accessible.

Is there a way to configure the caddy file to acquire the wildcard cert but defer to more specific matchers for serving?

for instance if i have this in my caddy file

*.lan.mydomain.com {

}

It will acquire the *.lan wildcard cert because it’s in my caddyfile; but i want to set up serving a rule that is specific to home.lan.mydomain.com and other things more specific that also are covered by that wildcard cert.

Yeah:

*.lan.mydomain.com {
	@home host home.lan.mydomain.com
	handle @home {
		...
	}

	@foo host foo.lan.mydomain.com
	handle @foo {
		...
	}

	# For anything else, falls through to this:
	handle {
		...
	}
}

Awesome, thank you so much; you’ve been an amazing help!

Now i’m off to go wrestle with building my own docker image with the cloudflare dns and set all that up.

Caddy Rules!

EDIT:

Looking over that i’m a little confused at this part

	@foo foo home.lan.mydomain.com
	handle @foo {
		...
	}

should this be @foo host foo.lan.mydomain.com?

Yes, totally, copy paste failure on my part :man_facepalming: :sweat_smile:

No worries, thank you again for all your help!!

Just wanted to comment again to say THANK YOU!

I’ve successfully moved my domains DNS service to cloudflare, re-set up ddclient with cloudflare, built a local docker image of caddy with cloudflare dns challange, and have modified my Caddyfile according to your help.

I can now navigate to home.lan.mydomain.com and it works great!

CADDY RULES! PADLOCK EVERYTHING!

2 Likes

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