There’s a lot of detail here, but the short of it is that I’m pretty sure I’m not setting up my clients correctly or that Caddy isn’t requesting client certs in a way that my browsers can understand. If anyone has a working tutorial that works with browsers on macOS or iOS, I’ll try that.
1. Caddy version (caddy version
): 2.2.1
2. How I run Caddy:
Docker Compose
a. System environment:
Raspberry Pi 2, Raspbian
b. Command:
caddy run
c. Service/unit/compose file:
---
version: '2.4'
services:
caddy:
image: caddy:2.2.1
ports:
# Local ports
- "80:80"
- "443:443"
# Public ports forwarded from :80 and :443 on router
- "8080:8080"
- "8443:8443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./root_ca.crt:/etc/caddy/client_ca.crt
- caddy_data:/data
volumes_from:
- certs
environment:
BASICAUTH_USER_HASH: ${BASICAUTH_USER_HASH}
restart: always
# Update star cert for internal domain (*.example.rocks and *.example.com)
certs:
build: ./lego
volumes:
- /srv/volumes/lego:/.lego
labels:
- 'dockron.schedule=0 0 * * 0' # Weekly on Sunday
environment:
CLOUDFLARE_EMAIL: ${CLOUDFLARE_EMAIL}
CLOUDFLARE_API_KEY: ${CLOUDFLARE_API_KEY}
dns: 1.1.1.1
# Update Cloudflare record for public home domain (home.example.com)
ddns:
image: iamthefij/cloudflare-ddns:linux-arm
labels:
- 'dockron.schedule=0 * * * *' # hourly on the 0
environment:
DOMAIN: home.example.com
CF_API_EMAIL: ${CLOUDFLARE_EMAIL}
CF_API_KEY: ${CLOUDFLARE_API_KEY}
dns: 1.1.1.1
whoami:
image: containous/whoami
volumes:
caddy_data:
d. My complete Caddyfile or JSON config:
{
debug
}
(add_basicauth) {
basicauth {
{$BASICAUTH_USER_HASH}
}
}
# Adds basic auth and a simple reverse proxy to args.0
(proxy_auth) {
import add_basicauth
reverse_proxy {args.0} {
header_up -Authorization
header_up X-Webauth-User "{http.auth.user.id}"
}
}
(lego_tls) {
tls {
load "/.lego"
}
}
ok.example.rocks {
# TLS certs must be loaded in at least one route
# This route loads the TLS certs from file and acts as a healthcheck
import lego_tls
respond "OK"
}
pihole.example.rocks {
reverse_proxy raspberrypi.example:9080
}
hass.example.rocks {
reverse_proxy hapi.example:8123
}
# Public ports
# Public http port, redirect to https
# This is automatic for 80>443 but not custom ports
:8080 {
redir https://{host}{uri}
}
auth_test.example.rocks:8443 {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file "/etc/caddy/client_ca.crt"
}
}
respond "Hi auth!"
}
3. The problem I’m having:
I’m encountering certificate errors when trying to access my auth_test
via browsers on my desktop and mobile. I’m not totally sure if I’m setting up certificates correctly though, but Safari doesn’t even ask for a cert but instead says the connection is not private despite showing a trusted Lets Encrypt cert.
4. Error messages and/or full log output:
n/a
5. What I already tried:
When I try to curl the endpoint, it does appear to work:
# no certs presented
$ curl https://auth_test.example.rocks
curl: (56) OpenSSL SSL_read: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate, errno 0
# certs presented
$ curl --cert ./user2.crt --key ./user2.key https://auth_test.example.rocks
Hi auth!
I’m not sure if the unauthenticated response is as expected either or if it should have instead returned a 401 or something.
I’ve also tried changing the directive a bit to verify_if_given
auth_test.example.rocks:8443 {
tls {
client_auth {
mode verify_if_given
trusted_ca_cert_file "/etc/caddy/client_ca.crt"
}
}
respond "Hi {tls_client_subject}! I'm {system.hostname}"
}
With this curl
shows:
# no certs presented
$ curl https://auth_test.example.rocks
Hi {http.request.tls.client.subject}! I'm 57f61d47b467
# certs presented
$ curl --cert ./user2.crt --key ./user2.key https://auth_test.example.rocks
Hi CN=user2! I'm 57f61d47b467
But still, no browsers ask for certificates.