1. The problem I’m having:
Hi,
I am hosting an Adguard Home instance in Docker, that publishes a DNS over HTTPS server on /dns-query
subpath, that I want to make accessible over the internet. Caddy is behind Cloudflare Tunnel via cloudflared because I cannot open ports with my ISP.
I already have the web admin UI of Adguard proxied through Caddy, on a subdomain. I am also using Authentik with forward auth to protect the administation UI. My caddyfile is the following:
adguard.mydomain.com {
route {
reverse_proxy /dns-query adguard:443
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
forward_auth authentik-server:9000 {
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements 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
uri /outpost.goauthentik.io/auth/caddy
}
reverse_proxy adguard:3000
}
}
I have set the reverse_proxy of /dns-query first so that it is not affected by forward_auth. This rule seems to be working as expected.
The web UI working perfectly, and the forward_auth too, but the DoH is not. I tried to connect to adguard.mydomain.com/dns-query
from devices that supports DoH, and it does not work.
When trying to access adguard.mydomain.com/dns-query
from a browser, I have a Cloudflare error 502, Bad Gateway.
I see no errors appearing on Adguard, Caddy or Cloudflared containers.
I am unsure if the problem comes from Caddy or cloudflare tunnel configuration. To me it looks more like it would come from my Caddy configuration, because if there is an error in my caddy configuration, I have a Cloudflare Bad Gateway error when trying to access.
Any help to get this to work is welcome. Have a nice day !
2. Error messages and/or full log output:
No error message
3. Caddy version:
Caddy v2.9.1
4. How I installed and ran Caddy:
a. System environment:
Docker on Debian
b. Command:
PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.
c. Service/unit/compose file:
services:
adguard:
image: adguard/adguardhome:latest
container_name: adguard
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
ports:
- 53:53
restart: unless-stopped
networks:
- services
volumes:
- ${CONFIG_FOLDER}/adguard/work:/opt/adguardhome/work
# - ${CONFIG_FOLDER}/adguard/conf:/opt/adguardhome/conf
configs:
- source: AdGuardHome.yaml
target: /opt/adguardhome/conf/AdGuardHome.yaml
labels:
caddy: adguard.${DOMAIN}
caddy.route.1_reverse_proxy: /dns-query adguard:443
caddy.route.2_reverse_proxy: /outpost.goauthentik.io/* authentik-server:9000
caddy.route.3_forward_auth: authentik-server:9000
caddy.route.3_forward_auth.uri: /outpost.goauthentik.io/auth/caddy
caddy.route.3_forward_auth.copy_headers: X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements 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
caddy.route.4_reverse_proxy: adguard:3000
networks:
services:
name: services
external: true
configs:
AdGuardHome.yaml:
content: |
http:
pprof:
port: 6060
enabled: false
address: 0.0.0.0:3000
session_ttl: 720h
users:
- name: admin
password: REDACTED
auth_attempts: 5
block_auth_min: 15
http_proxy: ""
language: ""
theme: auto
dns:
bind_hosts:
- 0.0.0.0
port: 53
anonymize_client_ip: false
ratelimit: 20
ratelimit_subnet_len_ipv4: 24
ratelimit_subnet_len_ipv6: 56
ratelimit_whitelist: []
refuse_any: true
upstream_dns:
- https://dns10.quad9.net/dns-query
upstream_dns_file: ""
bootstrap_dns:
- 9.9.9.10
- 149.112.112.10
- 2620:fe::10
- 2620:fe::fe:10
fallback_dns: []
upstream_mode: load_balance
fastest_timeout: 1s
allowed_clients: []
disallowed_clients: []
blocked_hosts:
- version.bind
- id.server
- hostname.bind
trusted_proxies:
- 127.0.0.0/8
- ::1/128
cache_size: 4194304
cache_ttl_min: 0
cache_ttl_max: 0
cache_optimistic: false
bogus_nxdomain: []
aaaa_disabled: false
enable_dnssec: false
edns_client_subnet:
custom_ip: ""
enabled: false
use_custom: false
max_goroutines: 300
handle_ddr: true
ipset: []
ipset_file: ""
bootstrap_prefer_ipv6: false
upstream_timeout: 10s
private_networks: []
use_private_ptr_resolvers: false
local_ptr_upstreams: []
use_dns64: false
dns64_prefixes: []
serve_http3: false
use_http3_upstreams: false
serve_plain_dns: true
hostsfile_enabled: true
tls:
enabled: true
server_name: "adguard.${DOMAIN}"
force_https: false
port_https: 443
port_dns_over_tls: 853
port_dns_over_quic: 853
port_dnscrypt: 0
dnscrypt_config_file: ""
allow_unencrypted_doh: true
certificate_chain: ""
private_key: ""
certificate_path: ""
private_key_path: ""
strict_sni_check: false
querylog:
dir_path: ""
ignored: []
interval: 2160h
size_memory: 1000
enabled: true
file_enabled: true
statistics:
dir_path: ""
ignored: []
interval: 24h
enabled: true
filters:
- enabled: true
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
name: AdGuard DNS filter
id: 1
- enabled: false
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt
name: AdAway Default Blocklist
id: 2
whitelist_filters: []
user_rules: []
dhcp:
enabled: false
interface_name: ""
local_domain_name: lan
dhcpv4:
gateway_ip: ""
subnet_mask: ""
range_start: ""
range_end: ""
lease_duration: 86400
icmp_timeout_msec: 1000
options: []
dhcpv6:
range_start: ""
lease_duration: 86400
ra_slaac_only: false
ra_allow_slaac: false
filtering:
blocking_ipv4: ""
blocking_ipv6: ""
blocked_services:
schedule:
time_zone: Europe/Zurich
ids: []
protection_disabled_until: null
safe_search:
enabled: false
bing: true
duckduckgo: true
ecosia: true
google: true
pixabay: true
yandex: true
youtube: true
blocking_mode: default
parental_block_host: family-block.dns.adguard.com
safebrowsing_block_host: standard-block.dns.adguard.com
rewrites: []
safe_fs_patterns:
- /opt/adguardhome/work/userfilters/*
safebrowsing_cache_size: 1048576
safesearch_cache_size: 1048576
parental_cache_size: 1048576
cache_time: 30
filters_update_interval: 24
blocked_response_ttl: 10
filtering_enabled: true
parental_enabled: false
safebrowsing_enabled: false
protection_enabled: true
clients:
runtime_sources:
whois: true
arp: true
rdns: true
dhcp: true
hosts: true
persistent: []
log:
enabled: true
file: ""
max_backups: 0
max_size: 100
max_age: 3
compress: false
local_time: false
verbose: false
os:
group: ""
user: ""
rlimit_nofile: 0
schema_version: 29
d. My complete Caddy config:
{
acme_dns cloudflare REDACTED
grace_period 10s
storage postgres {
connection_string postgres://caddy:REDACTED@caddy-db:5432/caddy?sslmode=disable
}
}
adguard.mydomain.com {
route {
reverse_proxy /dns-query adguard:443
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
forward_auth authentik-server:9000 {
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements 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
uri /outpost.goauthentik.io/auth/caddy
}
reverse_proxy adguard:3000
}
}
authbeelink.mydomain.com {
reverse_proxy authentik-server:9000
}
giteabeelink.mydomain.com {
reverse_proxy gitea:3000
}
portainerbeelink.mydomain.com {
reverse_proxy portainer:9000
}