1. The problem I’m having:
I am trying to add authentication to several services hosted public and local from my home server. Caddy is working fine reverse-proxying everything in the right direction. At least until I try to add the aforementioned authentication service. I am pretty sure it’s an error of thinking on my site and I hope I get a push in the right direction.
2. Error messages and/or full log output:
I get this error when I try to open ntfy.example.de in LibreWolf:
We can’t connect to the server at application. Did you mean to go to www.application.com/o/authorize/?client_id=jCswQofamg8OGL4vSzKPBD6nd9nqcjukXH7IJ1en&redirect_uri=https%3A%2F%2Fntfy.example.de%2Foutpost.goauthentik.io%2Fcallback%3FX-authentik-auth-callback%3Dtrue&response_type=code&scope=ak_proxy+openid+profile+email&state=S3O3jT1syXi8sinkNeip5_j2TtydWc93s8tnjsm9pBo?`
- Authentik uses forward auth (single application)
log:
INF | ts=1694352136.1825497 logger=admin.api msg=received request method=POST host=localhost:2019 uri=/load remote_ip=127.0.0.1 remote_port=58440 headers={"Accept-Encoding":["gzip"],"Content-Length":["10225"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}
INF | ts=1694352136.1855526 logger=admin msg=admin endpoint started address=:2019 enforce_origin=false origins=["//:2019"]
WRN | ts=1694352136.1855721 logger=admin msg=admin endpoint on open interface; host checking disabled address=:2019
INF | ts=1694352136.1878467 logger=http.auto_https 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
INF | ts=1694352136.187916 logger=http.auto_https msg=enabling automatic HTTP->HTTPS redirects server_name=srv0
INF | ts=1694352136.1904976 logger=pki.ca.local msg=root certificate is already trusted by system path=storage:pki/authorities/local/root.crt
INF | ts=1694352136.191116 logger=http.log msg=server running name=remaining_auto_https_redirects protocols=["h1","h2","h3"]
INF | ts=1694352136.1911268 logger=tls msg=cleaning storage unit description=FileStorage:/data/caddy
INF | ts=1694352136.1911695 logger=http msg=enabling HTTP/3 listener addr=:443
INF | ts=1694352136.1912203 logger=http.log msg=server running name=srv0 protocols=["h1","h2","h3"]
INF | ts=1694352136.1912498 logger=http msg=enabling automatic TLS certificate management domains=["port.example.de","dashboard.home.lab","backup.home.lab","project.example.de","prometheus.home.lab","cloud.example.de","pass.example.de","read.example.de","auth.example.de","snips.home.lab","sab.home.lab","recipes.example.de","code.example.de","finance.example.de","health.example.de","active.example.de","bookmark.example.de","ntfy.example.de","fritz.box","foto.example.de"]
INF | ts=1694352136.191383 logger=http msg=servers shutting down with eternal grace period
INF | ts=1694352136.192282 msg=autosaved config (load with --resume flag) file=/config/caddy/autosave.json
INF | ts=1694352136.192349 logger=admin.api msg=load complete
INF | ts=1694352136.1941514 logger=admin msg=stopped previous server address=:2019
INF | ts=1694352136.2350917 logger=tls msg=finished cleaning storage units
INF | ts=1694352156.1762204 logger=admin.api msg=received request method=GET host=192.168.0.28:2019 uri=/reverse_proxy/upstreams remote_ip=192.168.10.3 remote_port=59110 headers={"Connection":["close"],"Cookie":["PHPSESSID=ej24gfdlkjqfua4703o0ralc5v"]}
INF | ts=1694352157.6338186 logger=admin.api msg=received request method=GET host=192.168.0.28:2019 uri=/reverse_proxy/upstreams remote_ip=192.168.10.3 remote_port=59118 headers={"Connection":["close"],"Cookie":["PHPSESSID=ej24gfdlkjqfua4703o0ralc5v"]}
INF | ts=1694353048.4694173 logger=admin.api msg=received request method=GET host=192.168.0.28:2019 uri=/reverse_proxy/upstreams remote_ip=192.168.10.3 remote_port=38084 headers={"Connection":["close"],"Cookie":["PHPSESSID=ej24gfdlkjqfua4703o0ralc5v"]}
3. Caddy version:
v2.7.4 h1:J8nisjdOxnYHXlorUKXY75Gr6iBfudfoGhrJ8t7/flI=
4. How I installed and ran Caddy:
Docker run command I don’t have anymore. Should’ve been pretty standard
a. System environment:
Docker version 23.0.0, build e92dd87
Fedora release 37 (Thirty Seven)
b. Command:
c. Service/unit/compose file:
d. My complete Caddy config:
# global options
{
email admin@example.de
on_demand_tls {
interval 2m
burst 5
}
servers {
metrics
}
admin :2019
}
# SABnzbd
sab.{$LCLDMN} {
reverse_proxy 192.168.0.28:8087
tls internal
}
# Snippetbox
snips.{$LCLDMN} {
reverse_proxy 192.168.10.4:5000
tls internal
}
# Duplicati
backup.{$LCLDMN} {
reverse_proxy 192.168.0.28:8200
tls internal
}
# Homepage
dashboard.{$LCLDMN} {
reverse_proxy 192.168.10.3
tls internal
}
# Prometheus
prometheus.{$LCLDMN} {
reverse_proxy 192.168.0.28:9050
tls internal
}
fritz.box {
tls internal
}
(authentik) {
reverse_proxy /outpost.goauthentik.io/* http://192.168.0.28:9000
forward_auth http://192.168.0.28:9000 {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
trusted_proxies private_ranges # <- tried with and without this line
}
}
# Vaultwarden
pass.{$DOMAIN} {
reverse_proxy 192.168.0.28:8010
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy no-referrer-when-downgrade
}
reverse_proxy https://home.lab {
header_up Host {upstream_hostport}
}
}
# VSCode
code.{$DOMAIN} {
reverse_proxy 192.168.0.28:8443
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy no-referrer-when-downgrade
}
}
# Grafana
health.{$DOMAIN} {
reverse_proxy 192.168.0.28:3000
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy no-referrer-when-downgrade
}
}
# Uptime Kuma
active.{$DOMAIN} {
reverse_proxy 192.168.0.28:3001
encode zstd gzip
header {
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods "OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE"
Strict-Transport-Security max-age=31536000;
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy no-referrer-when-downgrade
}
}
# Nextcloud
cloud.{$DOMAIN} {
redir /.well-known/carddav /remote.php/dav 301
redir /.well-known/caldav /remote.php/dav 301
reverse_proxy 192.168.0.28:8070
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
}
}
# Immich
foto.{$DOMAIN} {
reverse_proxy 192.168.0.28:2283
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# Kavita
read.{$DOMAIN} {
reverse_proxy 192.168.0.28:5000
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# Tandoor
recipes.{$DOMAIN} {
reverse_proxy 192.168.0.28:8123
encode zstd gzip
header {
Strict-Transport-Security max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# Firefly III
finance.{$DOMAIN} {
reverse_proxy 192.168.0.28:8188
encode zstd gzip
header {
Strict-Transport-Security: max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# Wallabag
bookmark.{$DOMAIN} {
reverse_proxy 192.168.0.28:8544
encode zstd gzip
header {
Strict-Transport-Security: max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# Portainer
port.{$DOMAIN} {
reverse_proxy 192.168.10.5
encode zstd gzip
header {
Strict-Transport-Security: max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# Leantime
project.{$DOMAIN} {
reverse_proxy 192.168.0.28:8466
encode zstd gzip
header {
Strict-Transport-Security: max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
# ntfy
ntfy.{$DOMAIN} {
import authentik
reverse_proxy ntfy:80
encode zstd gzip
}
# authentik
auth.{$DOMAIN} {
reverse_proxy 192.168.0.28:9000 {
header_down Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"
header_up X-Real-IP {remote_host}
}
header {
Strict-Transport-Security: max-age=31536000;
Referrer-Policy no-referrer-when-downgrade
X-Content-Type-Options nosniff
X-Frame-Options DENY
}
}
5. Links to relevant resources:
Used several examples from caddy.community and this: Caddy | authentik