# nginx vhost: dns.rebreak.org # Deployed on: rebreak-mdm (178.105.101.137) # TLS termination for AdGuard Home DoH endpoint. # # CRITICAL: location uses prefix-match (^~) NOT exact-match (=). # AdGuard Home parses the ClientID from the URL path natively: # /dns-query -> normal DoH query (no ClientID) # /dns-query/ -> DoH query, AdGuard extracts into QueryLog.ClientID # # The full path MUST be forwarded to AdGuard unchanged (no $uri stripping). # AdGuard reads the path segment after /dns-query/ as the ClientID. # Stripping it (e.g. proxy_pass http://.../ without path) would break CID detection. # # AdGuard Home listens on 127.0.0.1:3000 (HTTPS UI) and plain DNS-over-HTTPS # on a dedicated port. Verify actual DoH port on server: # docker exec adguardhome cat /opt/adguardhome/conf/AdGuardHome.yaml | grep -A5 dns: # Common defaults: port 3000 for UI+DoH combined, or separate port 5353/8053. # Adjust proxy_pass port below to match actual AdGuard DoH port. # # Current assumption: AdGuard DoH on 127.0.0.1:3000 (same as UI, AdGuard's default). # If AdGuard runs in docker: verify with `docker ps | grep adguard`. server { listen 80; server_name dns.rebreak.org; return 301 https://dns.rebreak.org$request_uri; } server { listen 443 ssl http2; server_name dns.rebreak.org; ssl_certificate /etc/letsencrypt/live/dns.rebreak.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dns.rebreak.org/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # ── DoH endpoint — prefix match, path forwarded unchanged ─────────────── # ^~ wins over regex locations. Catches both: # /dns-query (plain DoH) # /dns-query/abc1 (DoH with ClientID — AdGuard parses the suffix) # # proxy_pass terminates without trailing slash so $request_uri is appended # as-is, preserving /dns-query/ verbatim. location ^~ /dns-query { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # DoH requests are short-lived; tight timeouts are fine. proxy_connect_timeout 5s; proxy_send_timeout 10s; proxy_read_timeout 10s; } # ── Health check (for monitoring / GH Actions deploy verify) ──────────── location /health { return 200 "OK\n"; add_header Content-Type text/plain; } # ── Block everything else ──────────────────────────────────────────────── location / { return 404; } }