DESEC: Properly support punycode domains (#3479)

This commit is contained in:
networkException 2025-05-03 14:37:48 +02:00 committed by GitHub
parent 697433563f
commit 25fa91c2e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 8 deletions

View file

@ -7,6 +7,7 @@ import (
"github.com/StackExchange/dnscontrol/v4/models"
"github.com/StackExchange/dnscontrol/v4/pkg/printer"
"github.com/miekg/dns/dnsutil"
)
// nativeToRecord takes a DNS record from deSEC and returns a native RecordConfig struct.
@ -34,7 +35,7 @@ func nativeToRecords(n resourceRecord, origin string) (rcs []*models.RecordConfi
return rcs
}
func recordsToNative(rcs []*models.RecordConfig) []resourceRecord {
func recordsToNative(rcs []*models.RecordConfig, origin string) []resourceRecord {
// Take a list of RecordConfig and return an equivalent list of resourceRecord.
// deSEC requires one resourceRecord for each label:key tuple, therefore we
// might collapse many RecordConfig into one resourceRecord.
@ -42,7 +43,7 @@ func recordsToNative(rcs []*models.RecordConfig) []resourceRecord {
keys := map[models.RecordKey]*resourceRecord{}
var zrs []resourceRecord
for _, r := range rcs {
label := r.GetLabel()
label := dnsutil.TrimDomainName(r.GetLabel(), origin)
if label == "@" {
label = ""
}

View file

@ -12,6 +12,7 @@ import (
"github.com/StackExchange/dnscontrol/v4/pkg/printer"
"github.com/StackExchange/dnscontrol/v4/providers"
"github.com/miekg/dns/dnsutil"
"golang.org/x/net/idna"
)
/*
@ -99,7 +100,12 @@ func (c *desecProvider) GetNameservers(domain string) ([]*models.Nameserver, err
// GetZoneRecords gets the records of a zone and returns them in RecordConfig format.
func (c *desecProvider) GetZoneRecords(domain string, meta map[string]string) (models.Records, error) {
records, err := c.getRecords(domain)
punycodeDomain, err := idna.ToASCII(domain)
if err != nil {
return nil, err
}
records, err := c.getRecords(punycodeDomain)
if err != nil {
return nil, err
}
@ -108,7 +114,7 @@ func (c *desecProvider) GetZoneRecords(domain string, meta map[string]string) (m
existingRecords := []*models.RecordConfig{}
// spew.Dump(records)
for _, rr := range records {
existingRecords = append(existingRecords, nativeToRecords(rr, domain)...)
existingRecords = append(existingRecords, nativeToRecords(rr, punycodeDomain)...)
}
return existingRecords, nil
@ -156,7 +162,12 @@ func PrepDesiredRecords(dc *models.DomainConfig, minTTL uint32) {
// GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records.
func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existing models.Records) ([]*models.Correction, int, error) {
minTTL, ok, err := c.searchDomainIndex(dc.Name)
punycodeName, err := idna.ToASCII(dc.Name)
if err != nil {
return nil, 0, err
}
minTTL, ok, err := c.searchDomainIndex(punycodeName)
if err != nil {
return nil, 0, err
}
@ -191,7 +202,7 @@ func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist
rc.Type = label.Type
rc.Records = make([]string, 0) // empty array of records should delete this rrset
rc.TTL = 3600
shortname := dnsutil.TrimDomainName(label.NameFQDN, dc.Name)
shortname := dnsutil.TrimDomainName(label.NameFQDN, punycodeName)
if shortname == "@" {
shortname = ""
}
@ -205,7 +216,7 @@ func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist
}
} else {
// it must be an update or create, both can be done with the same api call.
ns := recordsToNative(desiredRecords[label])
ns := recordsToNative(desiredRecords[label], punycodeName)
if len(ns) > 1 {
panic("we got more than one resource record to create / modify")
}
@ -229,7 +240,7 @@ func (c *desecProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, exist
Msg: msg,
F: func() error {
rc := rrs
err := c.upsertRR(rc, dc.Name)
err := c.upsertRR(rc, punycodeName)
if err != nil {
return err
}