Migrate from dns.RR to dnscontrol.RecordConfig
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
eb39197e11
commit
857e70c079
48
api/zones.go
48
api/zones.go
|
@ -337,7 +337,14 @@ func importZone(c *gin.Context) {
|
|||
rrs = append(rrs, rr)
|
||||
}
|
||||
|
||||
zone.Services, _, err = svcs.AnalyzeZone(domain.DomainName, rrs)
|
||||
rcs, err := models.RRstoRCs(rrs, strings.TrimSuffix(domain.DomainName, "."))
|
||||
if err != nil {
|
||||
log.Printf("Error when converting RRs to RCs of %s: %s", c.ClientIP(), err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Unable to read your zone file: %s", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
zone.Services, _, err = svcs.AnalyzeZone(domain.DomainName, rcs)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
|
@ -395,11 +402,7 @@ func diffZones(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
records, err := models.RRstoRCs(zone.GenerateRRs(domain.DomainName), strings.TrimSuffix(domain.DomainName, "."))
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
records := zone.GenerateRRs(domain.DomainName)
|
||||
|
||||
dc := &models.DomainConfig{
|
||||
Name: strings.TrimSuffix(domain.DomainName, "."),
|
||||
|
@ -449,11 +452,7 @@ func applyZone(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
records, err := models.RRstoRCs(zone.GenerateRRs(domain.DomainName), strings.TrimSuffix(domain.DomainName, "."))
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
records := zone.GenerateRRs(domain.DomainName)
|
||||
|
||||
dc := &models.DomainConfig{
|
||||
Name: strings.TrimSuffix(domain.DomainName, "."),
|
||||
|
@ -550,8 +549,12 @@ func viewZone(c *gin.Context) {
|
|||
|
||||
var ret string
|
||||
|
||||
for _, rr := range zone.GenerateRRs(domain.DomainName) {
|
||||
ret += rr.String() + "\n"
|
||||
for _, rc := range zone.GenerateRRs(domain.DomainName) {
|
||||
if _, ok := dns.StringToType[rc.Type]; ok {
|
||||
ret += rc.ToRR().String() + "\n"
|
||||
} else {
|
||||
ret += fmt.Sprintf("%s %d IN %s %s\n", rc.NameFQDN, rc.TTL, rc.Type, rc.String())
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, ret)
|
||||
|
@ -646,8 +649,10 @@ func deleteZoneService(c *gin.Context) {
|
|||
}
|
||||
|
||||
type serviceRecord struct {
|
||||
String string `json:"str"`
|
||||
Fields *dns.RR `json:"fields,omitempty"`
|
||||
Type string `json:"type"`
|
||||
String string `json:"str"`
|
||||
Fields *models.RecordConfig `json:"fields,omitempty"`
|
||||
RR dns.RR `json:"rr,omitempty"`
|
||||
}
|
||||
|
||||
// getServiceRecords retrieves the records that will be generated by a Service.
|
||||
|
@ -680,10 +685,17 @@ func getServiceRecords(c *gin.Context) {
|
|||
}
|
||||
|
||||
var ret []serviceRecord
|
||||
for _, rr := range svc.GenRRs(subdomain, 3600, domain.DomainName) {
|
||||
for _, rc := range svc.GenRRs(subdomain, 3600, domain.DomainName) {
|
||||
var rr dns.RR
|
||||
if _, ok := dns.StringToType[rc.Type]; ok {
|
||||
rr = rc.ToRR()
|
||||
}
|
||||
|
||||
ret = append(ret, serviceRecord{
|
||||
String: rr.String(),
|
||||
Fields: &rr,
|
||||
Type: rc.Type,
|
||||
String: rc.String(),
|
||||
Fields: rc,
|
||||
RR: rr,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ import (
|
|||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/providers"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Provider is where Domains and Zones can be managed.
|
||||
|
@ -108,17 +107,8 @@ func (p *ProviderCombined) DomainExists(fqdn string) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *ProviderCombined) ImportZone(dn *Domain) (rrs []dns.RR, err error) {
|
||||
rcs, err := p.getZoneRecords(dn.DomainName)
|
||||
if err != nil {
|
||||
return rrs, err
|
||||
}
|
||||
|
||||
for _, rc := range rcs {
|
||||
rrs = append(rrs, rc.ToRR())
|
||||
}
|
||||
|
||||
return
|
||||
func (p *ProviderCombined) ImportZone(dn *Domain) (rcs models.Records, err error) {
|
||||
return p.getZoneRecords(dn.DomainName)
|
||||
}
|
||||
|
||||
func (p *ProviderCombined) GetDomainCorrections(dn *Domain, dc *models.DomainConfig) (rrs []*models.Correction, err error) {
|
||||
|
|
|
@ -36,7 +36,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
)
|
||||
|
||||
// Service represents a service provided by one or more DNS record.
|
||||
|
@ -48,7 +48,7 @@ type Service interface {
|
|||
GenComment(origin string) string
|
||||
|
||||
// genRRs generates corresponding RRs.
|
||||
GenRRs(domain string, ttl uint32, origin string) []dns.RR
|
||||
GenRRs(domain string, ttl uint32, origin string) models.Records
|
||||
}
|
||||
|
||||
// ServiceMeta holds the metadata associated to a Service.
|
||||
|
|
|
@ -36,7 +36,7 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
)
|
||||
|
||||
// ZoneMeta holds the metadata associated to a Zone.
|
||||
|
@ -174,7 +174,7 @@ func (z *Zone) EraseServiceWithoutMeta(subdomain string, origin string, id []byt
|
|||
}
|
||||
|
||||
// GenerateRRs returns all the reals records of the Zone.
|
||||
func (z *Zone) GenerateRRs(origin string) (rrs []dns.RR) {
|
||||
func (z *Zone) GenerateRRs(origin string) (rrs models.Records) {
|
||||
for subdomain, svcs := range z.Services {
|
||||
if subdomain == "" {
|
||||
subdomain = origin
|
||||
|
|
|
@ -34,6 +34,7 @@ package abstract
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -53,25 +54,19 @@ func (s *ACMEChallenge) GenComment(origin string) string {
|
|||
return s.Challenge
|
||||
}
|
||||
|
||||
func (s *ACMEChallenge) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin("_acme-challenge", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: []string{s.Challenge},
|
||||
})
|
||||
func (s *ACMEChallenge) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rr := utils.NewRecordConfig(utils.DomainJoin("_acme-challenge", domain), "TXT", ttl, origin)
|
||||
rr.SetTargetTXT(s.Challenge)
|
||||
rrs = append(rrs, rr)
|
||||
return
|
||||
}
|
||||
|
||||
func acmechallenge_analyze(a *svcs.Analyzer) error {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT, Prefix: "_acme-challenge"}) {
|
||||
domain := strings.TrimPrefix(record.Header().Name, "_acme-challenge.")
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
domain := strings.TrimPrefix(record.NameFQDN, "_acme-challenge.")
|
||||
if record.Type == "TXT" {
|
||||
a.UseRR(record, domain, &ACMEChallenge{
|
||||
Challenge: strings.Join(txt.Txt, ""),
|
||||
Challenge: record.GetTargetTXTJoined(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ package abstract
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -59,31 +60,21 @@ func (s *Delegation) GenComment(origin string) string {
|
|||
return fmt.Sprintf("%d name servers"+ds, len(s.NameServers))
|
||||
}
|
||||
|
||||
func (s *Delegation) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *Delegation) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
for _, ns := range s.NameServers {
|
||||
rrs = append(rrs, &dns.NS{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: domain,
|
||||
Rrtype: dns.TypeNS,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Ns: utils.DomainFQDN(ns, origin),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin(domain), "NS", ttl, origin)
|
||||
rc.SetTarget(utils.DomainFQDN(ns, origin))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
for _, ds := range s.DS {
|
||||
rrs = append(rrs, &dns.DS{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: domain,
|
||||
Rrtype: dns.TypeDS,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
KeyTag: ds.KeyTag,
|
||||
Algorithm: ds.Algorithm,
|
||||
DigestType: ds.DigestType,
|
||||
Digest: ds.Digest,
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin(domain), "DS", ttl, origin)
|
||||
rc.DsKeyTag = ds.KeyTag
|
||||
rc.DsAlgorithm = ds.Algorithm
|
||||
rc.DsDigestType = ds.DigestType
|
||||
rc.DsDigest = ds.Digest
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -92,33 +83,33 @@ func delegation_analyze(a *svcs.Analyzer) error {
|
|||
delegations := map[string]*Delegation{}
|
||||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeNS}) {
|
||||
if record.Header().Name == a.GetOrigin() {
|
||||
if record.NameFQDN == a.GetOrigin() {
|
||||
continue
|
||||
}
|
||||
|
||||
if ns, ok := record.(*dns.NS); ok {
|
||||
if _, ok := delegations[ns.Header().Name]; !ok {
|
||||
delegations[ns.Header().Name] = &Delegation{}
|
||||
if record.Type == "NS" {
|
||||
if _, ok := delegations[record.NameFQDN]; !ok {
|
||||
delegations[record.NameFQDN] = &Delegation{}
|
||||
}
|
||||
|
||||
delegations[ns.Header().Name].NameServers = append(delegations[ns.Header().Name].NameServers, ns.Ns)
|
||||
delegations[record.NameFQDN].NameServers = append(delegations[record.NameFQDN].NameServers, record.GetTargetField())
|
||||
|
||||
a.UseRR(
|
||||
record,
|
||||
ns.Header().Name,
|
||||
delegations[ns.Header().Name],
|
||||
record.NameFQDN,
|
||||
delegations[record.NameFQDN],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for subdomain := range delegations {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeDS, Domain: subdomain}) {
|
||||
if ds, ok := record.(*dns.DS); ok {
|
||||
if record.Type == "DS" {
|
||||
delegations[subdomain].DS = append(delegations[subdomain].DS, svcs.DS{
|
||||
KeyTag: ds.KeyTag,
|
||||
Algorithm: ds.Algorithm,
|
||||
DigestType: ds.DigestType,
|
||||
Digest: ds.Digest,
|
||||
KeyTag: record.DsKeyTag,
|
||||
Algorithm: record.DsAlgorithm,
|
||||
DigestType: record.DsDigestType,
|
||||
Digest: record.DsDigest,
|
||||
})
|
||||
|
||||
a.UseRR(
|
||||
|
|
|
@ -36,6 +36,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/spflib"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -113,80 +115,50 @@ func (s *EMail) GenComment(origin string) string {
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (s *EMail) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *EMail) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
if len(s.MX) > 0 {
|
||||
for _, mx := range s.MX {
|
||||
rrs = append(rrs, &dns.MX{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeMX,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Mx: utils.DomainFQDN(mx.Target, origin),
|
||||
Preference: mx.Preference,
|
||||
})
|
||||
rc := utils.NewRecordConfig(domain, "MX", ttl, origin)
|
||||
rc.MxPreference = mx.Preference
|
||||
rc.SetTarget(utils.DomainFQDN(mx.Target, origin))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
}
|
||||
|
||||
if s.SPF != nil {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: utils.SplitN(s.SPF.String(), 255),
|
||||
})
|
||||
rc := utils.NewRecordConfig(domain, "TXT", ttl, origin)
|
||||
rc.SetTargetTXT(s.SPF.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
|
||||
for selector, d := range s.DKIM {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(selector+"._domainkey", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: utils.SplitN(d.String(), 255),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin(selector+"._domainkey", domain), "TXT", ttl, origin)
|
||||
rc.SetTargetTXT(d.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
|
||||
if s.DMARC != nil {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin("_dmarc", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: utils.SplitN(s.DMARC.String(), 255),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin("_dmarc", domain), "TXT", ttl, origin)
|
||||
rc.SetTargetTXT(s.DMARC.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
|
||||
if s.MTA_STS != nil {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin("_mta-sts", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: utils.SplitN(s.MTA_STS.String(), 255),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin("_mta-sts", domain), "TXT", ttl, origin)
|
||||
rc.SetTargetTXT(s.MTA_STS.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
|
||||
if s.TLS_RPT != nil {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin("_smtp._tls", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: utils.SplitN(s.TLS_RPT.String(), 255),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin("_smtp._tls", domain), "TXT", ttl, origin)
|
||||
rc.SetTargetTXT(s.TLS_RPT.String())
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -196,8 +168,8 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
|
||||
// Handle only MX records
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeMX}) {
|
||||
if mx, ok := record.(*dns.MX); ok {
|
||||
dn := mx.Header().Name
|
||||
if record.Type == "MX" {
|
||||
dn := record.NameFQDN
|
||||
|
||||
if _, ok := services[dn]; !ok {
|
||||
services[dn] = &EMail{}
|
||||
|
@ -206,8 +178,8 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
services[dn].MX = append(
|
||||
services[dn].MX,
|
||||
svcs.MX{
|
||||
Target: mx.Mx,
|
||||
Preference: mx.Preference,
|
||||
Target: record.GetTargetField(),
|
||||
Preference: record.MxPreference,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -225,12 +197,17 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
for domain, service := range services {
|
||||
// Is there SPF record?
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT, Domain: domain, Contains: "v=spf1"}) {
|
||||
if service.SPF == nil {
|
||||
service.SPF = &svcs.SPF{}
|
||||
}
|
||||
if record.Type == "TXT" || record.Type == "SPF" {
|
||||
_, err := spflib.Parse(record.GetTargetTXTJoined(), nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
fields := strings.Fields(service.SPF.Content + " " + strings.TrimPrefix(strings.TrimSpace(strings.Join(txt.Txt, "")), "v=spf1"))
|
||||
if service.SPF == nil {
|
||||
service.SPF = &svcs.SPF{}
|
||||
}
|
||||
|
||||
fields := strings.Fields(service.SPF.Content + " " + strings.TrimPrefix(strings.TrimSpace(record.GetTargetTXTJoined()), "v=spf1"))
|
||||
|
||||
for i := 0; i < len(fields); i += 1 {
|
||||
for j := i + 1; j < len(fields); j += 1 {
|
||||
|
@ -253,14 +230,14 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
service.DKIM = map[string]*svcs.DKIM{}
|
||||
// Is there DKIM record?
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT, SubdomainsOf: "_domainkey." + domain}) {
|
||||
selector := strings.TrimSuffix(record.Header().Name, "._domainkey."+domain)
|
||||
selector := strings.TrimSuffix(record.NameFQDN, "._domainkey."+domain)
|
||||
|
||||
if _, ok := service.DKIM[selector]; !ok {
|
||||
service.DKIM[selector] = &svcs.DKIM{}
|
||||
}
|
||||
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
service.DKIM[selector].Fields = append(service.DKIM[selector].Fields, strings.Split(strings.Join(txt.Txt, ""), ";")...)
|
||||
if record.Type == "TXT" {
|
||||
service.DKIM[selector].Fields = append(service.DKIM[selector].Fields, strings.Split(record.GetTargetTXTJoined(), ";")...)
|
||||
}
|
||||
|
||||
err = a.UseRR(record, domain, service)
|
||||
|
@ -275,8 +252,8 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
service.DMARC = &svcs.DMARC{}
|
||||
}
|
||||
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
service.DMARC.Fields = append(service.DMARC.Fields, strings.Split(strings.TrimPrefix(strings.Join(txt.Txt, ""), "v=DMARC1;"), ";")...)
|
||||
if record.Type == "TXT" {
|
||||
service.DMARC.Fields = append(service.DMARC.Fields, strings.Split(strings.TrimPrefix(record.GetTargetTXTJoined(), "v=DMARC1;"), ";")...)
|
||||
}
|
||||
|
||||
err = a.UseRR(record, domain, service)
|
||||
|
@ -291,8 +268,8 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
service.MTA_STS = &svcs.MTA_STS{}
|
||||
}
|
||||
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
service.MTA_STS.Fields = append(service.MTA_STS.Fields, strings.Split(strings.Join(txt.Txt, ""), ";")...)
|
||||
if record.Type == "TXT" {
|
||||
service.MTA_STS.Fields = append(service.MTA_STS.Fields, strings.Split(record.GetTargetTXTJoined(), ";")...)
|
||||
}
|
||||
|
||||
err = a.UseRR(record, domain, service)
|
||||
|
@ -307,8 +284,8 @@ func email_analyze(a *svcs.Analyzer) (err error) {
|
|||
service.TLS_RPT = &svcs.TLS_RPT{}
|
||||
}
|
||||
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
service.TLS_RPT.Fields = append(service.TLS_RPT.Fields, strings.Split(strings.Join(txt.Txt, ""), ";")...)
|
||||
if record.Type == "TXT" {
|
||||
service.TLS_RPT.Fields = append(service.TLS_RPT.Fields, strings.Split(record.GetTargetTXTJoined(), ";")...)
|
||||
}
|
||||
|
||||
err = a.UseRR(record, domain, service)
|
||||
|
|
|
@ -34,10 +34,12 @@ package abstract
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
"git.happydns.org/happyDomain/services"
|
||||
"git.happydns.org/happyDomain/utils"
|
||||
)
|
||||
|
||||
type GoogleVerif struct {
|
||||
|
@ -52,25 +54,20 @@ func (s *GoogleVerif) GenComment(origin string) string {
|
|||
return s.SiteVerification
|
||||
}
|
||||
|
||||
func (s *GoogleVerif) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: domain,
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: []string{"google-site-verification=" + strings.TrimPrefix(s.SiteVerification, "google-site-verification=")},
|
||||
})
|
||||
func (s *GoogleVerif) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rc := utils.NewRecordConfig(domain, "TXT", ttl, origin)
|
||||
rc.SetTargetTXT("google-site-verification=" + strings.TrimPrefix(s.SiteVerification, "google-site-verification="))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
return
|
||||
}
|
||||
|
||||
func googleverification_analyze(a *svcs.Analyzer) error {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT}) {
|
||||
domain := record.Header().Name
|
||||
if txt, ok := record.(*dns.TXT); ok && strings.HasPrefix(strings.Join(txt.Txt, ""), "google-site-verification=") {
|
||||
domain := record.NameFQDN
|
||||
if record.Type == "TXT" && strings.HasPrefix(record.GetTargetTXTJoined(), "google-site-verification=") {
|
||||
a.UseRR(record, domain, &GoogleVerif{
|
||||
SiteVerification: strings.TrimPrefix(strings.Join(txt.Txt, ""), "google-site-verification="),
|
||||
SiteVerification: strings.TrimPrefix(record.GetTargetTXTJoined(), "google-site-verification="),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ package abstract
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -53,25 +54,19 @@ func (s *KeybaseVerif) GenComment(origin string) string {
|
|||
return s.SiteVerification
|
||||
}
|
||||
|
||||
func (s *KeybaseVerif) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin("_keybase", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: []string{"keybase-site-verification=" + strings.TrimPrefix(s.SiteVerification, "keybase-site-verification=")},
|
||||
})
|
||||
func (s *KeybaseVerif) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin("_keybase", domain), "TXT", ttl, origin)
|
||||
rc.SetTargetTXT("keybase-site-verification=" + strings.TrimPrefix(s.SiteVerification, "keybase-site-verification="))
|
||||
rrs = append(rrs, rc)
|
||||
return
|
||||
}
|
||||
|
||||
func keybaseverification_analyze(a *svcs.Analyzer) error {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT, Prefix: "_keybase"}) {
|
||||
domain := strings.TrimPrefix(record.Header().Name, "_keybase.")
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
domain := strings.TrimPrefix(record.NameFQDN, "_keybase.")
|
||||
if record.Type == "TXT" {
|
||||
a.UseRR(record, domain, &KeybaseVerif{
|
||||
SiteVerification: strings.TrimPrefix(strings.Join(txt.Txt, ""), "keybase-site-verification="),
|
||||
SiteVerification: strings.TrimPrefix(record.GetTargetTXTJoined(), "keybase-site-verification="),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -90,7 +91,7 @@ destloop:
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (s *MatrixIM) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *MatrixIM) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
for _, matrix := range s.Matrix {
|
||||
rrs = append(rrs, matrix.GenRRs(utils.DomainJoin("_matrix._tcp", domain), ttl, origin)...)
|
||||
}
|
||||
|
@ -102,7 +103,7 @@ func matrix_analyze(a *svcs.Analyzer) error {
|
|||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Prefix: "_matrix._tcp.", Type: dns.TypeSRV}) {
|
||||
if srv := svcs.ParseSRV(record); srv != nil {
|
||||
domain := strings.TrimPrefix(record.Header().Name, "_matrix._tcp.")
|
||||
domain := strings.TrimPrefix(record.NameFQDN, "_matrix._tcp.")
|
||||
|
||||
if _, ok := matrixDomains[domain]; !ok {
|
||||
matrixDomains[domain] = &MatrixIM{}
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -59,21 +60,16 @@ func (s *OpenPGP) GenComment(origin string) string {
|
|||
return fmt.Sprintf("%s", s.Username)
|
||||
}
|
||||
|
||||
func (s *OpenPGP) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *OpenPGP) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
if len(s.PublicKey) > 0 {
|
||||
if s.Username != "" {
|
||||
s.Identifier = fmt.Sprintf("%x", sha256.Sum224([]byte(s.Username)))
|
||||
}
|
||||
|
||||
rrs = append(rrs, &dns.OPENPGPKEY{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(fmt.Sprintf("%s._openpgpkey", s.Identifier), domain),
|
||||
Rrtype: dns.TypeOPENPGPKEY,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
PublicKey: base64.StdEncoding.EncodeToString(s.PublicKey),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin(fmt.Sprintf("%s._openpgpkey", s.Identifier), domain), "OPENPGPKEY", ttl, origin)
|
||||
rc.SetTargetOpenPGPKey(base64.StdEncoding.EncodeToString(s.PublicKey))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -95,38 +91,30 @@ func (s *SMimeCert) GenComment(origin string) string {
|
|||
return fmt.Sprintf("%s", s.Username)
|
||||
}
|
||||
|
||||
func (s *SMimeCert) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *SMimeCert) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
if len(s.Certificate) > 0 {
|
||||
if s.Username != "" {
|
||||
s.Identifier = fmt.Sprintf("%x", sha256.Sum224([]byte(s.Username)))
|
||||
}
|
||||
|
||||
rrs = append(rrs, &dns.SMIMEA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(fmt.Sprintf("%s._smimecert", s.Identifier), domain),
|
||||
Rrtype: dns.TypeSMIMEA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Usage: s.CertUsage,
|
||||
Selector: s.Selector,
|
||||
MatchingType: s.MatchingType,
|
||||
Certificate: hex.EncodeToString(s.Certificate),
|
||||
})
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin(fmt.Sprintf("%s._smimecert", s.Identifier), domain), "SMIMEA", ttl, origin)
|
||||
rc.SetTarget(fmt.Sprintf("%d %d %d %s", s.CertUsage, s.Selector, s.MatchingType, hex.EncodeToString(s.Certificate)))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func openpgpkey_analyze(a *svcs.Analyzer) (err error) {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeOPENPGPKEY, Contains: "._openpgpkey."}) {
|
||||
if openpgpkey, ok := record.(*dns.OPENPGPKEY); ok {
|
||||
domain := record.Header().Name
|
||||
if record.Type == "OPENPGPKEY" {
|
||||
domain := record.NameFQDN
|
||||
domain = domain[strings.Index(domain, "._openpgpkey")+13:]
|
||||
|
||||
identifier := strings.TrimSuffix(record.Header().Name, "._openpgpkey."+domain)
|
||||
identifier := strings.TrimSuffix(record.NameFQDN, "._openpgpkey."+domain)
|
||||
|
||||
var pubkey []byte
|
||||
pubkey, err = base64.StdEncoding.DecodeString(strings.TrimSuffix(strings.TrimPrefix(openpgpkey.PublicKey, "( "), " )"))
|
||||
pubkey, err = base64.StdEncoding.DecodeString(strings.Join(strings.Fields(strings.TrimSuffix(strings.TrimPrefix(record.GetOpenPGPKeyField(), "("), ")")), ""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -149,11 +137,13 @@ func openpgpkey_analyze(a *svcs.Analyzer) (err error) {
|
|||
|
||||
func smimea_analyze(a *svcs.Analyzer) (err error) {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeSMIMEA, Contains: "._smimecert."}) {
|
||||
if smimecert, ok := record.(*dns.SMIMEA); ok {
|
||||
domain := record.Header().Name
|
||||
if record.Type == "SMIMEA" {
|
||||
domain := record.NameFQDN
|
||||
domain = domain[strings.Index(domain, "._smimecert")+12:]
|
||||
|
||||
identifier := strings.TrimSuffix(record.Header().Name, "._smimecert."+domain)
|
||||
smimecert := record.ToRR().(*dns.SMIMEA)
|
||||
|
||||
identifier := strings.TrimSuffix(record.NameFQDN, "._smimecert."+domain)
|
||||
|
||||
var cert []byte
|
||||
cert, err = hex.DecodeString(smimecert.Certificate)
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -68,61 +69,51 @@ func (s *Origin) GenComment(origin string) string {
|
|||
return fmt.Sprintf("%s %s %d"+ns, strings.TrimSuffix(s.Ns, "."+origin), strings.TrimSuffix(s.Mbox, "."+origin), s.Serial)
|
||||
}
|
||||
|
||||
func (s *Origin) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.SOA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeSOA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Ns: utils.DomainFQDN(s.Ns, origin),
|
||||
Mbox: utils.DomainFQDN(s.Mbox, origin),
|
||||
Serial: s.Serial,
|
||||
Refresh: uint32(s.Refresh.Seconds()),
|
||||
Retry: uint32(s.Retry.Seconds()),
|
||||
Expire: uint32(s.Expire.Seconds()),
|
||||
Minttl: uint32(s.Negttl.Seconds()),
|
||||
})
|
||||
func (s *Origin) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rc := utils.NewRecordConfig(domain, "SOA", ttl, origin)
|
||||
rc.SoaMbox = utils.DomainFQDN(s.Mbox, origin)
|
||||
rc.SoaSerial = s.Serial
|
||||
rc.SoaRefresh = uint32(s.Refresh.Seconds())
|
||||
rc.SoaRetry = uint32(s.Retry.Seconds())
|
||||
rc.SoaExpire = uint32(s.Expire.Seconds())
|
||||
rc.SoaMinttl = uint32(s.Negttl.Seconds())
|
||||
rc.SetTarget(utils.DomainFQDN(s.Ns, origin))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
for _, ns := range s.NameServers {
|
||||
rrs = append(rrs, &dns.NS{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeNS,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Ns: utils.DomainFQDN(ns, origin),
|
||||
})
|
||||
rc = utils.NewRecordConfig(domain, "NS", ttl, origin)
|
||||
rc.SetTarget(utils.DomainFQDN(ns, origin))
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func origin_analyze(a *svcs.Analyzer) error {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeSOA}) {
|
||||
if soa, ok := record.(*dns.SOA); ok {
|
||||
if record.Type == "SOA" {
|
||||
origin := &Origin{
|
||||
Ns: soa.Ns,
|
||||
Mbox: soa.Mbox,
|
||||
Serial: soa.Serial,
|
||||
Refresh: common.Duration(time.Duration(soa.Refresh) * time.Second),
|
||||
Retry: common.Duration(time.Duration(soa.Retry) * time.Second),
|
||||
Expire: common.Duration(time.Duration(soa.Expire) * time.Second),
|
||||
Negttl: common.Duration(time.Duration(soa.Minttl) * time.Second),
|
||||
Ns: record.GetTargetField(),
|
||||
Mbox: record.SoaMbox,
|
||||
Serial: record.SoaSerial,
|
||||
Refresh: common.Duration(time.Duration(record.SoaRefresh) * time.Second),
|
||||
Retry: common.Duration(time.Duration(record.SoaRetry) * time.Second),
|
||||
Expire: common.Duration(time.Duration(record.SoaExpire) * time.Second),
|
||||
Negttl: common.Duration(time.Duration(record.SoaMinttl) * time.Second),
|
||||
}
|
||||
|
||||
a.UseRR(
|
||||
record,
|
||||
soa.Header().Name,
|
||||
record.NameFQDN,
|
||||
origin,
|
||||
)
|
||||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeNS, Domain: soa.Header().Name}) {
|
||||
if ns, ok := record.(*dns.NS); ok {
|
||||
origin.NameServers = append(origin.NameServers, ns.Ns)
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeNS, Domain: record.NameFQDN}) {
|
||||
if record.Type == "NS" {
|
||||
origin.NameServers = append(origin.NameServers, record.GetTargetField())
|
||||
a.UseRR(
|
||||
record,
|
||||
ns.Header().Name,
|
||||
record.NameFQDN,
|
||||
origin,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ package abstract
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -53,25 +54,19 @@ func (s *ScalewayChallenge) GenComment(origin string) string {
|
|||
return s.Challenge
|
||||
}
|
||||
|
||||
func (s *ScalewayChallenge) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin("_scaleway-challenge", domain),
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: []string{s.Challenge},
|
||||
})
|
||||
func (s *ScalewayChallenge) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rc := utils.NewRecordConfig(utils.DomainJoin("_scaleway-challenge", domain), "TXT", ttl, origin)
|
||||
rc.SetTargetTXT(s.Challenge)
|
||||
rrs = append(rrs, rc)
|
||||
return
|
||||
}
|
||||
|
||||
func scalewaychallenge_analyze(a *svcs.Analyzer) error {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT, Prefix: "_scaleway-challenge"}) {
|
||||
domain := strings.TrimPrefix(record.Header().Name, "_scaleway-challenge.")
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
domain := strings.TrimPrefix(record.NameFQDN, "_scaleway-challenge.")
|
||||
if record.Type == "TXT" {
|
||||
a.UseRR(record, domain, &ScalewayChallenge{
|
||||
Challenge: strings.Join(txt.Txt, ""),
|
||||
Challenge: record.GetTargetTXTJoined(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -74,51 +75,36 @@ func (s *Server) GenComment(origin string) string {
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (s *Server) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *Server) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
if s.A != nil && len(*s.A) != 0 {
|
||||
rrs = append(rrs, &dns.A{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
A: *s.A,
|
||||
})
|
||||
rc := utils.NewRecordConfig(domain, "A", ttl, origin)
|
||||
rc.SetTargetIP(*s.A)
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
if s.AAAA != nil && len(*s.AAAA) != 0 {
|
||||
rrs = append(rrs, &dns.AAAA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeAAAA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
AAAA: *s.AAAA,
|
||||
})
|
||||
rc := utils.NewRecordConfig(domain, "AAAA", ttl, origin)
|
||||
rc.SetTargetIP(*s.AAAA)
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
for _, sshfp := range s.SSHFP {
|
||||
rrs = append(rrs, &dns.SSHFP{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeSSHFP,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Algorithm: sshfp.Algorithm,
|
||||
Type: sshfp.Type,
|
||||
FingerPrint: sshfp.FingerPrint,
|
||||
})
|
||||
rc := utils.NewRecordConfig(domain, "SSHFP", ttl, origin)
|
||||
rc.SshfpAlgorithm = sshfp.Algorithm
|
||||
rc.SshfpFingerprint = sshfp.Type
|
||||
rc.SetTarget(sshfp.FingerPrint)
|
||||
|
||||
rrs = append(rrs, rc)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func server_analyze(a *svcs.Analyzer) error {
|
||||
pool := map[string][]dns.RR{}
|
||||
pool := map[string]models.Records{}
|
||||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeA}, svcs.AnalyzerRecordFilter{Type: dns.TypeAAAA}, svcs.AnalyzerRecordFilter{Type: dns.TypeSSHFP}) {
|
||||
domain := record.Header().Name
|
||||
domain := record.NameFQDN
|
||||
|
||||
pool[domain] = append(pool[domain], record)
|
||||
}
|
||||
|
@ -128,24 +114,25 @@ next_pool:
|
|||
s := &Server{}
|
||||
|
||||
for _, rr := range rrs {
|
||||
if rr.Header().Rrtype == dns.TypeA {
|
||||
if rr.Type == "A" {
|
||||
if s.A != nil {
|
||||
continue next_pool
|
||||
}
|
||||
|
||||
s.A = &rr.(*dns.A).A
|
||||
} else if rr.Header().Rrtype == dns.TypeAAAA {
|
||||
addr := rr.GetTargetIP()
|
||||
s.A = &addr
|
||||
} else if rr.Type == "AAAA" {
|
||||
if s.AAAA != nil {
|
||||
continue next_pool
|
||||
}
|
||||
|
||||
s.AAAA = &rr.(*dns.AAAA).AAAA
|
||||
} else if rr.Header().Rrtype == dns.TypeSSHFP {
|
||||
sshfp := rr.(*dns.SSHFP)
|
||||
addr := rr.GetTargetIP()
|
||||
s.AAAA = &addr
|
||||
} else if rr.Type == "SSHFP" {
|
||||
s.SSHFP = append(s.SSHFP, &svcs.SSHFP{
|
||||
Algorithm: sshfp.Algorithm,
|
||||
Type: sshfp.Type,
|
||||
FingerPrint: sshfp.FingerPrint,
|
||||
Algorithm: rr.SshfpAlgorithm,
|
||||
Type: rr.SshfpFingerprint,
|
||||
FingerPrint: rr.GetTargetField(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -97,7 +98,7 @@ destloop:
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (s *XMPP) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *XMPP) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
for _, jabber := range s.Client {
|
||||
rrs = append(rrs, jabber.GenRRs(utils.DomainJoin("_jabber._tcp", domain), ttl, origin)...)
|
||||
}
|
||||
|
@ -116,7 +117,7 @@ func (s *XMPP) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
|||
func xmpp_subanalyze(a *svcs.Analyzer, prefix string, xmppDomains map[string]*XMPP, field string) error {
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Prefix: prefix, Type: dns.TypeSRV}) {
|
||||
if srv := svcs.ParseSRV(record); srv != nil {
|
||||
domain := strings.TrimPrefix(record.Header().Name, prefix)
|
||||
domain := strings.TrimPrefix(record.NameFQDN, prefix)
|
||||
|
||||
if _, ok := xmppDomains[domain]; !ok {
|
||||
xmppDomains[domain] = &XMPP{}
|
||||
|
|
|
@ -34,10 +34,12 @@ package svcs
|
|||
import (
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -46,7 +48,7 @@ import (
|
|||
|
||||
type Analyzer struct {
|
||||
origin string
|
||||
zone []dns.RR
|
||||
zone models.Records
|
||||
services map[string][]*happydns.ServiceCombined
|
||||
defaultTTL uint32
|
||||
}
|
||||
|
@ -61,20 +63,18 @@ type AnalyzerRecordFilter struct {
|
|||
SubdomainsOf string
|
||||
Contains string
|
||||
Type uint16
|
||||
Class uint16
|
||||
Ttl uint32
|
||||
}
|
||||
|
||||
func (a *Analyzer) SearchRR(arrs ...AnalyzerRecordFilter) (rrs []dns.RR) {
|
||||
func (a *Analyzer) SearchRR(arrs ...AnalyzerRecordFilter) (rrs models.Records) {
|
||||
for _, record := range a.zone {
|
||||
for _, arr := range arrs {
|
||||
if strings.HasPrefix(record.Header().Name, arr.Prefix) &&
|
||||
strings.HasSuffix(record.Header().Name, arr.SubdomainsOf) &&
|
||||
(arr.Domain == "" || record.Header().Name == arr.Domain) &&
|
||||
(arr.Type == 0 || record.Header().Rrtype == arr.Type) &&
|
||||
(arr.Class == 0 || record.Header().Class == arr.Class) &&
|
||||
(arr.Ttl == 0 || record.Header().Ttl == arr.Ttl) &&
|
||||
(arr.Contains == "" || strings.Contains(record.String(), arr.Contains)) {
|
||||
if rdtype, ok := dns.StringToType[record.Type]; strings.HasPrefix(record.NameFQDN, arr.Prefix) &&
|
||||
strings.HasSuffix(record.NameFQDN, arr.SubdomainsOf) &&
|
||||
(arr.Domain == "" || record.NameFQDN == arr.Domain) &&
|
||||
(arr.Type == 0 || (ok && rdtype == arr.Type)) &&
|
||||
(arr.Ttl == 0 || record.TTL == arr.Ttl) &&
|
||||
(arr.Contains == "" || strings.Contains(fmt.Sprintf("%s. %d IN %s %s", record.NameFQDN, record.TTL, record.Type, record.String()), arr.Contains)) {
|
||||
rrs = append(rrs, record)
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ func (a *Analyzer) SearchRR(arrs ...AnalyzerRecordFilter) (rrs []dns.RR) {
|
|||
return
|
||||
}
|
||||
|
||||
func (a *Analyzer) UseRR(rr dns.RR, domain string, svc happydns.Service) error {
|
||||
func (a *Analyzer) UseRR(rr *models.RecordConfig, domain string, svc happydns.Service) error {
|
||||
found := false
|
||||
for k, record := range a.zone {
|
||||
if record == rr {
|
||||
|
@ -103,7 +103,7 @@ func (a *Analyzer) UseRR(rr dns.RR, domain string, svc happydns.Service) error {
|
|||
}
|
||||
|
||||
// Remove origin to get an relative domain here
|
||||
domain = strings.TrimSuffix(strings.TrimSuffix(domain, "."+a.origin), a.origin)
|
||||
domain = strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(domain, "."), strings.TrimSuffix(a.origin, ".")), ".")
|
||||
|
||||
for _, service := range a.services[domain] {
|
||||
if service.Service == svc {
|
||||
|
@ -117,8 +117,8 @@ func (a *Analyzer) UseRR(rr dns.RR, domain string, svc happydns.Service) error {
|
|||
io.WriteString(hash, rr.String())
|
||||
|
||||
var ttl uint32 = 0
|
||||
if rr.Header().Ttl != a.defaultTTL {
|
||||
ttl = rr.Header().Ttl
|
||||
if rr.TTL != a.defaultTTL {
|
||||
ttl = rr.TTL
|
||||
}
|
||||
|
||||
a.services[domain] = append(a.services[domain], &happydns.ServiceCombined{
|
||||
|
@ -136,10 +136,10 @@ func (a *Analyzer) UseRR(rr dns.RR, domain string, svc happydns.Service) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getMostUsedTTL(zone []dns.RR) uint32 {
|
||||
func getMostUsedTTL(zone models.Records) uint32 {
|
||||
ttls := map[uint32]int{}
|
||||
for _, rr := range zone {
|
||||
ttls[rr.Header().Ttl] += 1
|
||||
ttls[rr.TTL] += 1
|
||||
}
|
||||
|
||||
var max uint32 = 0
|
||||
|
@ -152,7 +152,7 @@ func getMostUsedTTL(zone []dns.RR) uint32 {
|
|||
return max
|
||||
}
|
||||
|
||||
func AnalyzeZone(origin string, zone []dns.RR) (svcs map[string][]*happydns.ServiceCombined, defaultTTL uint32, err error) {
|
||||
func AnalyzeZone(origin string, zone models.Records) (svcs map[string][]*happydns.ServiceCombined, defaultTTL uint32, err error) {
|
||||
defaultTTL = getMostUsedTTL(zone)
|
||||
|
||||
a := Analyzer{
|
||||
|
@ -178,26 +178,26 @@ func AnalyzeZone(origin string, zone []dns.RR) (svcs map[string][]*happydns.Serv
|
|||
// Consider records not used by services as Orphan
|
||||
for _, record := range a.zone {
|
||||
// Skip DNSSEC records
|
||||
if utils.IsDNSSECType(record.Header().Rrtype) {
|
||||
if rdtype, ok := dns.StringToType[record.Type]; ok && utils.IsDNSSECType(rdtype) {
|
||||
continue
|
||||
}
|
||||
if record.Header().Name == "__dnssec."+origin && record.Header().Rrtype == dns.TypeTXT {
|
||||
if record.NameFQDN == "__dnssec."+origin && record.Type == "TXT" {
|
||||
continue
|
||||
}
|
||||
|
||||
domain := strings.TrimSuffix(strings.TrimSuffix(record.Header().Name, "."+a.origin), a.origin)
|
||||
domain := strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(record.NameFQDN, "."), strings.TrimSuffix(a.origin, ".")), ".")
|
||||
|
||||
hash := sha1.New()
|
||||
io.WriteString(hash, record.String())
|
||||
|
||||
orphan := &Orphan{record.String()[strings.LastIndex(record.Header().String(), "\tIN\t")+4:]}
|
||||
orphan := &Orphan{record.Type, record.String()}
|
||||
svcs[domain] = append(svcs[domain], &happydns.ServiceCombined{
|
||||
Service: orphan,
|
||||
ServiceMeta: happydns.ServiceMeta{
|
||||
Id: hash.Sum(nil),
|
||||
Type: reflect.Indirect(reflect.ValueOf(orphan)).Type().String(),
|
||||
Domain: domain,
|
||||
Ttl: record.Header().Ttl,
|
||||
Ttl: record.TTL,
|
||||
NbResources: 1,
|
||||
Comment: orphan.GenComment(a.origin),
|
||||
},
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -53,16 +54,10 @@ func (s *CNAME) GenComment(origin string) string {
|
|||
return strings.TrimSuffix(s.Target, "."+origin)
|
||||
}
|
||||
|
||||
func (s *CNAME) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.CNAME{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(domain),
|
||||
Rrtype: dns.TypeCNAME,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Target: utils.DomainFQDN(s.Target, origin),
|
||||
})
|
||||
func (s *CNAME) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rr := utils.NewRecordConfig(domain, "CNAME", ttl, origin)
|
||||
rr.SetTarget(utils.DomainFQDN(s.Target, origin))
|
||||
rrs = append(rrs, rr)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -79,27 +74,21 @@ func (s *SpecialCNAME) GenComment(origin string) string {
|
|||
return "(" + s.SubDomain + ") -> " + strings.TrimSuffix(s.Target, "."+origin)
|
||||
}
|
||||
|
||||
func (s *SpecialCNAME) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.CNAME{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(s.SubDomain, domain),
|
||||
Rrtype: dns.TypeCNAME,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Target: utils.DomainFQDN(s.Target, origin),
|
||||
})
|
||||
func (s *SpecialCNAME) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rr := utils.NewRecordConfig(utils.DomainJoin(s.SubDomain, domain), "CNAME", ttl, origin)
|
||||
rr.SetTarget(utils.DomainFQDN(s.Target, origin))
|
||||
rrs = append(rrs, rr)
|
||||
return
|
||||
}
|
||||
|
||||
func specialalias_analyze(a *Analyzer) error {
|
||||
// Try handle specials domains using CNAME
|
||||
for _, record := range a.SearchRR(AnalyzerRecordFilter{Type: dns.TypeCNAME, Prefix: "_"}) {
|
||||
subdomains := SRV_DOMAIN.FindStringSubmatch(record.Header().Name)
|
||||
if cname, ok := record.(*dns.CNAME); len(subdomains) == 4 && ok {
|
||||
subdomains := SRV_DOMAIN.FindStringSubmatch(record.NameFQDN)
|
||||
if record.Type == "CNAME" && len(subdomains) == 4 {
|
||||
a.UseRR(record, subdomains[3], &SpecialCNAME{
|
||||
SubDomain: fmt.Sprintf("_%s._%s", subdomains[1], subdomains[2]),
|
||||
Target: cname.Target,
|
||||
Target: record.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -108,12 +97,12 @@ func specialalias_analyze(a *Analyzer) error {
|
|||
|
||||
func alias_analyze(a *Analyzer) error {
|
||||
for _, record := range a.SearchRR(AnalyzerRecordFilter{Type: dns.TypeCNAME}) {
|
||||
if cname, ok := record.(*dns.CNAME); ok {
|
||||
if record.Type == "CNAME" {
|
||||
newrr := &CNAME{
|
||||
Target: strings.TrimSuffix(cname.Target, "."+a.origin),
|
||||
Target: strings.TrimSuffix(record.String(), "."+a.origin),
|
||||
}
|
||||
|
||||
a.UseRR(record, cname.Header().Name, newrr)
|
||||
a.UseRR(record, record.NameFQDN, newrr)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -33,14 +33,18 @@ package svcs
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
"git.happydns.org/happyDomain/utils"
|
||||
)
|
||||
|
||||
type Orphan struct {
|
||||
RR string
|
||||
Type string
|
||||
RR string
|
||||
}
|
||||
|
||||
func (s *Orphan) GetNbResources() int {
|
||||
|
@ -48,15 +52,25 @@ func (s *Orphan) GetNbResources() int {
|
|||
}
|
||||
|
||||
func (s *Orphan) GenComment(origin string) string {
|
||||
return s.RR
|
||||
return fmt.Sprintf("%s %s", s.Type, s.RR)
|
||||
}
|
||||
|
||||
func (s *Orphan) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rr, _ := dns.NewRR(fmt.Sprintf("$ORIGIN %s\n%s %d IN %s", origin, domain, ttl, s.RR))
|
||||
if rr != nil {
|
||||
rrs = append(rrs, rr)
|
||||
func (s *Orphan) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
if _, ok := dns.StringToType[s.Type]; ok {
|
||||
rr, err := dns.NewRR(fmt.Sprintf("%s %d IN %s %s", utils.DomainJoin(domain), ttl, s.Type, s.RR))
|
||||
if err == nil {
|
||||
rc, err := models.RRtoRC(rr, strings.TrimSuffix(origin, "."))
|
||||
if err == nil {
|
||||
rrs = append(rrs, &rc)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rr := utils.NewRecordConfig(domain, s.Type, ttl, origin)
|
||||
rr.SetTarget(s.RR)
|
||||
rrs = append(rrs, rr)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ package google // import "git.happydns.org/happyDomain/services/providers/google
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -81,7 +82,7 @@ func (s *GSuite) GenComment(origin string) string {
|
|||
return strings.Join(comments, ", ")
|
||||
}
|
||||
|
||||
func (s *GSuite) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *GSuite) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
for _, svc := range s.GenKnownSvcs() {
|
||||
rrs = append(rrs, svc.GenRRs(domain, ttl, origin)...)
|
||||
}
|
||||
|
@ -92,9 +93,9 @@ func gsuite_analyze(a *svcs.Analyzer) (err error) {
|
|||
var googlemx []string
|
||||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeMX}) {
|
||||
if mx, ok := record.(*dns.MX); ok {
|
||||
if strings.ToLower(mx.Mx) == "aspmx.l.google.com." {
|
||||
googlemx = append(googlemx, mx.Header().Name)
|
||||
if record.Type == "MX" {
|
||||
if strings.ToLower(record.GetTargetField()) == "aspmx.l.google.com." {
|
||||
googlemx = append(googlemx, record.NameFQDN)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -105,9 +106,9 @@ func gsuite_analyze(a *svcs.Analyzer) (err error) {
|
|||
googlerr := &GSuite{}
|
||||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeMX, Domain: dn}) {
|
||||
if mx, ok := record.(*dns.MX); ok {
|
||||
if strings.HasSuffix(mx.Mx, "mx-verification.google.com.") {
|
||||
googlerr.ValidationCode = mx.Mx
|
||||
if record.Type == "MX" {
|
||||
if strings.HasSuffix(record.GetTargetField(), "mx-verification.google.com.") {
|
||||
googlerr.ValidationCode = record.GetTargetField()
|
||||
if err = a.UseRR(
|
||||
record,
|
||||
dn,
|
||||
|
@ -115,7 +116,7 @@ func gsuite_analyze(a *svcs.Analyzer) (err error) {
|
|||
); err != nil {
|
||||
return
|
||||
}
|
||||
} else if strings.HasSuffix(mx.Mx, "google.com.") {
|
||||
} else if strings.HasSuffix(record.GetTargetField(), "google.com.") {
|
||||
if err = a.UseRR(
|
||||
record,
|
||||
dn,
|
||||
|
@ -128,8 +129,8 @@ func gsuite_analyze(a *svcs.Analyzer) (err error) {
|
|||
}
|
||||
|
||||
for _, record := range a.SearchRR(svcs.AnalyzerRecordFilter{Type: dns.TypeTXT, Domain: dn}) {
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
content := strings.Join(txt.Txt, "")
|
||||
if record.Type == "TXT" {
|
||||
content := record.GetTargetTXTJoined()
|
||||
if strings.HasPrefix(content, "v=spf1") && strings.Contains(content, "_spf.google.com") {
|
||||
if err = a.UseRR(
|
||||
record,
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -57,29 +58,24 @@ func (s *SRV) GenComment(origin string) string {
|
|||
return fmt.Sprintf("%s:%d", strings.TrimSuffix(s.Target, "."+origin), s.Port)
|
||||
}
|
||||
|
||||
func (s *SRV) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.SRV{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: domain,
|
||||
Rrtype: dns.TypeSRV,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Priority: s.Priority,
|
||||
Weight: s.Weight,
|
||||
Port: s.Port,
|
||||
Target: utils.DomainFQDN(s.Target, origin),
|
||||
})
|
||||
func (s *SRV) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rr := utils.NewRecordConfig(domain, "SRV", ttl, origin)
|
||||
rr.SrvPriority = s.Priority
|
||||
rr.SrvWeight = s.Weight
|
||||
rr.SrvPort = s.Port
|
||||
rr.SetTarget(utils.DomainFQDN(s.Target, origin))
|
||||
|
||||
rrs = append(rrs, rr)
|
||||
return
|
||||
}
|
||||
|
||||
func ParseSRV(record dns.RR) (ret *SRV) {
|
||||
if srv, ok := record.(*dns.SRV); ok {
|
||||
func ParseSRV(record *models.RecordConfig) (ret *SRV) {
|
||||
if record.Type == "SRV" {
|
||||
ret = &SRV{
|
||||
Priority: srv.Priority,
|
||||
Weight: srv.Weight,
|
||||
Port: srv.Port,
|
||||
Target: srv.Target,
|
||||
Priority: record.SrvPriority,
|
||||
Weight: record.SrvWeight,
|
||||
Port: record.SrvPort,
|
||||
Target: record.GetTargetField(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +100,7 @@ func (s *UnknownSRV) GenComment(origin string) string {
|
|||
return fmt.Sprintf("%s (%s)", s.Name, s.Proto)
|
||||
}
|
||||
|
||||
func (s *UnknownSRV) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (s *UnknownSRV) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
for _, service := range s.SRV {
|
||||
rrs = append(rrs, service.GenRRs(utils.DomainJoin(fmt.Sprintf("_%s._%s", s.Name, s.Proto), domain), ttl, origin)...)
|
||||
}
|
||||
|
@ -115,7 +111,7 @@ func srv_analyze(a *Analyzer) error {
|
|||
srvDomains := map[string]map[string]*UnknownSRV{}
|
||||
|
||||
for _, record := range a.SearchRR(AnalyzerRecordFilter{Type: dns.TypeSRV}) {
|
||||
subdomains := SRV_DOMAIN.FindStringSubmatch(record.Header().Name)
|
||||
subdomains := SRV_DOMAIN.FindStringSubmatch(record.NameFQDN)
|
||||
if srv := ParseSRV(record); len(subdomains) == 4 && srv != nil {
|
||||
svc := subdomains[1] + "." + subdomains[2]
|
||||
domain := subdomains[3]
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
|
@ -98,21 +99,15 @@ protoloop:
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (ss *TLSAs) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
func (ss *TLSAs) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
for _, s := range ss.TLSA {
|
||||
if len(s.Certificate) > 0 {
|
||||
rrs = append(rrs, &dns.TLSA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: utils.DomainJoin(fmt.Sprintf("_%d._%s", s.Port, s.Proto), domain),
|
||||
Rrtype: dns.TypeTLSA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Usage: s.CertUsage,
|
||||
Selector: s.Selector,
|
||||
MatchingType: s.MatchingType,
|
||||
Certificate: hex.EncodeToString(s.Certificate),
|
||||
})
|
||||
rr := utils.NewRecordConfig(utils.DomainJoin(fmt.Sprintf("_%d._%s", s.Port, s.Proto), domain), "TLSA", ttl, origin)
|
||||
rr.TlsaUsage = s.CertUsage
|
||||
rr.TlsaSelector = s.Selector
|
||||
rr.TlsaMatchingType = s.MatchingType
|
||||
rr.SetTarget(hex.EncodeToString(s.Certificate))
|
||||
rrs = append(rrs, rr)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -125,13 +120,13 @@ var (
|
|||
func tlsa_analyze(a *Analyzer) (err error) {
|
||||
pool := map[string]*TLSAs{}
|
||||
for _, record := range a.SearchRR(AnalyzerRecordFilter{Type: dns.TypeTLSA}) {
|
||||
subdomains := TLSA_DOMAIN.FindStringSubmatch(record.Header().Name)
|
||||
if tlsa, ok := record.(*dns.TLSA); len(subdomains) == 4 && ok {
|
||||
subdomains := TLSA_DOMAIN.FindStringSubmatch(record.NameFQDN)
|
||||
if record.Type == "TLSA" && len(subdomains) == 4 {
|
||||
var port uint64
|
||||
port, err = strconv.ParseUint(subdomains[1], 10, 16)
|
||||
|
||||
var cert []byte
|
||||
cert, err = hex.DecodeString(tlsa.Certificate)
|
||||
cert, err = hex.DecodeString(record.GetTargetField())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -145,9 +140,9 @@ func tlsa_analyze(a *Analyzer) (err error) {
|
|||
&TLSA{
|
||||
Port: uint16(port),
|
||||
Proto: subdomains[2],
|
||||
CertUsage: tlsa.Usage,
|
||||
Selector: tlsa.Selector,
|
||||
MatchingType: tlsa.MatchingType,
|
||||
CertUsage: record.TlsaUsage,
|
||||
Selector: record.TlsaSelector,
|
||||
MatchingType: record.TlsaMatchingType,
|
||||
Certificate: cert,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -34,9 +34,11 @@ package svcs
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
"git.happydns.org/happyDomain/utils"
|
||||
)
|
||||
|
||||
type TXT struct {
|
||||
|
@ -51,31 +53,25 @@ func (ss *TXT) GenComment(origin string) string {
|
|||
return ss.Content
|
||||
}
|
||||
|
||||
func (ss *TXT) GenRRs(domain string, ttl uint32, origin string) (rrs []dns.RR) {
|
||||
rrs = append(rrs, &dns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: domain,
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: ttl,
|
||||
},
|
||||
Txt: []string{ss.Content},
|
||||
})
|
||||
func (ss *TXT) GenRRs(domain string, ttl uint32, origin string) (rrs models.Records) {
|
||||
rr := utils.NewRecordConfig(domain, "TXT", ttl, origin)
|
||||
rr.SetTargetTXT(ss.Content)
|
||||
rrs = append(rrs, rr)
|
||||
return
|
||||
}
|
||||
|
||||
func txt_analyze(a *Analyzer) (err error) {
|
||||
for _, record := range a.SearchRR(AnalyzerRecordFilter{Type: dns.TypeTXT}) {
|
||||
// Skip DNSSEC record added by dnscontrol
|
||||
if strings.HasPrefix(record.Header().Name, "__dnssec.") {
|
||||
if strings.HasPrefix(record.Name, "__dnssec") {
|
||||
continue
|
||||
}
|
||||
|
||||
if txt, ok := record.(*dns.TXT); ok {
|
||||
if record.Type == "TXT" {
|
||||
err = a.UseRR(
|
||||
record,
|
||||
txt.Header().Name,
|
||||
&TXT{Content: strings.Join(txt.Txt, "")},
|
||||
record.NameFQDN,
|
||||
&TXT{Content: record.GetTargetTXTJoined()},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright or © or Copr. happyDNS (2023)
|
||||
//
|
||||
// contact@happydomain.org
|
||||
//
|
||||
// This software is a computer program whose purpose is to provide a modern
|
||||
// interface to interact with DNS systems.
|
||||
//
|
||||
// This software is governed by the CeCILL license under French law and abiding
|
||||
// by the rules of distribution of free software. You can use, modify and/or
|
||||
// redistribute the software under the terms of the CeCILL license as
|
||||
// circulated by CEA, CNRS and INRIA at the following URL
|
||||
// "http://www.cecill.info".
|
||||
//
|
||||
// As a counterpart to the access to the source code and rights to copy, modify
|
||||
// and redistribute granted by the license, users are provided only with a
|
||||
// limited warranty and the software's author, the holder of the economic
|
||||
// rights, and the successive licensors have only limited liability.
|
||||
//
|
||||
// In this respect, the user's attention is drawn to the risks associated with
|
||||
// loading, using, modifying and/or developing or reproducing the software by
|
||||
// the user in light of its specific status of free software, that may mean
|
||||
// that it is complicated to manipulate, and that also therefore means that it
|
||||
// is reserved for developers and experienced professionals having in-depth
|
||||
// computer knowledge. Users are therefore encouraged to load and test the
|
||||
// software's suitability as regards their requirements in conditions enabling
|
||||
// the security of their systems and/or data to be ensured and, more generally,
|
||||
// to use and operate it in the same conditions as regards security.
|
||||
//
|
||||
// The fact that you are presently reading this means that you have had
|
||||
// knowledge of the CeCILL license and that you accept its terms.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"git.happydns.org/happyDomain/model"
|
||||
"git.happydns.org/happyDomain/services"
|
||||
)
|
||||
|
||||
func migrateFrom4(s *LevelDBStorage) (err error) {
|
||||
err = migrateFrom4_orphanrecords(s)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = s.Tidy()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func migrateFrom4_orphanrecords(s *LevelDBStorage) (err error) {
|
||||
iter := s.search("domain.zone-")
|
||||
for iter.Next() {
|
||||
var tmpid string
|
||||
fmt.Sscanf(string(iter.Key()), "domain.zone-%s", &tmpid)
|
||||
|
||||
var id happydns.Identifier
|
||||
id, err = happydns.NewIdentifierFromString(tmpid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to determine identifier of %s: %w", iter.Key(), err)
|
||||
}
|
||||
|
||||
var zone *happydns.Zone
|
||||
zone, err = s.GetZone(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", iter.Key(), err)
|
||||
}
|
||||
|
||||
changed := false
|
||||
for _, zServices := range zone.Services {
|
||||
for _, svc := range zServices {
|
||||
if orphan, ok := svc.Service.(*svcs.Orphan); ok {
|
||||
tmp := strings.Fields(orphan.RR)
|
||||
|
||||
orphan.Type = tmp[0]
|
||||
orphan.RR = strings.TrimSpace(orphan.RR[len(tmp[0]):])
|
||||
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
err = s.UpdateZone(zone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to write %s: %w", iter.Key(), err)
|
||||
}
|
||||
log.Printf("Migrating v3 -> v4: %s (contains Orphan)...", iter.Key())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -43,6 +43,7 @@ var migrations []LevelDBMigrationFunc = []LevelDBMigrationFunc{
|
|||
migrateFrom1,
|
||||
migrateFrom2,
|
||||
migrateFrom3,
|
||||
migrateFrom4,
|
||||
}
|
||||
|
||||
func (s *LevelDBStorage) DoMigration() (err error) {
|
||||
|
|
13
utils/dns.go
13
utils/dns.go
|
@ -32,6 +32,9 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
|
@ -100,3 +103,13 @@ func DomainJoin(domains ...string) (ret string) {
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
// DomainJoin appends each relative domains passed as argument.
|
||||
func NewRecordConfig(domain string, rtype string, ttl uint32, origin string) *models.RecordConfig {
|
||||
return &models.RecordConfig{
|
||||
Name: strings.TrimSuffix(strings.TrimSuffix(DomainJoin(domain), origin), "."),
|
||||
NameFQDN: strings.TrimSuffix(DomainJoin(domain), "."),
|
||||
Type: rtype,
|
||||
TTL: ttl,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue