diff --git a/go.mod b/go.mod index de8b2ad7..60cada3e 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,7 @@ module github.com/AdguardTeam/AdGuardHome go 1.19 require ( - // TODO(a.garipov): Update to a tagged version when it's released. - github.com/AdguardTeam/dnsproxy v0.50.3-0.20230628054307-31e374065768 + github.com/AdguardTeam/dnsproxy v0.52.0 github.com/AdguardTeam/golibs v0.13.4 github.com/AdguardTeam/urlfilter v0.16.1 github.com/NYTimes/gziphandler v1.1.1 @@ -28,7 +27,7 @@ require ( // own code for that. Perhaps, use gopacket. github.com/mdlayher/raw v0.1.0 github.com/miekg/dns v1.1.55 - github.com/quic-go/quic-go v0.35.1 + github.com/quic-go/quic-go v0.36.1 github.com/stretchr/testify v1.8.4 github.com/ti-mo/netfilter v0.5.0 go.etcd.io/bbolt v1.3.7 diff --git a/go.sum b/go.sum index 196b7903..13431f68 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/AdguardTeam/dnsproxy v0.50.3-0.20230628054307-31e374065768 h1:5Ia6wA+tqAlTyzuaOVGSlHmb0osLWXeJUs3NxCuC4gA= -github.com/AdguardTeam/dnsproxy v0.50.3-0.20230628054307-31e374065768/go.mod h1:CQhZTkqC8X0ID6glrtyaxgqRRdiYfn1gJulC1cZ5Dn8= +github.com/AdguardTeam/dnsproxy v0.52.0 h1:uZxCXflHSAwtJ7uTYXP6qgWcxaBsH0pJvldpwTqIDJk= +github.com/AdguardTeam/dnsproxy v0.52.0/go.mod h1:Jo2zeRe97Rxt3yikXc+fn0LdLtqCj0Xlyh1PNBj6bpM= 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.13.4 h1:ACTwIR1pEENBijHcEWtiMbSh4wWQOlIHRxmUB8oBHf8= @@ -108,8 +108,8 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc8 github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.35.1 h1:b0kzj6b/cQAf05cT0CkQubHM31wiA+xH3IBkxP62poo= -github.com/quic-go/quic-go v0.35.1/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= +github.com/quic-go/quic-go v0.36.1 h1:WsG73nVtnDy1TiACxFxhQ3TqaW+DipmqzLEtNlAwZyY= +github.com/quic-go/quic-go v0.36.1/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA= github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index 20bc9770..ffd51a78 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -344,6 +344,7 @@ func (s *Server) createProxyConfig() (conf proxy.Config, err error) { UpstreamConfig: srvConf.UpstreamConfig, BeforeRequestHandler: s.beforeRequestHandler, RequestHandler: s.handleDNSRequest, + HTTPSServerName: aghhttp.UserAgent(), EnableEDNSClientSubnet: srvConf.EDNSClientSubnet.Enabled, MaxGoroutines: int(srvConf.MaxGoroutines), UseDNS64: srvConf.UseDNS64, diff --git a/internal/dnsforward/dnsforward.go b/internal/dnsforward/dnsforward.go index bb389969..9cf979e5 100644 --- a/internal/dnsforward/dnsforward.go +++ b/internal/dnsforward/dnsforward.go @@ -100,12 +100,17 @@ type Server struct { // must be a valid domain name plus dots on each side. localDomainSuffix string + ipset ipsetCtx + privateNets netutil.SubnetSet + // addrProc, if not nil, is used to process clients' IP addresses with rDNS, // WHOIS, etc. addrProc client.AddressProcessor - ipset ipsetCtx - privateNets netutil.SubnetSet + // localResolvers is a DNS proxy instance used to resolve PTR records for + // addresses considered private as per the [privateNets]. + // + // TODO(e.burkov): Remove once the local resolvers logic moved to dnsproxy. localResolvers *proxy.Proxy sysResolvers aghnet.SystemResolvers @@ -452,23 +457,27 @@ func (s *Server) filterOurDNSAddrs(addrs []string) (filtered []string, err error return stringutil.FilterOut(addrs, ourAddrsSet.Has), nil } -// setupResolvers initializes the resolvers for local addresses. For internal -// use only. -func (s *Server) setupResolvers(localAddrs []string) (err error) { +// setupLocalResolvers initializes the resolvers for local addresses. For +// internal use only. +func (s *Server) setupLocalResolvers() (err error) { bootstraps := s.conf.BootstrapDNS - if len(localAddrs) == 0 { - localAddrs = s.sysResolvers.Get() + resolvers := s.conf.LocalPTRResolvers + + if len(resolvers) == 0 { + resolvers = s.sysResolvers.Get() bootstraps = nil + } else { + resolvers = stringutil.FilterOut(resolvers, IsCommentOrEmpty) } - localAddrs, err = s.filterOurDNSAddrs(localAddrs) + resolvers, err = s.filterOurDNSAddrs(resolvers) if err != nil { return err } - log.Debug("dnsforward: upstreams to resolve ptr for local addresses: %v", localAddrs) + log.Debug("dnsforward: upstreams to resolve ptr for local addresses: %v", resolvers) - upsConfig, err := s.prepareUpstreamConfig(localAddrs, nil, &upstream.Options{ + uc, err := s.prepareUpstreamConfig(resolvers, nil, &upstream.Options{ Bootstrap: bootstraps, Timeout: defaultLocalTimeout, // TODO(e.burkov): Should we verify server's certificates? @@ -481,10 +490,17 @@ func (s *Server) setupResolvers(localAddrs []string) (err error) { s.localResolvers = &proxy.Proxy{ Config: proxy.Config{ - UpstreamConfig: upsConfig, + UpstreamConfig: uc, }, } + if s.conf.UsePrivateRDNS && + // Only set the upstream config if there are any upstreams. It's safe + // to put nil into [proxy.Config.PrivateRDNSUpstreamConfig]. + len(uc.Upstreams)+len(uc.DomainReservedUpstreams)+len(uc.SpecifiedDomainUpstreams) > 0 { + s.dnsProxy.PrivateRDNSUpstreamConfig = uc + } + return nil } @@ -534,20 +550,16 @@ func (s *Server) Prepare(conf *ServerConfig) (err error) { return fmt.Errorf("preparing access: %w", err) } - s.registerHandlers() - + // Set the proxy here because [setupLocalResolvers] sets its values. + // // TODO(e.burkov): Remove once the local resolvers logic moved to dnsproxy. - err = s.setupResolvers(s.conf.LocalPTRResolvers) + s.dnsProxy = &proxy.Proxy{Config: proxyConfig} + + err = s.setupLocalResolvers() if err != nil { return fmt.Errorf("setting up resolvers: %w", err) } - if s.conf.UsePrivateRDNS { - proxyConfig.PrivateRDNSUpstreamConfig = s.localResolvers.UpstreamConfig - } - - s.dnsProxy = &proxy.Proxy{Config: proxyConfig} - s.recDetector.clear() if s.conf.AddrProcConf == nil { @@ -568,6 +580,8 @@ func (s *Server) Prepare(conf *ServerConfig) (err error) { c.InitialAddresses = nil } + s.registerHandlers() + return nil } diff --git a/internal/dnsforward/process.go b/internal/dnsforward/process.go index e6949ec1..60feb968 100644 --- a/internal/dnsforward/process.go +++ b/internal/dnsforward/process.go @@ -719,6 +719,18 @@ func (s *Server) processLocalPTR(dctx *dnsContext) (rc resultCode) { if s.conf.UsePrivateRDNS { s.recDetector.add(*pctx.Req) if err := s.localResolvers.Resolve(pctx); err != nil { + // Generate the server failure if the private upstream configuration + // is empty. + // + // TODO(e.burkov): Get rid of this crutch once the local resolvers + // logic is moved to the dnsproxy completely. + if errors.Is(err, upstream.ErrNoUpstreams) { + pctx.Res = s.genServerFailure(pctx.Req) + + // Do not even put into query log. + return resultCodeFinish + } + dctx.err = err return resultCodeError diff --git a/internal/home/web.go b/internal/home/web.go index d53c946b..dd6386de 100644 --- a/internal/home/web.go +++ b/internal/home/web.go @@ -15,7 +15,6 @@ import ( "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/netutil" "github.com/NYTimes/gziphandler" - "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/http3" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" @@ -295,7 +294,7 @@ func (web *webAPI) mustStartHTTP3(address string) { log.Debug("web: starting http/3 server") err := web.httpsServer.server3.ListenAndServe() - if !errors.Is(err, quic.ErrServerClosed) { + if !errors.Is(err, http.ErrServerClosed) { cleanupAlways() log.Fatalf("web: http3: %s", err) }