diff --git a/go.mod b/go.mod index de05a226a..5f12342cd 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/hexonet/go-sdk v2.2.3+incompatible github.com/jarcoal/httpmock v1.0.4 // indirect github.com/miekg/dns v1.1.31 - github.com/mittwald/go-powerdns v0.4.0 + github.com/mittwald/go-powerdns v0.5.2 github.com/mjibson/esc v0.2.0 github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 github.com/nrdcg/goinwx v0.8.1 diff --git a/go.sum b/go.sum index 7d2d873da..5a7481351 100644 --- a/go.sum +++ b/go.sum @@ -279,6 +279,8 @@ github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mittwald/go-powerdns v0.4.0 h1:vEl2+4JINusy5NF8weObVRCuvHv8wqNBVMPZSQWq9zo= github.com/mittwald/go-powerdns v0.4.0/go.mod h1:bI/sZBAWyTViDknOTp19VfDxVEnh1U7rWPx2aRKtlzg= +github.com/mittwald/go-powerdns v0.5.2 h1:kfqr9ZNIuxOjjBaoJcOFiy/19VmKEUgfJPmObDglPJU= +github.com/mittwald/go-powerdns v0.5.2/go.mod h1:bI/sZBAWyTViDknOTp19VfDxVEnh1U7rWPx2aRKtlzg= github.com/mjibson/esc v0.2.0 h1:k96hdaR9Z+nMcnDwNrOvhdBqtjyMrbVyxLpsRCdP2mA= github.com/mjibson/esc v0.2.0/go.mod h1:9Hw9gxxfHulMF5OJKCyhYD7PzlSdhzXyaGEBRPH1OPs= github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g= diff --git a/providers/powerdns/dnssec.go b/providers/powerdns/dnssec.go new file mode 100644 index 000000000..bd1a41874 --- /dev/null +++ b/providers/powerdns/dnssec.go @@ -0,0 +1,74 @@ +package powerdns + +import ( + "context" + "github.com/StackExchange/dnscontrol/v3/models" + "github.com/mittwald/go-powerdns/apis/cryptokeys" +) + +// getDNSSECCorrections returns corrections that update a domain's DNSSEC state. +func (api *PowerDNS) getDNSSECCorrections(dc *models.DomainConfig) ([]*models.Correction, error) { + cryptokeys, getErr := api.client.Cryptokeys().ListCryptokeys(context.Background(), api.ServerName, dc.Name) + if getErr != nil { + return nil, getErr + } + + // check if any of the avail. key is active and published + hasEnabledKey := false + var keyID int + + if len(cryptokeys) > 0 { + for _, cryptoKey := range cryptokeys { + if cryptoKey.Active && cryptoKey.Published { + hasEnabledKey = true + keyID = cryptoKey.ID + break + } + } + } + + // dnssec is enabled, we want it to be disabled + if hasEnabledKey && !dc.AutoDNSSEC { + return []*models.Correction{ + { + Msg: "Disable DNSSEC", + F: func() error { _, err := api.removeDnssec(dc.Name, keyID); return err }, + }, + }, nil + } + + // dnssec is disabled, we want it to be enabled + if !hasEnabledKey && dc.AutoDNSSEC { + return []*models.Correction{ + { + Msg: "Enable DNSSEC", + F: func() error { _, err := api.enableDnssec(dc.Name); return err }, + }, + }, nil + } + + return nil, nil +} + +// enableDnssec creates a active and published cryptokey on this domain +func (api *PowerDNS) enableDnssec(domain string) (bool, error) { + // if there is now key, create one and enable it + _, err := api.client.Cryptokeys().CreateCryptokey(context.Background(), api.ServerName, domain, cryptokeys.Cryptokey{ + KeyType: "csk", + Active: true, + Published: true, + }) + if err != nil { + return false, err + } + return true, nil +} + +// removeDnssec removes the cryptokey from this zone +func (api *PowerDNS) removeDnssec(domain string, keyID int) (bool, error) { + err := api.client.Cryptokeys().DeleteCryptokey(context.Background(), api.ServerName, domain, keyID) + if err != nil { + return false, err + } + return true, nil +} diff --git a/providers/powerdns/powerdnsProvider.go b/providers/powerdns/powerdnsProvider.go index 1072cb847..e4f56943a 100644 --- a/providers/powerdns/powerdnsProvider.go +++ b/providers/powerdns/powerdnsProvider.go @@ -24,7 +24,7 @@ var features = providers.DocumentationNotes{ providers.CanUseSRV: providers.Can(), providers.CanUseTLSA: providers.Can(), providers.CanUseSSHFP: providers.Can(), - providers.CanAutoDNSSEC: providers.Unimplemented("Need support in library first"), + providers.CanAutoDNSSEC: providers.Can(), providers.DocCreateDomains: providers.Can(), providers.DocOfficiallySupported: providers.Cannot(), providers.CanGetZones: providers.Can(), @@ -195,7 +195,11 @@ func (api *PowerDNS) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Co } // DNSSec corrections - // TODO: Implementing of on-demand DNSSec creation in library + dnssecCorrections, err := api.getDNSSECCorrections(dc) + if err != nil { + return nil, err + } + corrections = append(corrections, dnssecCorrections...) return corrections, nil }