1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

BIND: Improve SOA serial number handling (#651)

* github.com/miekg/dns
* Greatly simplify the logic for handling serial numbers. Related code was all over the place. Now it is abstracted into one testable method makeSoa. This simplifies code in many other places.
* Update docs/_providers/bind.md: Edit old text. Add SOA description.
* SOA records are now treated like any other record internally. You still can't specify them in dnsconfig.js, but that's by design.
* The URL for issue 491 was wrong in many places
* BIND: Clarify GENERATE_ZONEFILE message
This commit is contained in:
Tom Limoncelli
2020-02-23 13:58:49 -05:00
committed by GitHub
parent 3c41a39252
commit 9812ecd9ff
60 changed files with 708 additions and 254 deletions

View File

@@ -84,6 +84,12 @@ type RecordConfig struct {
NaptrRegexp string `json:"naptrregexp,omitempty"`
SshfpAlgorithm uint8 `json:"sshfpalgorithm,omitempty"`
SshfpFingerprint uint8 `json:"sshfpfingerprint,omitempty"`
SoaMbox string `json:"soambox,omitempty"`
SoaSerial uint32 `json:"soaserial,omitempty"`
SoaRefresh uint32 `json:"soarefresh,omitempty"`
SoaRetry uint32 `json:"soaretry,omitempty"`
SoaExpire uint32 `json:"soaexpire,omitempty"`
SoaMinttl uint32 `json:"soaminttl,omitempty"`
TlsaUsage uint8 `json:"tlsausage,omitempty"`
TlsaSelector uint8 `json:"tlsaselector,omitempty"`
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
@@ -181,6 +187,10 @@ func (rc *RecordConfig) GetLabelFQDN() string {
// extraMaps: a list of maps that should be included in the comparison.
func (rc *RecordConfig) ToDiffable(extraMaps ...map[string]string) string {
content := fmt.Sprintf("%v ttl=%d", rc.GetTargetCombined(), rc.TTL)
if rc.Type == "SOA" {
content = fmt.Sprintf("%s %v %d %d %d %d ttl=%d", rc.Target, rc.SoaMbox, rc.SoaRefresh, rc.SoaRetry, rc.SoaExpire, rc.SoaMinttl, rc.TTL)
// SoaSerial is not used in comparison
}
for _, valueMap := range extraMaps {
// sort the extra values map keys to perform a deterministic
// comparison since Golang maps iteration order is not guaranteed
@@ -246,15 +256,13 @@ func (rc *RecordConfig) ToRR() dns.RR {
case dns.TypeNS:
rr.(*dns.NS).Ns = rc.GetTargetField()
case dns.TypeSOA:
t := strings.Replace(rc.GetTargetField(), `\ `, ` `, -1)
parts := strings.Fields(t)
rr.(*dns.SOA).Ns = parts[0]
rr.(*dns.SOA).Mbox = parts[1]
rr.(*dns.SOA).Serial = atou32(parts[2])
rr.(*dns.SOA).Refresh = atou32(parts[3])
rr.(*dns.SOA).Retry = atou32(parts[4])
rr.(*dns.SOA).Expire = atou32(parts[5])
rr.(*dns.SOA).Minttl = atou32(parts[6])
rr.(*dns.SOA).Ns = rc.GetTargetField()
rr.(*dns.SOA).Mbox = rc.SoaMbox
rr.(*dns.SOA).Serial = rc.SoaSerial
rr.(*dns.SOA).Refresh = rc.SoaRefresh
rr.(*dns.SOA).Retry = rc.SoaRetry
rr.(*dns.SOA).Expire = rc.SoaExpire
rr.(*dns.SOA).Minttl = rc.SoaMinttl
case dns.TypeSRV:
rr.(*dns.SRV).Priority = rc.SrvPriority
rr.(*dns.SRV).Weight = rc.SrvWeight
@@ -318,28 +326,28 @@ func (recs Records) HasRecordTypeName(rtype, name string) bool {
// FQDNMap returns a map of all LabelFQDNs. Useful for making a
// truthtable of labels that exist in Records.
func (r Records) FQDNMap() (m map[string]bool) {
func (recs Records) FQDNMap() (m map[string]bool) {
m = map[string]bool{}
for _, rec := range r {
for _, rec := range recs {
m[rec.GetLabelFQDN()] = true
}
return m
}
// Grouped returns a map of keys to records.
func (r Records) GroupedByKey() map[RecordKey]Records {
// GroupedByKey returns a map of keys to records.
func (recs Records) GroupedByKey() map[RecordKey]Records {
groups := map[RecordKey]Records{}
for _, rec := range r {
for _, rec := range recs {
groups[rec.Key()] = append(groups[rec.Key()], rec)
}
return groups
}
// GroupedByLabel returns a map of keys to records, and their original key order.
func (r Records) GroupedByLabel() ([]string, map[string]Records) {
func (recs Records) GroupedByLabel() ([]string, map[string]Records) {
order := []string{}
groups := map[string]Records{}
for _, rec := range r {
for _, rec := range recs {
if _, found := groups[rec.Name]; !found {
order = append(order, rec.Name)
}
@@ -349,10 +357,10 @@ func (r Records) GroupedByLabel() ([]string, map[string]Records) {
}
// GroupedByFQDN returns a map of keys to records, grouped by FQDN.
func (r Records) GroupedByFQDN() ([]string, map[string]Records) {
func (recs Records) GroupedByFQDN() ([]string, map[string]Records) {
order := []string{}
groups := map[string]Records{}
for _, rec := range r {
for _, rec := range recs {
namefqdn := rec.GetLabelFQDN()
if _, found := groups[namefqdn]; !found {
order = append(order, namefqdn)
@@ -376,9 +384,16 @@ func downcase(recs []*RecordConfig) {
case "ANAME", "CNAME", "MX", "NS", "PTR", "NAPTR", "SRV":
// These record types have a target that is case insensitive, so we downcase it.
r.Target = strings.ToLower(r.Target)
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TLSA", "TXT", "SOA", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT":
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TLSA", "TXT", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT":
// These record types have a target that is case sensitive, or is an IP address. We leave them alone.
// Do nothing.
case "SOA":
if r.Target != "DEFAULT_NOT_SET." {
r.Target = strings.ToLower(r.Target) // .Target stores the Ns
}
if r.SoaMbox != "DEFAULT_NOT_SET." {
r.SoaMbox = strings.ToLower(r.SoaMbox)
}
default:
// TODO: we'd like to panic here, but custom record types complicate things.
}