From 5234e58e2380f8deb0710b81b5cb1cdf277fe0d1 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Thu, 24 Oct 2024 12:13:15 +0300 Subject: [PATCH] feat: answer TXT queries for _acme-challenge --- internal/dns/query.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/internal/dns/query.go b/internal/dns/query.go index 889b9a0..433985a 100644 --- a/internal/dns/query.go +++ b/internal/dns/query.go @@ -35,6 +35,8 @@ func parseQuery(m *dns.Msg, r *dns.Msg) { handleNSRecord(&q, m, r) case dns.TypeSOA: handleSOARecord(&q, m, r) + case dns.TypeTXT: + handleTXTRecord(&q, m, r) default: m.SetRcode(r, dns.RcodeNotImplemented) } @@ -117,3 +119,37 @@ func handleSOARecord(q *dns.Question, m *dns.Msg, r *dns.Msg) { m.SetRcode(r, dns.RcodeNameError) } } + +func handleTXTRecord(q *dns.Question, m *dns.Msg, r *dns.Msg) { + qName := strings.ToLower(q.Name) + + // NOTE: This handles only _acme-challenge queries + expectedPrefix := "_acme-challenge." + if !strings.HasPrefix(qName, expectedPrefix) { + m.SetRcode(r, dns.RcodeNameError) + return + } + qNameWithoutPrefix, ok := strings.CutPrefix(qName, expectedPrefix) + if !ok { + m.SetRcode(r, dns.RcodeFormatError) + return + } + + var ddnsDomain string + if index := strings.IndexByte(qNameWithoutPrefix, '.'); index >= 0 { + ddnsDomain = qNameWithoutPrefix[:index] + } else { + m.SetRcode(r, dns.RcodeNameError) + return + } + + txtRecord, err := db.FetchDomainAcmeChallenge(ddnsDomain) + if err != nil { + m.SetRcode(r, dns.RcodeNameError) + } else { + m.Answer = append(m.Answer, &dns.TXT{ + Hdr: dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}, + Txt: []string{txtRecord}, + }) + } +} -- 2.44.1