detached 0b16d6a

Document global DNS config for ACME

commit
0b16d6a9f036f233cdd290a606e7da2bdb566fd3
author
brice · · 2026-05-01 14:01 UTC
parent
0537081
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +22 -0
M docs/config/reference.md +11 -0
@@ -23,6 +23,14 @@ registry_allowed_ips = [] # IPs or CIDR ranges allowed to acc
2323 proxy_allowed_ips = [] # IPs or CIDR ranges allowed to reach the proxy (empty = allow all, e.g. Cloudflare IPs)
2424 registry_listen_address = "" # Bind address for registry (empty = all interfaces, "127.0.0.1" = loopback only)
2525
26+# =============================================================================
27+# DNS
28+# =============================================================================
29+[dns]
30+resolvers = ["1.1.1.1:53", "8.8.8.8:53"] # Recursive resolvers for public DNS visibility checks
31+propagation_timeout = "5m" # Max wait for DNS-01 TXT propagation
32+polling_interval = "5s" # Interval between DNS-01 propagation checks
33+
2634 # =============================================================================
2735 # AUTHENTICATION (required - Gordon won't start without credentials configured)
2836 # =============================================================================
@@ -204,6 +212,9 @@ keep_last = 3 # Keep N newest tags per repository
204212 | `server.registry_allowed_ips` | `[]` | IPs or CIDR ranges allowed to access the registry (empty = allow all) |
205213 | `server.proxy_allowed_ips` | `[]` | IPs or CIDR ranges allowed to reach the proxy (empty = allow all) |
206214 | `server.registry_listen_address` | `""` | Bind address for registry (empty = all interfaces) |
215+| `dns.resolvers` | `["1.1.1.1:53", "8.8.8.8:53"]` | Recursive resolvers used for public DNS visibility checks, including ACME DNS-01 propagation |
216+| `dns.propagation_timeout` | `"5m"` | Maximum time to wait for DNS-01 TXT records to become visible through configured recursive resolvers |
217+| `dns.polling_interval` | `"5s"` | Interval between DNS-01 propagation checks |
207218 | `tls.acme.enabled` | `false` | Enable public ACME certificates (requires `server.tls_port > 0`) |
208219 | `tls.acme.email` | `""` | ACME account email when enabled |
209220 | `tls.acme.challenge` | `"auto"` | ACME challenge mode: `auto`, `http-01`, or `cloudflare-dns-01` |
@@ -23,6 +23,14 @@ registry_allowed_ips = [] # IPs or CIDR ranges allowed to acc
23 proxy_allowed_ips = [] # IPs or CIDR ranges allowed to reach the proxy (empty = allow all, e.g. Cloudflare IPs)23 proxy_allowed_ips = [] # IPs or CIDR ranges allowed to reach the proxy (empty = allow all, e.g. Cloudflare IPs)
24 registry_listen_address = "" # Bind address for registry (empty = all interfaces, "127.0.0.1" = loopback only)24 registry_listen_address = "" # Bind address for registry (empty = all interfaces, "127.0.0.1" = loopback only)
25 25
26+# =============================================================================
27+# DNS
28+# =============================================================================
29+[dns]
30+resolvers = ["1.1.1.1:53", "8.8.8.8:53"] # Recursive resolvers for public DNS visibility checks
31+propagation_timeout = "5m" # Max wait for DNS-01 TXT propagation
32+polling_interval = "5s" # Interval between DNS-01 propagation checks
33+
26 # =============================================================================34 # =============================================================================
27 # AUTHENTICATION (required - Gordon won't start without credentials configured)35 # AUTHENTICATION (required - Gordon won't start without credentials configured)
28 # =============================================================================36 # =============================================================================
@@ -204,6 +212,9 @@ keep_last = 3 # Keep N newest tags per repository
204 | `server.registry_allowed_ips` | `[]` | IPs or CIDR ranges allowed to access the registry (empty = allow all) |212 | `server.registry_allowed_ips` | `[]` | IPs or CIDR ranges allowed to access the registry (empty = allow all) |
205 | `server.proxy_allowed_ips` | `[]` | IPs or CIDR ranges allowed to reach the proxy (empty = allow all) |213 | `server.proxy_allowed_ips` | `[]` | IPs or CIDR ranges allowed to reach the proxy (empty = allow all) |
206 | `server.registry_listen_address` | `""` | Bind address for registry (empty = all interfaces) |214 | `server.registry_listen_address` | `""` | Bind address for registry (empty = all interfaces) |
215+| `dns.resolvers` | `["1.1.1.1:53", "8.8.8.8:53"]` | Recursive resolvers used for public DNS visibility checks, including ACME DNS-01 propagation |
216+| `dns.propagation_timeout` | `"5m"` | Maximum time to wait for DNS-01 TXT records to become visible through configured recursive resolvers |
217+| `dns.polling_interval` | `"5s"` | Interval between DNS-01 propagation checks |
207 | `tls.acme.enabled` | `false` | Enable public ACME certificates (requires `server.tls_port > 0`) |218 | `tls.acme.enabled` | `false` | Enable public ACME certificates (requires `server.tls_port > 0`) |
208 | `tls.acme.email` | `""` | ACME account email when enabled |219 | `tls.acme.email` | `""` | ACME account email when enabled |
209 | `tls.acme.challenge` | `"auto"` | ACME challenge mode: `auto`, `http-01`, or `cloudflare-dns-01` |220 | `tls.acme.challenge` | `"auto"` | ACME challenge mode: `auto`, `http-01`, or `cloudflare-dns-01` |
M docs/config/server.md +11 -0
@@ -92,6 +92,11 @@ Gordon can obtain public certificates through Let's Encrypt-compatible ACME when
9292 [server]
9393 tls_port = 8443
9494
95+[dns]
96+resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
97+propagation_timeout = "5m"
98+polling_interval = "5s"
99+
95100 [tls.acme]
96101 enabled = true
97102 email = "admin@example.com"
@@ -114,6 +119,12 @@ For Cloudflare Full/Strict, Cloudflare terminates browser TLS at the edge and co
114119
115120 Static certificates have priority, then public ACME certificates, then Gordon's internal CA fallback. Gordon uses the `go-acme/lego` ACME client, including its DNS-provider support for Cloudflare DNS-01.
116121
122+DNS-01 uses the Cloudflare API to create TXT records, then checks public DNS visibility through `[dns].resolvers`. These resolvers are recursive resolvers (for example Cloudflare DNS or Google DNS), not the authoritative DNS provider. A domain can be hosted at Cloudflare while Gordon verifies propagation through Google DNS.
123+
124+The defaults avoid relying on host-local DNS. This matters on hosts using Tailscale MagicDNS, split-horizon corporate DNS, or Pi-hole, where `/etc/resolv.conf` may not reflect public DNS visibility as Let's Encrypt sees it.
125+
126+Because Gordon's ACME challenge mode is global, `cloudflare-dns-01` requires a Cloudflare token that can read zones and edit DNS records for every zone used by configured HTTPS routes. If that is not desirable, use `http-01` until Gordon supports per-route or per-zone challenge policy.
127+
117128 #### Direct HTTP Onboarding
118129
119130 When `tls_port` is non-zero, direct HTTP clients (those not arriving through a trusted proxy) are restricted to CA onboarding paths only:
@@ -92,6 +92,11 @@ Gordon can obtain public certificates through Let's Encrypt-compatible ACME when
92 [server]92 [server]
93 tls_port = 844393 tls_port = 8443
94 94
95+[dns]
96+resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
97+propagation_timeout = "5m"
98+polling_interval = "5s"
99+
95 [tls.acme]100 [tls.acme]
96 enabled = true101 enabled = true
97 email = "admin@example.com"102 email = "admin@example.com"
@@ -114,6 +119,12 @@ For Cloudflare Full/Strict, Cloudflare terminates browser TLS at the edge and co
114 119
115 Static certificates have priority, then public ACME certificates, then Gordon's internal CA fallback. Gordon uses the `go-acme/lego` ACME client, including its DNS-provider support for Cloudflare DNS-01.120 Static certificates have priority, then public ACME certificates, then Gordon's internal CA fallback. Gordon uses the `go-acme/lego` ACME client, including its DNS-provider support for Cloudflare DNS-01.
116 121
122+DNS-01 uses the Cloudflare API to create TXT records, then checks public DNS visibility through `[dns].resolvers`. These resolvers are recursive resolvers (for example Cloudflare DNS or Google DNS), not the authoritative DNS provider. A domain can be hosted at Cloudflare while Gordon verifies propagation through Google DNS.
123+
124+The defaults avoid relying on host-local DNS. This matters on hosts using Tailscale MagicDNS, split-horizon corporate DNS, or Pi-hole, where `/etc/resolv.conf` may not reflect public DNS visibility as Let's Encrypt sees it.
125+
126+Because Gordon's ACME challenge mode is global, `cloudflare-dns-01` requires a Cloudflare token that can read zones and edit DNS records for every zone used by configured HTTPS routes. If that is not desirable, use `http-01` until Gordon supports per-route or per-zone challenge policy.
127+
117 #### Direct HTTP Onboarding128 #### Direct HTTP Onboarding
118 129
119 When `tls_port` is non-zero, direct HTTP clients (those not arriving through a trusted proxy) are restricted to CA onboarding paths only:130 When `tls_port` is non-zero, direct HTTP clients (those not arriving through a trusted proxy) are restricted to CA onboarding paths only:

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close