ERR_SSL_PROTOCOL_ERROR when using search domain to complete domain name

Hi guys! It’s me again… I hope i’m not getting on your nerves. This is (hopefully) the last issue I need to get sorted to be happy with my home network setup.

1. Caddy version (caddy version):

v2.2.1 h1:Q62GWHMtztnvyRU+KPOpw6fNfeCD3SkwH7SfT1Tgt2c=

2. How I run Caddy:

Custom built docker image with cloudflare dns

Dockerfile

FROM caddy:builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/cloudflare

FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

a. System environment:

Raspberry Pi 3 with docker.

b. Command:

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

c. Service/unit/compose file:

version: "3.8"
services:
  caddy:
    image: caddy_cloudflare:1.0
    container_name: caddy
    hostname: caddy
    env_file:
      - ../.env
      # Add CLOUDFLARE_API_TOKEN to secret.env
      #  Token permissions:
      #    (Zone/DNS/EDIT)
      #    (Zone/Zone/Read)
      - ./secret.env
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config

networks:
  default:
    external:
      name: $NETWORK

d. My complete Caddyfile or JSON config:

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

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


# Internal
*.lan.{$DOMAIN} {
  tls MYEMAIL@gmail.com { 
    dns cloudflare {$CLOUDFLARE_API_TOKEN}
  }

  @unifi host unifi.lan.{$DOMAIN}
  handle @unifi {
    reverse_proxy {$IP_UNIFI}:8443 {
      transport http {
        tls_insecure_skip_verify
      }
    }
  }

  @udm host udm.lan.{$DOMAIN}
  handle @udm {
    reverse_proxy {$IP_UNIFI}:443 {
      transport http {
        tls_insecure_skip_verify
      }
    }

    redir / /login
  }

  @home host home.lan.{$DOMAIN}
  handle @home {
    reverse_proxy {$IP_HOMEASSISTANT}:8123
  }

  @portainer host portainer.lan.{$DOMAIN}
  handle @portainer {
    reverse_proxy {$IP_PORTAINER}:9000
  }

  @pihole host pihole.lan.{$DOMAIN}
  handle @pihole {
    reverse_proxy {$IP_PIHOLE}:8080
    redir / /admin
  }

  # For anything else, falls through to this:
  handle {
    respond "404 bruh." 404 {
      close
    }
  }
}

3. The problem I’m having:

I have my routers domain set to lan.mydomain.com and have pi-hole running as a local DNS server that routes certain subdomains of this domain to the rasperry pi running caddy.

An an example, I have a DNS entry in pi-hole for home.lan.mydomain.com and it sends that to 192.168.1.100 which caddy routes over to the machine (which turns out to be itself) running home assistant on port 8123.

The reason I set it up this way is because I want to be able to type home/ into my browser and hit that page. This should work because when i type home/ into the browser my computer is configured by my routers DHCP to append the search domain lan.silmanserver.net. And indeed, when I type home/ into my browser i can see a log on my Pi-Hole:

Oct 27 18:50:44 dnsmasq[21750]: query[A] home.lan.mydomain.com from 192.168.1.173
Oct 27 18:50:44 dnsmasq[21750]: /etc/pihole/custom.list home.lan.mydomain.com is 192.168.1.100

So this side of things seems to be working great.

But when I do type home/ into my browser and hit enter I am me with ERR_SSL_PROTOCOL_ERROR and when i click on the top left icon (an i in a circle) next to the omnibox i see “Your connection to this site is not secure.”

I have set up a wildcard cert for lan.mydomain.net which I know is working because if i type home.lan.mydomain.com into the browser everything works awesomely and i have the padlock and I can click it to see my wildcard cert shown.

4. Error messages and/or full log output:

ERR_SSL_PROTOCOL_ERROR

5. What I already tried:

I checked all my other domains in the caddy file: portainer, unifi, udm, pihole. They all show the exact same symptoms. They work with their fully qualified domain names typed into the browser but not if i do the shorthand and let my search-domain do the rest of the work.

My intuition is that the host field is the problem because its Host: home instead of Host: home.lan.mydomain.com. But I don’t actually know how SSL certs work so i’m just taking a stab in the dark; do they need the host to match exactly?

If the host it he problem I might be in big trouble because i think caddy only gets certs for host domains and there is no way to get a wildcard cert to match home since i need a domain.tld that i own.

EDIT: Tried with firefox, same thing but firefox calls this error SSL_ERROR_INTERNAL_ERROR_ALERT

I think this must be caused by the host not matching but i have no idea why. I was under the impression that the search domain / dns suffix was appended when i typed a domain into the browser.

EDIT 2 : I guess i lacked some understanding of how the host header field works. So now i’m thinking i need to have caddy match home and redirect it to home.lan.mydomain.com. Hopefully I can figure that out and it actually solves the problem (and works with tls).

EDIT 3:

I tried adding this

@home_short host home 
handle @home_short{
    reverse_proxy {$IP_HOMEASSISTANT}:8123
}

right above the *.lan.{$DOMAIN} block

But it yielded this error when booting the docker

{"level":"info","ts":1603856803.015378,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
run: adapting config using caddyfile: cannot define a matcher outside of a site block: '@home_short'

but if i tried to make a home block like this

home {
    reverse_proxy {$IP_HOMEASSISTANT}:8123
}

I get another error because obviously tls won’t work on this host

{"level":"error","ts":1603856987.33924,"logger":"tls.obtain","msg":"will retry","error":"[home] Obtain: [home] creating new order: request to https://acme-v02.api.letsencrypt.org/acme/new-order failed after 1 attempts: HTTP 400 urn:ietf:params:acme:error:rejectedIdentifier - Error creating new order :: Cannot issue for \"home\": Domain name needs at least one dot (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":0.986014299,"max_duration":2592000}

EDIT 4:
Defined a block like this to disable automatic https for just this:

http://home {
    redir https://home.lan.{$DOMAIN}
}

but now i’m back to the original ERR_SSL_PROTOCOL_ERROR error. The same thing happens if i try to use reverse_proxy {$IP_HOMEASSISTANT}:8123 instead of redir https://home.lan.{$DOMAIN}

EDIT 5:
AAAAAAAAAND SOLVED.

http://home {
    redir https://home.lan.{$DOMAIN}
}

just need to add these for each short URL i want. it doesn’t preserve the cool short URL but i guess that’s okay.

6. Links to relevant resources:

AAAAAAAAAND SOLVED.

http://home {
    redir https://home.lan.{$DOMAIN}
}

just need to add these for each short URL i want. it doesn’t preserve the cool short URL but i guess that’s okay.

If you all have a good suggestion for how to preserve the cool short URL please let me know, but i don’t know if it’s possible to do while still having SSL.

I tried with

http://home {
    reverse_proxy https://home.lan.{$DOMAIN}:8123
}

thinking this would give me SSL and still maintain the cool short URL but alas i get 502 Error Bad Gateway.

Quick question:

Is there any way to reference the host match itself so i can make this less error prone.

Like if I define some environmental variable LAN_DOMAIN that is `lan.{$DOMAIN} then I can make a bunch of these short urls like so:

http://shortURL {
    redir https://shortURL.{$LAN_DOMAIN}
}

Is there an way to reference shortURL

EDIT: I should have just read the docs before asking lol… found {host} on Caddyfile Concepts — Caddy Documentation

Now i can condense them all down to

http://home,
http://portainer,
http://pihole {
    redir https://{host}.{$LAN_DOMAIN}

CADDY RUUUUUUUUUUUUUUULES!!!11!!!

1 Like

Yes, they do (but note that wildcard certs are a thing, so obviously *.example.com would match foo.example.com). That’s a big part of the security they offer. (Also FYI they’re TLS certs, not SSL certs, SSL is the outdated term; browsers kept it in their error message names to avoid changing things though).

Caddy also uses SNI (Server Name Identification) to decide which certificate to use for the handshake, so if there’s no match, it can’t make a connection. And past that point, the Host header is how Caddy decides which site to serve, so home alone wouldn’t match your original config.

Unfortunately there’s no mechanism for telling a browser to redirect one DNS record to another (before hitting a web server).

But like you’ve realized, you can make a site block that serves over HTTP only with that hostname.

What happened here is you were missing a space before the {, which is important for the Caddyfile lexer to correctly read your config.

Thanks for all the info (and all the help)!

I’ve finally achieved the dream of having short URL redirects on my home network and it’s awesome! And i’ve learned a thing or two about how the web works which is neat :smile:

1 Like

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