DEVELOPMENT ENVIRONMENT

~liljamo/felu

5234e58e2380f8deb0710b81b5cb1cdf277fe0d1 — Jonni Liljamo 20 days ago 326c993
feat: answer TXT queries for _acme-challenge
1 files changed, 36 insertions(+), 0 deletions(-)

M internal/dns/query.go
M internal/dns/query.go => internal/dns/query.go +36 -0
@@ 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},
		})
	}
}