DNS Server: IPv4: no mixing of dots and dashes

Long-ago behavior (PowerDNS):

minio-01.192-168-1-100.sslip.io → 192.168.1.100

More-recent behavior (Golang):

minio-01.192-168-1-100.sslip.io → 1.192.168.1

This behavior is counter-intuitive & wrong. We now restore the long-ago
behavior by being much more strict--no more mixing of dots and dashes!

Thanks @pandaxin!

[fixes #9]
This commit is contained in:
Brian Cunnie
2020-12-12 09:23:57 -08:00
parent b4e3005d84
commit 94c55db57b
2 changed files with 15 additions and 13 deletions

View File

@@ -37,10 +37,11 @@ type DomainCustomizations map[string]struct {
var (
// https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
ipv4RE = regexp.MustCompile(`(^|[.-])(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])[.-]){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))($|[.-])`)
ipv6RE = regexp.MustCompile(`(^|[.-])(([0-9a-fA-F]{1,4}-){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,7}-|([0-9a-fA-F]{1,4}-){1,6}-[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,5}(-[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}-){1,4}(-[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}-){1,3}(-[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}-){1,2}(-[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}-((-[0-9a-fA-F]{1,4}){1,6})|-((-[0-9a-fA-F]{1,4}){1,7}|-)|fe80-(-[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|--(ffff(-0{1,4}){0,1}-){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}-){1,4}-((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))($|[.-])`)
ErrNotFound = errors.New("record not found")
NameServers = []string{
ipv4REDots = regexp.MustCompile(`(^|[.-])(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))($|[.-])`)
ipv4REDashes = regexp.MustCompile(`(^|[.-])(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])-){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))($|[.-])`)
ipv6RE = regexp.MustCompile(`(^|[.-])(([0-9a-fA-F]{1,4}-){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,7}-|([0-9a-fA-F]{1,4}-){1,6}-[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,5}(-[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}-){1,4}(-[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}-){1,3}(-[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}-){1,2}(-[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}-((-[0-9a-fA-F]{1,4}){1,6})|-((-[0-9a-fA-F]{1,4}){1,7}|-)|fe80-(-[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|--(ffff(-0{1,4}){0,1}-){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}-){1,4}-((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))($|[.-])`)
ErrNotFound = errors.New("record not found")
NameServers = []string{
"ns-aws.nono.io.",
"ns-azure.nono.io.",
"ns-gce.nono.io.",
@@ -372,15 +373,15 @@ func NameToA(fqdnString string) (*dnsmessage.AResource, error) {
if domain, ok := Customizations[fqdnString]; ok && len(domain.A) > 0 {
return &domain.A[0], nil // TODO: handle multiple A records
}
if !ipv4RE.Match(fqdn) {
return &dnsmessage.AResource{}, ErrNotFound
for _, ipv4RE := range []*regexp.Regexp{ipv4REDots, ipv4REDashes} {
if ipv4RE.Match(fqdn) {
match := string(ipv4RE.FindSubmatch(fqdn)[2])
match = strings.Replace(match, "-", ".", -1)
ipv4address := net.ParseIP(match).To4()
return &dnsmessage.AResource{A: [4]byte{ipv4address[0], ipv4address[1], ipv4address[2], ipv4address[3]}}, nil
}
}
match := string(ipv4RE.FindSubmatch(fqdn)[2])
match = strings.Replace(match, "-", ".", -1)
ipv4address := net.ParseIP(match).To4()
return &dnsmessage.AResource{A: [4]byte{ipv4address[0], ipv4address[1], ipv4address[2], ipv4address[3]}}, nil
return &dnsmessage.AResource{}, ErrNotFound
}
// NameToAAAA NameToA returns either an AAAAResource that matched the hostname

View File

@@ -352,7 +352,7 @@ var _ = Describe("Xip", func() {
Entry("link-local with domain", "169-254-168-253-com", dnsmessage.AResource{A: [4]byte{169, 254, 168, 253}}),
Entry("IETF protocol assignments with domain and www", "www-192-0-0-1-com", dnsmessage.AResource{A: [4]byte{192, 0, 0, 1}}),
// dots-and-dashes, mix-and-matches
Entry("test-net address with dots-and-dashes", "www-192.0-2.3.example-me.com", dnsmessage.AResource{A: [4]byte{192, 0, 2, 3}}),
Entry("Pandaxin's paradox", "minio-01.192-168-1-100.sslip.io", dnsmessage.AResource{A: [4]byte{192, 168, 1, 100}}),
)
DescribeTable("when it does not match an IP address",
func(fqdn string) {
@@ -367,6 +367,7 @@ var _ = Describe("Xip", func() {
Entry("too big", "256.254.253.252"),
Entry("NS but no dot", "ns-aws.nono.io"),
Entry("NS + cruft at beginning", "p-ns-aws.nono.io"),
Entry("test-net address with dots-and-dashes mixed", "www-192.0-2.3.example-me.com"),
)
})