diff --git a/plugin/dnssec/README.md b/plugin/dnssec/README.md index bf560464d..372e9d971 100644 --- a/plugin/dnssec/README.md +++ b/plugin/dnssec/README.md @@ -47,10 +47,10 @@ If monitoring is enabled (via the *prometheus* directive) then the following met Sign responses for `example.org` with the key "Kexample.org.+013+45330.key". -~~~ -example.org:53 { +~~~ corefile +example.org { dnssec { - key file /etc/coredns/Kexample.org.+013+45330 + key file Kexample.org.+013+45330 } whoami } @@ -59,10 +59,10 @@ example.org:53 { Sign responses for a kubernetes zone with the key "Kcluster.local+013+45129.key". ~~~ -cluster.local:53 { - kubernetes cluster.local - dnssec cluster.local { - key file /etc/coredns/Kcluster.local+013+45129 +cluster.local { + kubernetes + dnssec { + key file Kcluster.local+013+45129 } } ~~~ @@ -70,17 +70,16 @@ cluster.local:53 { ## Bugs Multiple *dnssec* plugins inside one server stanza will silently overwrite earlier ones, here -`example.local` will overwrite the one for `cluster.local`. +`example.local` will overwrite the one for `cluster.org`. ~~~ -.:53 { +. { kubernetes cluster.local dnssec cluster.local { - key file /etc/coredns/cluster.local + key file Kcluster.local+013+45129 } - dnssec example.local { - key file /etc/coredns/example.local + dnssec example.org { + key file Kexample.org.+013+45330 } - whoami } ~~~ diff --git a/plugin/dnssec/dnskey.go b/plugin/dnssec/dnskey.go index 885538fbf..5c326d9a9 100644 --- a/plugin/dnssec/dnskey.go +++ b/plugin/dnssec/dnskey.go @@ -38,7 +38,10 @@ func ParseKeyFile(pubFile, privFile string) (*DNSKEY, error) { return nil, e } - dk := k.(*dns.DNSKEY) + dk, ok := k.(*dns.DNSKEY) + if !ok { + return nil, errors.New("no public key found") + } p, e := dk.ReadPrivateKey(f, privFile) if e != nil { return nil, e @@ -50,7 +53,7 @@ func ParseKeyFile(pubFile, privFile string) (*DNSKEY, error) { if s, ok := p.(*ecdsa.PrivateKey); ok { return &DNSKEY{K: dk, D: dk.ToDS(dns.SHA256), s: s, tag: dk.KeyTag()}, nil } - return &DNSKEY{K: dk, D: dk.ToDS(dns.SHA256), s: nil, tag: 0}, errors.New("no known private key found") + return &DNSKEY{K: dk, D: dk.ToDS(dns.SHA256), s: nil, tag: 0}, errors.New("no private key found") } // getDNSKEY returns the correct DNSKEY to the client. Signatures are added when do is true. diff --git a/plugin/file/README.md b/plugin/file/README.md index 3dfb319bb..50912ca9c 100644 --- a/plugin/file/README.md +++ b/plugin/file/README.md @@ -44,9 +44,22 @@ file DBFILE [ZONES... ] { Load the `example.org` zone from `example.org.signed` and allow transfers to the internet, but send notifies to 10.240.1.1 -~~~ -file example.org.signed example.org { - transfer to * - transfer to 10.240.1.1 +~~~ corefile +example.org { + file example.org.signed { + transfer to * + transfer to 10.240.1.1 + } +} +~~~ + +Or use a single zone file for multiple zones: + +~~~ +. { + file example.org.signed example.org example.net { + transfer to * + transfer to 10.240.1.1 + } } ~~~ diff --git a/test/readme_test.go b/test/readme_test.go index dcbb56619..f8ae0e346 100644 --- a/test/readme_test.go +++ b/test/readme_test.go @@ -14,7 +14,25 @@ import ( "github.com/mholt/caddy" ) -// TestReadme parses all README.md's of the plugins and checks if every example Corefile +// As we use the filesystem as-is, these files need to exist ON DISK for the readme test to work. This is especially +// useful for the *file* and *dnssec* plugins as their Corefiles are now tested as well. We create files in the +// current dir for all these, meaning the example READMEs MUST use relative path in their READMEs. +var contents = map[string]string{ + "Kexample.org.+013+45330.key": examplePub, + "Kexample.org.+013+45330.private": examplePriv, + "example.org.signed": exampleOrg, // not signed, but does not matter for this test. +} + +const ( + examplePub = `example.org. IN DNSKEY 256 3 13 eNMYFZYb6e0oJOV47IPo5f/UHy7wY9aBebotvcKakIYLyyGscBmXJQhbKLt/LhrMNDE2Q96hQnI5PdTBeOLzhQ== +` + examplePriv = `Private-key-format: v1.3 +Algorithm: 13 (ECDSAP256SHA256) +PrivateKey: f03VplaIEA+KHI9uizlemUSbUJH86hPBPjmcUninPoM= +` +) + +// TestReadme parses all README.mds of the plugins and checks if every example Corefile // actually works. Each corefile snippet is only used if the language is set to 'corefile': // // ~~~ corefile @@ -27,6 +45,9 @@ func TestReadme(t *testing.T) { caddy.Quiet = true dnsserver.Quiet = true + create(contents) + defer remove(contents) + log.SetOutput(ioutil.Discard) middle := filepath.Join("..", "plugin") @@ -99,3 +120,15 @@ func corefileFromReadme(readme string) ([]*Input, error) { } return input, nil } + +func create(c map[string]string) { + for name, content := range c { + ioutil.WriteFile(name, []byte(content), 0644) + } +} + +func remove(c map[string]string) { + for name := range c { + os.Remove(name) + } +}