From b3d25a9a61d09db2fb6be8c623c2dc09b3b1321e Mon Sep 17 00:00:00 2001 From: Philipp Kern Date: Sun, 7 Feb 2016 00:09:43 +0100 Subject: [PATCH 1/2] Allow to specify the TSIG algorithm for RFC2136 DNS-01 authentication. Add a new environment variable RFC2136_TSIG_ALGORITHM that accepts the TSIG algorithm pseudo-domain name. Let it default to "hmac-md5.sig-alg.reg.int." if unset. --- acme/dns_challenge_rfc2136.go | 24 +++++++++++++++--------- acme/dns_challenge_rfc2136_test.go | 8 ++++---- cli_handlers.go | 3 ++- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/acme/dns_challenge_rfc2136.go b/acme/dns_challenge_rfc2136.go index e6f93fa4..35f983e9 100644 --- a/acme/dns_challenge_rfc2136.go +++ b/acme/dns_challenge_rfc2136.go @@ -2,30 +2,36 @@ package acme import ( "fmt" - "github.com/miekg/dns" "time" + + "github.com/miekg/dns" ) // DNSProviderRFC2136 is an implementation of the ChallengeProvider interface that // uses dynamic DNS updates (RFC 2136) to create TXT records on a nameserver. type DNSProviderRFC2136 struct { - nameserver string - zone string - tsigKey string - tsigSecret string - records map[string]string + nameserver string + zone string + tsigAlgorithm string + tsigKey string + tsigSecret string + records map[string]string } // NewDNSProviderRFC2136 returns a new DNSProviderRFC2136 instance. -// To disable TSIG authentication 'tsigKey' and 'tsigSecret' must be set to the empty string. +// To disable TSIG authentication 'tsigAlgorithm, 'tsigKey' and 'tsigSecret' must be set to the empty string. // 'nameserver' must be a network address in the the form "host:port". 'zone' must be the fully // qualified name of the zone. -func NewDNSProviderRFC2136(nameserver, zone, tsigKey, tsigSecret string) (*DNSProviderRFC2136, error) { +func NewDNSProviderRFC2136(nameserver, zone, tsigAlgorithm, tsigKey, tsigSecret string) (*DNSProviderRFC2136, error) { d := &DNSProviderRFC2136{ nameserver: nameserver, zone: zone, records: make(map[string]string), } + if tsigAlgorithm == "" { + tsigAlgorithm = dns.HmacMD5 + } + d.tsigAlgorithm = tsigAlgorithm if len(tsigKey) > 0 && len(tsigSecret) > 0 { d.tsigKey = tsigKey d.tsigSecret = tsigSecret @@ -73,7 +79,7 @@ func (r *DNSProviderRFC2136) changeRecord(action, fqdn, value string, ttl int) e c.SingleInflight = true // TSIG authentication / msg signing if len(r.tsigKey) > 0 && len(r.tsigSecret) > 0 { - m.SetTsig(dns.Fqdn(r.tsigKey), dns.HmacMD5, 300, time.Now().Unix()) + m.SetTsig(dns.Fqdn(r.tsigKey), r.tsigAlgorithm, 300, time.Now().Unix()) c.TsigSecret = map[string]string{dns.Fqdn(r.tsigKey): r.tsigSecret} } diff --git a/acme/dns_challenge_rfc2136_test.go b/acme/dns_challenge_rfc2136_test.go index f9fc5dea..9af8f491 100644 --- a/acme/dns_challenge_rfc2136_test.go +++ b/acme/dns_challenge_rfc2136_test.go @@ -57,7 +57,7 @@ func TestRFC2136ServerSuccess(t *testing.T) { } defer server.Shutdown() - provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "") + provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "", "") if err != nil { t.Fatalf("Expected NewDNSProviderRFC2136() to return no error but the error was -> %v", err) } @@ -76,7 +76,7 @@ func TestRFC2136ServerError(t *testing.T) { } defer server.Shutdown() - provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "") + provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "", "") if err != nil { t.Fatalf("Expected NewDNSProviderRFC2136() to return no error but the error was -> %v", err) } @@ -97,7 +97,7 @@ func TestRFC2136TsigClient(t *testing.T) { } defer server.Shutdown() - provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, rfc2136TestTsigKey, rfc2136TestTsigSecret) + provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", rfc2136TestTsigKey, rfc2136TestTsigSecret) if err != nil { t.Fatalf("Expected NewDNSProviderRFC2136() to return no error but the error was -> %v", err) } @@ -135,7 +135,7 @@ func TestRFC2136ValidUpdatePacket(t *testing.T) { t.Fatalf("Error packing expect msg: %v", err) } - provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "") + provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "", "") if err != nil { t.Fatalf("Expected NewDNSProviderRFC2136() to return no error but the error was -> %v", err) } diff --git a/cli_handlers.go b/cli_handlers.go index 2b5b3fc0..42e3fece 100644 --- a/cli_handlers.go +++ b/cli_handlers.go @@ -69,10 +69,11 @@ func setup(c *cli.Context) (*Configuration, *Account, *acme.Client) { case "rfc2136": nameserver := os.Getenv("RFC2136_NAMESERVER") zone := os.Getenv("RFC2136_ZONE") + tsigAlgorithm := os.Getenv("RFC2136_TSIG_ALGORITHM") tsigKey := os.Getenv("RFC2136_TSIG_KEY") tsigSecret := os.Getenv("RFC2136_TSIG_SECRET") - provider, err = acme.NewDNSProviderRFC2136(nameserver, zone, tsigKey, tsigSecret) + provider, err = acme.NewDNSProviderRFC2136(nameserver, zone, tsigAlgorithm, tsigKey, tsigSecret) case "manual": provider, err = acme.NewDNSProviderManual() } From f00f09f19cf226e33c68fb2b12d59b77f8f9d2fc Mon Sep 17 00:00:00 2001 From: Philipp Kern Date: Sun, 7 Feb 2016 00:12:48 +0100 Subject: [PATCH 2/2] Allow to specify RFC2136_NAMESERVER without the port. Append the default DNS port if the nameserver specification does not contain any. --- acme/dns_challenge_rfc2136.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acme/dns_challenge_rfc2136.go b/acme/dns_challenge_rfc2136.go index 35f983e9..e2954d25 100644 --- a/acme/dns_challenge_rfc2136.go +++ b/acme/dns_challenge_rfc2136.go @@ -2,6 +2,7 @@ package acme import ( "fmt" + "strings" "time" "github.com/miekg/dns" @@ -20,9 +21,13 @@ type DNSProviderRFC2136 struct { // NewDNSProviderRFC2136 returns a new DNSProviderRFC2136 instance. // To disable TSIG authentication 'tsigAlgorithm, 'tsigKey' and 'tsigSecret' must be set to the empty string. -// 'nameserver' must be a network address in the the form "host:port". 'zone' must be the fully +// 'nameserver' must be a network address in the the form "host" or "host:port". 'zone' must be the fully // qualified name of the zone. func NewDNSProviderRFC2136(nameserver, zone, tsigAlgorithm, tsigKey, tsigSecret string) (*DNSProviderRFC2136, error) { + // Append the default DNS port if none is specified. + if !strings.Contains(nameserver, ":") { + nameserver += ":53" + } d := &DNSProviderRFC2136{ nameserver: nameserver, zone: zone,