Skip to content

Adds DNS-01 challenges for noisebridge.{io,net} using a self-hosted acme-dns server hosted on noisegarden-root. - #553

Merged
mcint merged 7 commits into
noisebridge:masterfrom
ElanHR:dns/noisegarden-root-host-record
Aug 5, 2026
Merged

Adds DNS-01 challenges for noisebridge.{io,net} using a self-hosted acme-dns server hosted on noisegarden-root.#553
mcint merged 7 commits into
noisebridge:masterfrom
ElanHR:dns/noisegarden-root-host-record

Conversation

@ElanHR

@ElanHR ElanHR commented Jul 31, 2026

Copy link
Copy Markdown
Member

No description provided.

Elan Hourticolon-Retzler added 4 commits July 31, 2026 09:11
…cme-dns server hosted on noisegarden-root.
Both zones referenced the Hetzner VPS by literal IP in more than one
place, so moving that host meant finding every occurrence. Each zone now
defines the address once, as a host record alongside m3/m5/m6/m7, and
everything else refers to it by name.

  noisebridge.io   the acme NS target (was a separate acme-dns A record
                   carrying a second copy of the address)
  noisebridge.net  donate (was an A record)

Both zone files now contain the IP exactly once.

Two things worth knowing:

The record is A-only, no AAAA. The host has a public IPv6, but the
cluster on it is single-stack IPv4, so nothing there answers on the v6
address. In noisebridge.io the name is also an NS target, where an AAAA
would send v6-preferring resolvers to an address nothing listens on and
fail ACME challenges intermittently. Add one when the cluster actually
serves v6.

donate is now a CNAME, and the resend/DMARC records sit underneath it.
Strictly, data below a CNAME is occluded; CoreDNS serves it anyway, which
was verified rather than assumed before making the change. Left a comment
on that line, since it is the sort of thing that would break quietly if
the zone ever moved to a different nameserver.

TESTED:

Both zones parse at the strictest checking level:

    named-checkzone -k fail -n fail noisebridge.io  files/coredns/zones/noisebridge.io
    named-checkzone -k fail -n fail noisebridge.net files/coredns/zones/noisebridge.net
    # loaded serial 2026073100 / OK  (both)

Served the real zone files with CoreDNS locally and queried them, rather
than reasoning about the CNAME question:

    donate.noisebridge.net              -> noisegarden-root.noisebridge.net.
                                        -> 204.168.192.161

donate's email authentication still resolves underneath the CNAME:

    resend._domainkey.donate  TXT  "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQK..."
    send.donate               MX   10 feedback-smtp.us-east-1.amazonses.com.
    _dmarc.donate             TXT  "v=DMARC1; p=none;"

The acme delegation produces a proper referral -- no answer, no aa flag,
NS in the authority section, which is what a resolver needs:

    dig TXT <subdomain>.acme.noisebridge.io
    # flags: qr rd; ANSWER: 0, AUTHORITY: 1
    # acme.noisebridge.io. 3600 IN NS noisegarden-root.noisebridge.io.
    # noisegarden-root.noisebridge.io. -> 204.168.192.161

And the four per-host acme accounts that belong to other machines are
untouched, checked explicitly because they live in the same block:

    _acme-challenge.colossus  -> 16c8a8b7-....auth.acme-dns.io.
    _acme-challenge.ducky     -> 331d1498-....auth.acme-dns.io.
    _acme-challenge.garden    -> 89d749fd-....auth.acme-dns.io.
    _acme-challenge.hw        -> 2d7577da-....auth.acme-dns.io.

NOT tested: not deployed. Needs an ansible run against m3 and an AXFR to
ns2.
garden.noisebridge.net is no longer used. Its challenge CNAME was the only
record left for that name -- the host itself has no address record -- so it
pointed an ACME delegation at a machine that is gone.

Leaving it costs nothing operationally but is misleading: the next person
reading this block sees four per-host delegations and reasonably assumes
four live machines, which is exactly the wrong thing to believe when
deciding whether one is safe to touch.

colossus, ducky and hw are untouched and stay on auth.acme-dns.io. They are
separate accounts held by the machines of those names, whose own cert
clients have the credentials.

The acme-dns account behind the dropped record (89d749fd-...) lives on the
public auth.acme-dns.io and cannot be deleted from here; it simply goes
unused. It is recorded in this message rather than left in the zone so the
zone stops advertising a delegation nothing serves.

No serial bump: the serial was already moved to 2026073100 earlier on this
branch and none of it has been published yet, so one bump covers the whole
deploy.

TESTED:

Zone parses at the strictest checking level:

    named-checkzone -k fail -n fail noisebridge.net \
      files/coredns/zones/noisebridge.net
    # loaded serial 2026073100 / OK

Served the real zone with CoreDNS and confirmed the removal took effect
without collateral -- the neighbouring records share the same block, so
they were checked explicitly rather than assumed:

    _acme-challenge.garden.noisebridge.net    -> NXDOMAIN
    _acme-challenge.colossus.noisebridge.net  -> 16c8a8b7-....auth.acme-dns.io.
    _acme-challenge.ducky.noisebridge.net     -> 331d1498-....auth.acme-dns.io.
    _acme-challenge.hw.noisebridge.net        -> 2d7577da-....auth.acme-dns.io.

The apex delegation and donate are unaffected:

    _acme-challenge.noisebridge.net -> 9d3537e8-....acme.noisebridge.io.
    donate.noisebridge.net          -> noisegarden-root.noisebridge.net.
                                    -> 204.168.192.161
The two zones had drifted into describing the same mechanism in different
words and at different lengths, which makes them hard to read together and
easy to update inconsistently.

Both now open with a byte-identical header covering what DNS-01 is for, that
a self-hosted acme-dns answers the challenges, how to register a new
subdomain, and where to read more. Only the notes attached to the individual
records differ, because only those genuinely differ:

  noisebridge.io   the subzone delegation and its NS host
  noisebridge.net  why the target lives in another zone

The comments now describe the current state and nothing else. Narrative
about which account a record used to point at, how to undo the change, and
which host was decommissioned is all gone: it is true only until the next
edit, and the history already holds it. What is left is the part a reader
needs in order to change these records safely -- that the NS host and the
acme-dns config carry the same address, that a lost acme-dns database
strands the CNAME, that a CNAME may target any zone so a signed zone needs
no unsigned delegation, and that the per-host accounts belong to other
machines.

Also corrects the registration recipe, which still told the reader to curl
auth.acme-dns.io. That endpoint is no longer where these accounts live, and
the self-hosted one is deliberately not reachable from outside the cluster,
so following the old instructions would have produced an account on the
wrong server.

Comment-only. No record, TTL or serial changes.

TESTED:

Both zones parse at the strictest checking level:

    named-checkzone -k fail -n fail noisebridge.io  files/coredns/zones/noisebridge.io
    named-checkzone -k fail -n fail noisebridge.net files/coredns/zones/noisebridge.net
    # OK (both)

The shared header is identical rather than merely similar:

    diff <(sed -n '/^; DNS-01/,/^;$/p' .../noisebridge.io) \
         <(sed -n '/^; DNS-01/,/^;$/p' .../noisebridge.net)
    # IDENTICAL

Served both zones with CoreDNS afterwards and re-checked every record the
edit sits next to, since a comment-only change is exactly the kind that gets
committed without verifying it stayed comment-only:

    acme.noisebridge.io                 -> referral to noisegarden-root (1 NS)
    _acme-challenge.noisebridge.io      -> 03171cac-....acme.noisebridge.io.
    _acme-challenge.noisebridge.net     -> 9d3537e8-....acme.noisebridge.io.
    _acme-challenge.garden              -> NXDOMAIN
    _acme-challenge.{colossus,ducky,hw} -> 3/3 unchanged on auth.acme-dns.io
    donate.noisebridge.net              -> noisegarden-root -> 204.168.192.161
    donate DKIM + MX                    -> unchanged

All identical to the previous commit.
@ElanHR
ElanHR force-pushed the dns/noisegarden-root-host-record branch from 2b8fcd4 to 0c2166f Compare July 31, 2026 10:10
auth, code, git, headscale, mail, vault and zulip, as aliases of the
noisegarden-root host record rather than seven copies of its address, so
moving the cluster stays a one-line change.

mail is the webmail portal, not a mail exchanger. That distinction is what
makes a CNAME safe here: an MX target must not be an alias (RFC 2181
section 10.3), and noisebridge.io has no MX record -- its mail is redirected
to noisebridge.net by the apex SPF. If an MX is ever pointed at this name it
has to become an A record first.

code has no service behind it yet; the record is deliberately ahead of the
deployment.

No per-host _acme-challenge records are needed. The zone-wide CNAME already
covers every name here, including the wildcard, so these hostnames are
certificate-ready without further zone edits.

Serial 2026073100 -> 2026073101. Second change to this zone today, and the
increment matters rather than being bookkeeping: the role that ships zone
files does not restart CoreDNS, so the file plugin picks the zone up on its
own timer and only applies one whose serial has increased. Deploying this
after the delegation without the bump would copy the file and change
nothing.

TESTED:

Zone parses at the strictest checking level:

    named-checkzone -k fail -n fail noisebridge.io \
      files/coredns/zones/noisebridge.io
    # loaded serial 2026073101 / OK

Served with CoreDNS; all seven resolve through the alias to the cluster:

    auth       CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161
    code       CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161
    git        CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161
    headscale  CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161
    mail       CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161
    vault      CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161
    zulip      CNAME=noisegarden-root.noisebridge.io.  A=204.168.192.161

Pre-existing names and the delegation are untouched:

    noisebridge.io            -> 216.252.162.220   (apex, still m3)
    brony                     -> 199.241.139.224
    www / blog / webmail      -> unchanged CNAMEs
    acme.noisebridge.io       -> referral to noisegarden-root
    _acme-challenge           -> 03171cac-....acme.noisebridge.io.

The zone still contains the cluster's address exactly once.

NOT tested: nothing serves these hostnames yet. The cluster has no
*.noisebridge.io certificate or gateway listener, so until those land a
browser reaches the gateway and gets a name mismatch rather than NXDOMAIN.
@Doty1154

Copy link
Copy Markdown
Contributor

Perhaps do a dmarc as well, but beyond that idk it seems fine.

Comment thread files/coredns/zones/noisebridge.io

@Doty1154 Doty1154 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems good to me.

Comment thread files/coredns/zones/noisebridge.io
Comment thread files/coredns/zones/noisebridge.io
@mcint
mcint merged commit 518b4fd into noisebridge:master Aug 5, 2026
1 check failed
@ElanHR

ElanHR commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

ansible-playbook site.yml --tags dns --limit primary_dns_server --check --diff

ansible-playbook site.yml --tags dns --limit primary_dns_server

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants