feat(rfc2136): add support for IPv6 address in nameserver
Signed-off-by: Johan Fleury <jfleury@arcaik.net>
This commit is contained in:
parent
51d46e5f76
commit
08db170a36
@ -326,7 +326,10 @@ spec:
|
||||
properties:
|
||||
nameserver:
|
||||
description: The IP address or hostname of an authoritative
|
||||
DNS server supporting RFC2136. Required.
|
||||
DNS server supporting RFC2136 in the form host:port. If
|
||||
the host is an IPv6 address it must be enclosed in square
|
||||
brackets (e.g [2001:db8::1]) ; port is optional. This
|
||||
field is required.
|
||||
type: string
|
||||
tsigAlgorithm:
|
||||
description: 'The TSIG Algorithm configured in the DNS supporting
|
||||
|
||||
@ -380,7 +380,10 @@ spec:
|
||||
properties:
|
||||
nameserver:
|
||||
description: The IP address or hostname of an authoritative
|
||||
DNS server supporting RFC2136. Required.
|
||||
DNS server supporting RFC2136 in the form host:port.
|
||||
If the host is an IPv6 address it must be enclosed
|
||||
in square brackets (e.g [2001:db8::1]) ; port is
|
||||
optional. This field is required.
|
||||
type: string
|
||||
tsigAlgorithm:
|
||||
description: 'The TSIG Algorithm configured in the
|
||||
|
||||
@ -380,7 +380,10 @@ spec:
|
||||
properties:
|
||||
nameserver:
|
||||
description: The IP address or hostname of an authoritative
|
||||
DNS server supporting RFC2136. Required.
|
||||
DNS server supporting RFC2136 in the form host:port.
|
||||
If the host is an IPv6 address it must be enclosed
|
||||
in square brackets (e.g [2001:db8::1]) ; port is
|
||||
optional. This field is required.
|
||||
type: string
|
||||
tsigAlgorithm:
|
||||
description: 'The TSIG Algorithm configured in the
|
||||
|
||||
@ -1081,7 +1081,10 @@ spec:
|
||||
properties:
|
||||
nameserver:
|
||||
description: The IP address or hostname of an authoritative
|
||||
DNS server supporting RFC2136. Required.
|
||||
DNS server supporting RFC2136 in the form host:port. If
|
||||
the host is an IPv6 address it must be enclosed in square
|
||||
brackets (e.g [2001:db8::1]) ; port is optional. This
|
||||
field is required.
|
||||
type: string
|
||||
tsigAlgorithm:
|
||||
description: 'The TSIG Algorithm configured in the DNS supporting
|
||||
@ -2542,7 +2545,10 @@ spec:
|
||||
properties:
|
||||
nameserver:
|
||||
description: The IP address or hostname of an authoritative
|
||||
DNS server supporting RFC2136. Required.
|
||||
DNS server supporting RFC2136 in the form host:port.
|
||||
If the host is an IPv6 address it must be enclosed
|
||||
in square brackets (e.g [2001:db8::1]) ; port is
|
||||
optional. This field is required.
|
||||
type: string
|
||||
tsigAlgorithm:
|
||||
description: 'The TSIG Algorithm configured in the
|
||||
@ -4295,7 +4301,10 @@ spec:
|
||||
properties:
|
||||
nameserver:
|
||||
description: The IP address or hostname of an authoritative
|
||||
DNS server supporting RFC2136. Required.
|
||||
DNS server supporting RFC2136 in the form host:port.
|
||||
If the host is an IPv6 address it must be enclosed
|
||||
in square brackets (e.g [2001:db8::1]) ; port is
|
||||
optional. This field is required.
|
||||
type: string
|
||||
tsigAlgorithm:
|
||||
description: 'The TSIG Algorithm configured in the
|
||||
|
||||
@ -355,7 +355,10 @@ type ACMEIssuerDNS01ProviderAcmeDNS struct {
|
||||
// ACMEIssuerDNS01ProviderRFC2136 is a structure containing the
|
||||
// configuration for RFC2136 DNS
|
||||
type ACMEIssuerDNS01ProviderRFC2136 struct {
|
||||
// The IP address or hostname of an authoritative DNS server supporting RFC2136. Required.
|
||||
// The IP address or hostname of an authoritative DNS server supporting
|
||||
// RFC2136 in the form host:port. If the host is an IPv6 address it must be
|
||||
// enclosed in square brackets (e.g [2001:db8::1]) ; port is optional.
|
||||
// This field is required.
|
||||
Nameserver string `json:"nameserver"`
|
||||
|
||||
// The name of the secret containing the TSIG value.
|
||||
|
||||
@ -355,7 +355,10 @@ type ACMEIssuerDNS01ProviderAcmeDNS struct {
|
||||
// ACMEIssuerDNS01ProviderRFC2136 is a structure containing the
|
||||
// configuration for RFC2136 DNS
|
||||
type ACMEIssuerDNS01ProviderRFC2136 struct {
|
||||
// The IP address or hostname of an authoritative DNS server supporting RFC2136. Required.
|
||||
// The IP address or hostname of an authoritative DNS server supporting
|
||||
// RFC2136 in the form host:port. If the host is an IPv6 address it must be
|
||||
// enclosed in square brackets (e.g [2001:db8::1]) ; port is optional.
|
||||
// This field is required.
|
||||
Nameserver string `json:"nameserver"`
|
||||
|
||||
// The name of the secret containing the TSIG value.
|
||||
|
||||
@ -314,7 +314,10 @@ type ACMEIssuerDNS01ProviderAcmeDNS struct {
|
||||
// ACMEIssuerDNS01ProviderRFC2136 is a structure containing the
|
||||
// configuration for RFC2136 DNS
|
||||
type ACMEIssuerDNS01ProviderRFC2136 struct {
|
||||
// The IP address or hostname of an authoritative DNS server supporting RFC2136. Required.
|
||||
// The IP address or hostname of an authoritative DNS server supporting
|
||||
// RFC2136 in the form host:port. If the host is an IPv6 address it must be
|
||||
// enclosed in square brackets (e.g [2001:db8::1]) ; port is optional.
|
||||
// This field is required.
|
||||
Nameserver string
|
||||
|
||||
// The name of the secret containing the TSIG value.
|
||||
|
||||
@ -348,7 +348,7 @@ func ValidateACMEChallengeSolverDNS01(p *cmacme.ACMEChallengeSolverDNS01, fldPat
|
||||
el = append(el, field.Required(fldPath.Child("rfc2136", "nameserver"), ""))
|
||||
} else {
|
||||
if _, err := util.ValidNameserver(p.RFC2136.Nameserver); err != nil {
|
||||
el = append(el, field.Invalid(fldPath.Child("rfc2136", "nameserver"), p.RFC2136.Nameserver, "nameserver must be an hostname or IP address in the form host[:port]."))
|
||||
el = append(el, field.Invalid(fldPath.Child("rfc2136", "nameserver"), p.RFC2136.Nameserver, "nameserver must be set in the form host:port where host is an IPv4 address, an enclosed IPv6 address or a hostname and port is an optional port number."))
|
||||
}
|
||||
}
|
||||
if len(p.RFC2136.TSIGAlgorithm) > 0 {
|
||||
|
||||
@ -656,6 +656,34 @@ func TestValidateACMEIssuerDNS01Config(t *testing.T) {
|
||||
},
|
||||
errs: []*field.Error{},
|
||||
},
|
||||
"rfc2136 provider with unenclosed IPv6 nameserver": {
|
||||
cfg: &cmacme.ACMEChallengeSolverDNS01{
|
||||
RFC2136: &cmacme.ACMEIssuerDNS01ProviderRFC2136{
|
||||
Nameserver: "2001:db8::1",
|
||||
},
|
||||
},
|
||||
errs: []*field.Error{
|
||||
field.Invalid(fldPath.Child("rfc2136", "nameserver"), "2001:db8::1", "nameserver must be set in the form host:port where host is an IPv4 address, an enclosed IPv6 address or a hostname and port is an optional port number."),
|
||||
},
|
||||
},
|
||||
"rfc2136 provider with empty IPv6 nameserver": {
|
||||
cfg: &cmacme.ACMEChallengeSolverDNS01{
|
||||
RFC2136: &cmacme.ACMEIssuerDNS01ProviderRFC2136{
|
||||
Nameserver: "[]:53",
|
||||
},
|
||||
},
|
||||
errs: []*field.Error{
|
||||
field.Invalid(fldPath.Child("rfc2136", "nameserver"), "[]:53", "nameserver must be set in the form host:port where host is an IPv4 address, an enclosed IPv6 address or a hostname and port is an optional port number."),
|
||||
},
|
||||
},
|
||||
"rfc2136 provider with IPv6 nameserver": {
|
||||
cfg: &cmacme.ACMEChallengeSolverDNS01{
|
||||
RFC2136: &cmacme.ACMEIssuerDNS01ProviderRFC2136{
|
||||
Nameserver: "[2001:db8::1]",
|
||||
},
|
||||
},
|
||||
errs: []*field.Error{},
|
||||
},
|
||||
"rfc2136 provider with FQDN nameserver": {
|
||||
cfg: &cmacme.ACMEChallengeSolverDNS01{
|
||||
RFC2136: &cmacme.ACMEIssuerDNS01ProviderRFC2136{
|
||||
@ -679,7 +707,7 @@ func TestValidateACMEIssuerDNS01Config(t *testing.T) {
|
||||
},
|
||||
},
|
||||
errs: []*field.Error{
|
||||
field.Invalid(fldPath.Child("rfc2136", "nameserver"), ":53", "nameserver must be an hostname or IP address in the form host[:port]."),
|
||||
field.Invalid(fldPath.Child("rfc2136", "nameserver"), ":53", "nameserver must be set in the form host:port where host is an IPv4 address, an enclosed IPv6 address or a hostname and port is an optional port number."),
|
||||
},
|
||||
},
|
||||
"rfc2136 provider using case-camel in algorithm": {
|
||||
|
||||
@ -37,6 +37,9 @@ func ValidNameserver(nameserver string) (string, error) {
|
||||
// 8.8.8.8 "" "" missing port in address
|
||||
// 8.8.8.8: "8.8.8.8" "" <nil>
|
||||
// 8.8.8.8.8:53 "8.8.8.8" 53 <nil>
|
||||
// [2001:db8::1] "" "" missing port in address
|
||||
// [2001:db8::1]: "2001:db8::1" "" <nil>
|
||||
// [2001:db8::1]:53 "2001:db8::1" 53 <nil>
|
||||
// nameserver.com "" "" missing port in address
|
||||
// nameserver.com: "nameserver.com" "" <nil>
|
||||
// nameserver.com:53 "nameserver.com" 53 <nil>
|
||||
@ -44,19 +47,20 @@ func ValidNameserver(nameserver string) (string, error) {
|
||||
host, port, err := net.SplitHostPort(nameserver)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
host = nameserver
|
||||
// net.JoinHostPort expect IPv6 address to be unenclosed
|
||||
host = strings.Trim(nameserver, "[]")
|
||||
} else {
|
||||
return "", fmt.Errorf("RFC2136 nameserver is invalid: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
port = defaultRFC2136Port
|
||||
}
|
||||
|
||||
if host == "" {
|
||||
return "", fmt.Errorf("RFC2136 nameserver has no host defined, %v", nameserver)
|
||||
}
|
||||
|
||||
nameserver = host + ":" + port
|
||||
if port == "" {
|
||||
port = defaultRFC2136Port
|
||||
}
|
||||
|
||||
return nameserver, nil
|
||||
return net.JoinHostPort(host, port), nil
|
||||
}
|
||||
|
||||
@ -181,6 +181,48 @@ func TestRFC2136NameserverIPv4WithPort(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRFC2136NameserverIPv6NotEnclosed(t *testing.T) {
|
||||
nameserver := "2001:db8::1"
|
||||
_, err := NewDNSProviderCredentials(nameserver, "", rfc2136TestTsigKeyName, rfc2136TestTsigSecret)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRFC2136NameserverIPv6Empty(t *testing.T) {
|
||||
nameserver := "[]:53"
|
||||
_, err := NewDNSProviderCredentials(nameserver, "", rfc2136TestTsigKeyName, rfc2136TestTsigSecret)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRFC2136NameserverIPv6WithoutPort(t *testing.T) {
|
||||
nameserver := "[2001:db8::1]"
|
||||
dnsProvider, err := NewDNSProviderCredentials(nameserver, "", rfc2136TestTsigKeyName, rfc2136TestTsigSecret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
if dnsProvider.nameserver != nameserver+":"+defaultPort {
|
||||
t.Errorf("dnsProvider.nameserver to be %v:%v, but it is %v", nameserver, defaultPort, dnsProvider.nameserver)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRFC2136NameserverIPv6WithEmptyPort(t *testing.T) {
|
||||
nameserver := "[2001:db8::1]:"
|
||||
dnsProvider, err := NewDNSProviderCredentials(nameserver, "", rfc2136TestTsigKeyName, rfc2136TestTsigSecret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
if dnsProvider.nameserver != nameserver+defaultPort {
|
||||
t.Errorf("dnsProvider.nameserver to be %v%v, but it is %v", nameserver, defaultPort, dnsProvider.nameserver)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRFC2136NameserverIPv6WithPort(t *testing.T) {
|
||||
nameserver := "[2001:db8::1]:12345"
|
||||
dnsProvider, err := NewDNSProviderCredentials(nameserver, "", rfc2136TestTsigKeyName, rfc2136TestTsigSecret)
|
||||
assert.NoError(t, err)
|
||||
|
||||
if dnsProvider.nameserver != nameserver {
|
||||
t.Errorf("dnsProvider.nameserver to be %v, but it is %v", nameserver, dnsProvider.nameserver)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRFC2136NameserverFQDNWithoutPort(t *testing.T) {
|
||||
nameserver := "dns.example.net"
|
||||
dnsProvider, err := NewDNSProviderCredentials(nameserver, "", rfc2136TestTsigKeyName, rfc2136TestTsigSecret)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user