From bac782f7fa1bac0b19a4e6a5313b699c5a9835ce Mon Sep 17 00:00:00 2001 From: Joel Messerli Date: Thu, 11 Jul 2024 22:48:31 +0200 Subject: [PATCH] feat: allow specifying a port for the primaries --- config.example.json | 5 +- config/config_reader.go | 23 +++---- ns/dns/configgenerator.go | 128 ++++++++++++++++++++----------------- ns/dns/zonegenerator.go | 10 +-- templates/bind-config.tmpl | 20 +++--- util/util.go | 8 +-- 6 files changed, 104 insertions(+), 90 deletions(-) diff --git a/config.example.json b/config.example.json index 9d87232..37e7ed3 100644 --- a/config.example.json +++ b/config.example.json @@ -5,10 +5,11 @@ }, "namespaces": { "dns": { - "masters": [ + "primaries": [ { "name": "ns1.example.com", "ip": "192.168.0.1", + "port": 54, "dotted_mail": "user.example.com", "zones": [ "example.com", @@ -26,7 +27,7 @@ ] } ], - "additional_slaves": { + "additional_secondaries": { "f.f.f.f.f.f.f.f.f.f.f.f.ip6.arpa": [ "ffff:fff:fff::21", "ffff:fff:fff::22" diff --git a/config/config_reader.go b/config/config_reader.go index 959e937..79ca9b4 100644 --- a/config/config_reader.go +++ b/config/config_reader.go @@ -15,20 +15,21 @@ type ZoneInclude struct { IncludeFiles []string `json:"include_files"` } -type AdditionalSlavesConfig = map[string][]string - -type MasterConfig struct { - Name string `json:"name"` - IP string `json:"ip"` - DottedEmail string `json:"dotted_mail"` - Zones []string `json:"zones"` - DnssecZones []string `json:"dnssec_zones"` - Includes []ZoneInclude `json:"includes"` - AdditionalSlaves AdditionalSlavesConfig `json:"additional_slaves"` +type AdditionalSecondariesConfig = map[string][]string + +type PrimaryConfig struct { + Name string `json:"name"` + IP string `json:"ip"` + Port int `json:"port"` + DottedEmail string `json:"dotted_mail"` + Zones []string `json:"zones"` + DnssecZones []string `json:"dnssec_zones"` + Includes []ZoneInclude `json:"includes"` + AdditionalSecondaries AdditionalSecondariesConfig `json:"additional_secondaries"` } type DNSNamespaceConfig struct { - Masters []MasterConfig `json:"masters"` + Primaries []PrimaryConfig `json:"primaries"` } type NamespaceConfig struct { diff --git a/ns/dns/configgenerator.go b/ns/dns/configgenerator.go index fc5571f..04f6124 100644 --- a/ns/dns/configgenerator.go +++ b/ns/dns/configgenerator.go @@ -17,48 +17,54 @@ import ( type zoneType string const ( - zoneSlave zoneType = "slave" - zoneMaster zoneType = "master" + zoneSecondary zoneType = "slave" + zonePrimary zoneType = "master" ) type templateZone struct { Name string Type zoneType - IsSlave bool + IsSecondary bool IsDnssecEnabled bool - MasterIP string + PrimaryIP string + PrimaryPort int TransferAcls []string - NotifyMasters []string + NotifyPrimaries []string } -type aclMasterType string +type aclPrimaryType string const ( - listAcl aclMasterType = "acl" - listMaster aclMasterType = "masters" + listAcl aclPrimaryType = "acl" + listPrimaries aclPrimaryType = "masters" ) -type aclMastersList struct { - Type aclMasterType +type primaryIPAndPort struct { + IP string + Port int +} + +type aclPrimaryList struct { + Type aclPrimaryType Name string - Entries []string + Entries []primaryIPAndPort } type configTemplateVars struct { - ServerName string - ServerIP string - GeneratedAt string - Zones []templateZone - AclMasterLists []aclMastersList + ServerName string + ServerIP string + GeneratedAt string + Zones []templateZone + AclPrimaryLists []aclPrimaryList } -const defaultAclName = "nx-slaves-acl" -const defaultMastersName = "nx-slaves-masters" +const defaultAclName = "nx-secondary-acl" +const defaultPrimariesName = "nx-secondary-primaries" -func generateStandardAclMasterLists(masterIps []string) []aclMastersList { - return []aclMastersList{ - {Type: listAcl, Name: defaultAclName, Entries: masterIps}, - {Type: listMaster, Name: defaultMastersName, Entries: masterIps}, +func generateStandardAclPrimaryLists(primaries []primaryIPAndPort) []aclPrimaryList { + return []aclPrimaryList{ + {Type: listAcl, Name: defaultAclName, Entries: primaries}, + {Type: listPrimaries, Name: defaultPrimariesName, Entries: primaries}, } } @@ -68,20 +74,25 @@ func canonicalizeZoneName(zone string) string { return hex.EncodeToString(hasher.Sum(nil))[:8] } -func getAdditionalAclMasterName(zone string, ty aclMasterType) string { +func getAdditionalAclPrimaryName(zone string, ty aclPrimaryType) string { canonicalZone := canonicalizeZoneName(zone) - return fmt.Sprintf("nx-slaves-%s-%s", ty, canonicalZone) + return fmt.Sprintf("nx-secondary-%s-%s", ty, canonicalZone) } -func generateAdditionalAclMasterLists(masterConfig *config.MasterConfig) []aclMastersList { - var lists []aclMastersList +func generateAdditionalAclPrimaryLists(primaryConfig *config.PrimaryConfig) []aclPrimaryList { + var lists []aclPrimaryList + + if primaryConfig.AdditionalSecondaries != nil { + for zone, secondaries := range primaryConfig.AdditionalSecondaries { + var secondariesWithPorts []primaryIPAndPort + for _, secondary := range secondaries { + secondariesWithPorts = append(secondariesWithPorts, primaryIPAndPort{IP: secondary}) // port is empty for now + } - if masterConfig.AdditionalSlaves != nil { - for zone, slaves := range masterConfig.AdditionalSlaves { - lists = append(lists, []aclMastersList{ - {Type: listAcl, Name: getAdditionalAclMasterName(zone, listAcl), Entries: slaves}, - {Type: listMaster, Name: getAdditionalAclMasterName(zone, listMaster), Entries: slaves}, + lists = append(lists, []aclPrimaryList{ + {Type: listAcl, Name: getAdditionalAclPrimaryName(zone, listAcl), Entries: secondariesWithPorts}, + {Type: listPrimaries, Name: getAdditionalAclPrimaryName(zone, listPrimaries), Entries: secondariesWithPorts}, }...) } } @@ -103,61 +114,62 @@ func GenerateConfigs(zones []string, conf *config.NXConfig) { templateVars := configTemplateVars{ GeneratedAt: time.Now().Format(time.RFC3339), } - for _, currentMaster := range conf.Namespaces.DNS.Masters { - templateVars.ServerName = currentMaster.Name - templateVars.ServerIP = currentMaster.IP + for _, currentPrimary := range conf.Namespaces.DNS.Primaries { + templateVars.ServerName = currentPrimary.Name + templateVars.ServerIP = currentPrimary.IP var templateZones []templateZone - for _, zonesMaster := range conf.Namespaces.DNS.Masters { - isMaster := zonesMaster.Name == currentMaster.Name - masterZoneType := zoneMaster - if !isMaster { - masterZoneType = zoneSlave + for _, zonesPrimary := range conf.Namespaces.DNS.Primaries { + isPrimary := zonesPrimary.Name == currentPrimary.Name + serverZoneType := zonePrimary + if !isPrimary { + serverZoneType = zoneSecondary } - for _, zone := range zonesMaster.Zones { + for _, zone := range zonesPrimary.Zones { if !util.SliceContainsString(zones, zone) { continue } transferAcls := []string{defaultAclName} - notifyMasters := []string{defaultMastersName} + notifyPrimaries := []string{defaultPrimariesName} - _, hasAdditionalSlaves := currentMaster.AdditionalSlaves[zone] - if hasAdditionalSlaves { - transferAcls = append(transferAcls, getAdditionalAclMasterName(zone, listAcl)) - notifyMasters = append(notifyMasters, getAdditionalAclMasterName(zone, listMaster)) + _, hasAdditionalSecondaries := currentPrimary.AdditionalSecondaries[zone] + if hasAdditionalSecondaries { + transferAcls = append(transferAcls, getAdditionalAclPrimaryName(zone, listAcl)) + notifyPrimaries = append(notifyPrimaries, getAdditionalAclPrimaryName(zone, listPrimaries)) } - dnssecEnabled := util.SliceContainsString(zonesMaster.DnssecZones, zone) + dnssecEnabled := util.SliceContainsString(zonesPrimary.DnssecZones, zone) templateZones = append(templateZones, templateZone{ - IsSlave: !isMaster, + IsSecondary: !isPrimary, IsDnssecEnabled: dnssecEnabled, - MasterIP: zonesMaster.IP, + PrimaryIP: zonesPrimary.IP, + PrimaryPort: zonesPrimary.Port, Name: zone, - Type: masterZoneType, + Type: serverZoneType, TransferAcls: transferAcls, - NotifyMasters: notifyMasters, + NotifyPrimaries: notifyPrimaries, }) } } templateVars.Zones = templateZones - var masterIPsWithoutCurrent = make([]string, 0, len(conf.Namespaces.DNS.Masters)-1) - for _, master := range conf.Namespaces.DNS.Masters { - if master.IP != currentMaster.IP { - masterIPsWithoutCurrent = append(masterIPsWithoutCurrent, master.IP) + var primaryIpsWithoutCurrent = make([]primaryIPAndPort, 0, len(conf.Namespaces.DNS.Primaries)-1) + for _, primary := range conf.Namespaces.DNS.Primaries { + if primary.IP != currentPrimary.IP { + primaryIpsWithoutCurrent = append(primaryIpsWithoutCurrent, primaryIPAndPort{IP: primary.IP, Port: primary.Port}) } } - aclMastersLists := generateStandardAclMasterLists(masterIPsWithoutCurrent) - aclMastersLists = append(aclMastersLists, generateAdditionalAclMasterLists(¤tMaster)...) - templateVars.AclMasterLists = aclMastersLists + aclPrimaryLists := generateStandardAclPrimaryLists(primaryIpsWithoutCurrent) + aclPrimaryLists = append(aclPrimaryLists, generateAdditionalAclPrimaryLists(¤tPrimary)...) + templateVars.AclPrimaryLists = aclPrimaryLists _, err = cw.WriteTemplate( - fmt.Sprintf("generated/bind-config/%s.conf", currentMaster.Name), + fmt.Sprintf("generated/bind-config/%s.conf", currentPrimary.Name), templateVars, ) if err != nil { diff --git a/ns/dns/zonegenerator.go b/ns/dns/zonegenerator.go index 110e47e..002eef5 100644 --- a/ns/dns/zonegenerator.go +++ b/ns/dns/zonegenerator.go @@ -249,13 +249,13 @@ func GenerateZones(addresses []model.IPAddress, defaultSoaInfo SOAInfo, conf *co templateArgs.ZoneName = zone soaInfo := defaultSoaInfo - masterConf := util.FindMasterForZone(*conf, zone) - if masterConf != nil { - soaInfo.DottedMailResponsible = masterConf.DottedEmail - soaInfo.NameserverFQDN = fmt.Sprintf("%s.", masterConf.Name) + primaryConf := util.FindPrimaryForZone(*conf, zone) + if primaryConf != nil { + soaInfo.DottedMailResponsible = primaryConf.DottedEmail + soaInfo.NameserverFQDN = fmt.Sprintf("%s.", primaryConf.Name) var includes []string - for _, include := range masterConf.Includes { + for _, include := range primaryConf.Includes { if include.Zone == zone { includes = append(includes, include.IncludeFiles...) } diff --git a/templates/bind-config.tmpl b/templates/bind-config.tmpl index 3672b5d..ef44d39 100644 --- a/templates/bind-config.tmpl +++ b/templates/bind-config.tmpl @@ -4,10 +4,10 @@ * Start of config for nameserver {{ .ServerName }} */ -/* acl and master lists */ -{{ range $aclMaster := .AclMasterLists -}} -{{ $aclMaster.Type }} "{{$aclMaster.Name}}" { -{{ range $ip := $aclMaster.Entries }} {{ $ip }}; +/* acl and primary lists */ +{{ range $aclPrimary := .AclPrimaryLists -}} +{{ $aclPrimary.Type }} "{{$aclPrimary.Name}}" { +{{ range $entry := $aclPrimary.Entries }} {{ $entry.IP }}{{ if and ($entry.Port) (eq $aclPrimary.Type "masters") }} port {{ $entry.Port }}{{ end }}; {{ end -}} }; {{ end }} @@ -16,21 +16,21 @@ zone "{{ $zone.Name }}" { type {{ $zone.Type }}; file "/ - {{- if $zone.IsSlave -}} + {{- if $zone.IsSecondary -}} var/cache/bind {{- else -}} etc/bind/zones {{- end -}} /{{ $zone.Name }}.db"; - {{- if $zone.IsSlave }} - masters { {{ $zone.MasterIP }}; }; + {{- if $zone.IsSecondary }} + masters { {{ $zone.PrimaryIP }}{{ if $zone.PrimaryPort }} port {{ $zone.PrimaryPort }}{{ end }}; }; transfer-source {{ $.ServerIP }}; {{- else }} - allow-transfer { {{ range $transfer := $zone.TransferAcls }}"{{ $transfer }}"; {{ end -}} }; - also-notify { {{ range $master := $zone.NotifyMasters }}"{{ $master }}"; {{ end -}} }; + allow-transfer { {{ range $transferAcl := $zone.TransferAcls }}"{{ $transferAcl }}"; {{ end -}} }; + also-notify { {{ range $primaryAcl := $zone.NotifyPrimaries }}"{{ $primaryAcl }}"; {{ end -}} }; notify yes; {{- end -}} - {{- if and ($zone.IsDnssecEnabled) (not $zone.IsSlave) }} + {{- if and ($zone.IsDnssecEnabled) (not $zone.IsSecondary) }} /* This zone is DNSSEC enabled */ dnssec-policy default; inline-signing yes; diff --git a/util/util.go b/util/util.go index 483e1aa..7e17173 100644 --- a/util/util.go +++ b/util/util.go @@ -56,10 +56,10 @@ func SliceContainsString(slice []string, value string) bool { return false } -func FindMasterForZone(conf config.NXConfig, zone string) *config.MasterConfig { - for _, master := range conf.Namespaces.DNS.Masters { - if SliceContainsString(master.Zones, zone) { - return &master +func FindPrimaryForZone(conf config.NXConfig, zone string) *config.PrimaryConfig { + for _, primary := range conf.Namespaces.DNS.Primaries { + if SliceContainsString(primary.Zones, zone) { + return &primary } }