diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c05663..5529e708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,12 +25,17 @@ NOTE: Add new changes BELOW THIS COMMENT. ### Fixed +- Requirements to domain names in domain-specific upstream configurations have + been relaxed to meet those from [RFC 3696][rfc3696] ([#4884]). - Panic when using unencrypted DNS-over-HTTPS ([#5518]). - Failing service installation via script on FreeBSD ([#5431]). +[#4884]: https://github.com/AdguardTeam/AdGuardHome/issues/4884 [#5518]: https://github.com/AdguardTeam/AdGuardHome/issues/5518 [#5431]: https://github.com/AdguardTeam/AdGuardHome/issues/5431 +[rfc3696]: https://datatracker.ietf.org/doc/html/rfc3696 + diff --git a/go.mod b/go.mod index 2d54d4c4..6c2f1dad 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.19 require ( // TODO(a.garipov): Use v0.48.0 when it's released. - github.com/AdguardTeam/dnsproxy v0.47.1-0.20230207130636-533058b17239 - github.com/AdguardTeam/golibs v0.11.4 + github.com/AdguardTeam/dnsproxy v0.48.0 + github.com/AdguardTeam/golibs v0.12.0 github.com/AdguardTeam/urlfilter v0.16.1 github.com/NYTimes/gziphandler v1.1.1 github.com/ameshkov/dnscrypt/v2 v2.2.5 diff --git a/go.sum b/go.sum index 68a4b1ab..346caa8d 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -github.com/AdguardTeam/dnsproxy v0.47.1-0.20230207130636-533058b17239 h1:n1oOiywOvdeqWLto809bK1rK1EPDkpaSfT/r1OiCVaQ= -github.com/AdguardTeam/dnsproxy v0.47.1-0.20230207130636-533058b17239/go.mod h1:+Sdi5ISrjDFbeCsKNqzcC1Ag7pJ5Hh9y+UBNb3dfqJ4= +github.com/AdguardTeam/dnsproxy v0.48.0 h1:sGViYy2pV0cEp2zCsxPjFd9rlgD0+yELpIeLkBxHAoI= +github.com/AdguardTeam/dnsproxy v0.48.0/go.mod h1:9OHoeaVod+moWwrLjHF95RQnFWGi/6B1tfKsxWc/yGE= github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw= -github.com/AdguardTeam/golibs v0.11.4 h1:IltyvxwCTN+xxJF5sh6VadF8Zfbf8elgCm9dgijSVzM= -github.com/AdguardTeam/golibs v0.11.4/go.mod h1:87bN2x4VsTritptE3XZg9l8T6gznWsIxHBcQ1DeRIXA= +github.com/AdguardTeam/golibs v0.12.0 h1:z4Q3Mz0pHJ2Zag4B0RBaIXEUue1TPOKkbRiYkwC4r7I= +github.com/AdguardTeam/golibs v0.12.0/go.mod h1:87bN2x4VsTritptE3XZg9l8T6gznWsIxHBcQ1DeRIXA= github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU= github.com/AdguardTeam/urlfilter v0.16.1 h1:ZPi0rjqo8cQf2FVdzo6cqumNoHZx2KPXj2yZa1A5BBw= github.com/AdguardTeam/urlfilter v0.16.1/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI= diff --git a/internal/aghnet/arpdb_bsd.go b/internal/aghnet/arpdb_bsd.go index c4048939..50287785 100644 --- a/internal/aghnet/arpdb_bsd.go +++ b/internal/aghnet/arpdb_bsd.go @@ -67,7 +67,7 @@ func parseArpA(sc *bufio.Scanner, lenHint int) (ns []Neighbor) { } host := fields[0] - err = netutil.ValidateDomainName(host) + err = netutil.ValidateHostname(host) if err != nil { log.Debug("arpdb: parsing arp output: host: %s", err) } else { diff --git a/internal/aghnet/arpdb_linux.go b/internal/aghnet/arpdb_linux.go index e6e51feb..d3ebe4a7 100644 --- a/internal/aghnet/arpdb_linux.go +++ b/internal/aghnet/arpdb_linux.go @@ -198,7 +198,7 @@ func parseArpA(sc *bufio.Scanner, lenHint int) (ns []Neighbor) { } host := fields[0] - if verr := netutil.ValidateDomainName(host); verr != nil { + if verr := netutil.ValidateHostname(host); verr != nil { log.Debug("arpdb: parsing arp output: host: %s", verr) } else { n.Name = host diff --git a/internal/aghnet/hostscontainer.go b/internal/aghnet/hostscontainer.go index 62886730..c53f9d7c 100644 --- a/internal/aghnet/hostscontainer.go +++ b/internal/aghnet/hostscontainer.go @@ -343,7 +343,7 @@ func (hp *hostsParser) parseLine(line string) (ip netip.Addr, hosts []string) { // See https://github.com/AdguardTeam/AdGuardHome/issues/3946. // // TODO(e.burkov): Investigate if hosts may contain DNS-SD domains. - err = netutil.ValidateDomainName(f) + err = netutil.ValidateHostname(f) if err != nil { log.Error("%s: host %q is invalid, ignoring", hostsContainerPref, f) diff --git a/internal/dhcpd/v4_unix.go b/internal/dhcpd/v4_unix.go index d83e0125..64ebf25d 100644 --- a/internal/dhcpd/v4_unix.go +++ b/internal/dhcpd/v4_unix.go @@ -108,7 +108,7 @@ func (s *v4Server) validHostnameForClient(cliHostname string, ip net.IP) (hostna hostname = aghnet.GenerateHostname(ip) } - err = netutil.ValidateDomainName(hostname) + err = netutil.ValidateHostname(hostname) if err != nil { log.Info("dhcpv4: %s", err) hostname = "" @@ -372,7 +372,7 @@ func (s *v4Server) AddStaticLease(l *Lease) (err error) { return err } - err = netutil.ValidateDomainName(hostname) + err = netutil.ValidateHostname(hostname) if err != nil { return fmt.Errorf("validating hostname: %w", err) } diff --git a/internal/dhcpd/v4_unix_test.go b/internal/dhcpd/v4_unix_test.go index 411e36d9..8c1255e1 100644 --- a/internal/dhcpd/v4_unix_test.go +++ b/internal/dhcpd/v4_unix_test.go @@ -251,8 +251,8 @@ func TestV4Server_AddRemove_static(t *testing.T) { }, name: "bad_hostname", wantErrMsg: `dhcpv4: adding static lease: validating hostname: ` + - `bad domain name "bad-lbl-.local": ` + - `bad domain name label "bad-lbl-": bad domain name label rune '-'`, + `bad hostname "bad-lbl-.local": ` + + `bad hostname label "bad-lbl-": bad hostname label rune '-'`, }} for _, tc := range testCases { diff --git a/internal/dnsforward/clientid.go b/internal/dnsforward/clientid.go index b48d4a4c..a7f2902a 100644 --- a/internal/dnsforward/clientid.go +++ b/internal/dnsforward/clientid.go @@ -14,7 +14,7 @@ import ( // ValidateClientID returns an error if id is not a valid ClientID. func ValidateClientID(id string) (err error) { - err = netutil.ValidateDomainNameLabel(id) + err = netutil.ValidateHostnameLabel(id) if err != nil { // Replace the domain name label wrapper with our own. return fmt.Errorf("invalid clientid %q: %w", id, errors.Unwrap(err)) diff --git a/internal/dnsforward/clientid_test.go b/internal/dnsforward/clientid_test.go index 458b66d3..5391ddc0 100644 --- a/internal/dnsforward/clientid_test.go +++ b/internal/dnsforward/clientid_test.go @@ -119,7 +119,7 @@ func TestServer_clientIDFromDNSContext(t *testing.T) { cliSrvName: "!!!.example.com", wantClientID: "", wantErrMsg: `clientid check: invalid clientid "!!!": ` + - `bad domain name label rune '!'`, + `bad hostname label rune '!'`, inclHTTPTLS: false, strictSNI: true, }, { @@ -131,7 +131,7 @@ func TestServer_clientIDFromDNSContext(t *testing.T) { wantClientID: "", wantErrMsg: `clientid check: invalid clientid "abcdefghijklmno` + `pqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789": ` + - `domain name label is too long: got 72, max 63`, + `hostname label is too long: got 72, max 63`, inclHTTPTLS: false, strictSNI: true, }, { @@ -330,7 +330,7 @@ func TestClientIDFromDNSContextHTTPS(t *testing.T) { path: "/dns-query/!!!", cliSrvName: "example.com", wantClientID: "", - wantErrMsg: `clientid check: invalid clientid "!!!": bad domain name label rune '!'`, + wantErrMsg: `clientid check: invalid clientid "!!!": bad hostname label rune '!'`, }, { name: "both_ids", path: "/dns-query/right", diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index 9e8eb7df..eeeb4c40 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -540,7 +540,8 @@ func matchesDomainWildcard(host, pat string) (ok bool) { // anyNameMatches returns true if sni, the client's SNI value, matches any of // the DNS names and patterns from certificate. dnsNames must be sorted. func anyNameMatches(dnsNames []string, sni string) (ok bool) { - if netutil.ValidateDomainName(sni) != nil { + // Check sni is either a valid hostname or a valid IP address. + if netutil.ValidateHostname(sni) != nil && net.ParseIP(sni) == nil { return false } diff --git a/internal/dnsforward/config_test.go b/internal/dnsforward/config_test.go index 007a7fee..a13a567b 100644 --- a/internal/dnsforward/config_test.go +++ b/internal/dnsforward/config_test.go @@ -31,6 +31,10 @@ func TestAnyNameMatches(t *testing.T) { name: "match", dnsName: "1.2.3.4", want: true, + }, { + name: "mismatch_bad_ip", + dnsName: "1.2.3.256", + want: false, }, { name: "mismatch", dnsName: "host2", diff --git a/internal/dnsforward/dns.go b/internal/dnsforward/dns.go index 8d924f3b..9289eb45 100644 --- a/internal/dnsforward/dns.go +++ b/internal/dnsforward/dns.go @@ -230,7 +230,7 @@ func (s *Server) onDHCPLeaseChanged(flags int) { for _, l := range ll { // TODO(a.garipov): Remove this after we're finished with the client // hostname validations in the DHCP server code. - err := netutil.ValidateDomainName(l.Hostname) + err := netutil.ValidateHostname(l.Hostname) if err != nil { log.Debug("dnsforward: skipping invalid hostname %q from dhcp: %s", l.Hostname, err) @@ -468,7 +468,7 @@ func (s *Server) processRestrictLocal(dctx *dnsContext) (rc resultCode) { return resultCodeError } - log.Debug("dnsforward: request is for a service domain") + log.Debug("dnsforward: request is not for arpa domain") return resultCodeSuccess } diff --git a/internal/dnsforward/dnsforward_test.go b/internal/dnsforward/dnsforward_test.go index a95b03df..6d928422 100644 --- a/internal/dnsforward/dnsforward_test.go +++ b/internal/dnsforward/dnsforward_test.go @@ -1171,7 +1171,8 @@ func TestNewServer(t *testing.T) { LocalDomain: "!!!", }, wantErrMsg: `local domain: bad domain name "!!!": ` + - `bad domain name label "!!!": bad domain name label rune '!'`, + `bad top-level domain name label "!!!": ` + + `bad top-level domain name label rune '!'`, }} for _, tc := range testCases { diff --git a/internal/dnsforward/http_test.go b/internal/dnsforward/http_test.go index 5e0b8018..db3356dc 100644 --- a/internal/dnsforward/http_test.go +++ b/internal/dnsforward/http_test.go @@ -337,7 +337,8 @@ func TestValidateUpstreams(t *testing.T) { }, { name: "bad_domain", wantErr: `bad upstream for domain "[/!/]8.8.8.8": domain at index 0: ` + - `bad domain name "!": bad domain name label "!": bad domain name label rune '!'`, + `bad domain name "!": bad top-level domain name label "!": ` + + `bad top-level domain name label rune '!'`, set: []string{"[/!/]8.8.8.8"}, }}