Pull request 1922: AG-23889-upd-dnsproxy

Merge in DNS/adguard-home from AG-23889-upd-dnsproxy to master

Squashed commit of the following:

commit ec61d4824946d28bf898d023d3321753273b7df3
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jul 18 19:09:32 2023 +0300

    all: imp code

commit 271f1ca0e6e583c829519cb0b5b24ab070e08933
Merge: 684c5aedc dee7c0681
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jul 18 17:54:52 2023 +0300

    Merge branch 'master' into AG-23889-upd-dnsproxy

commit 684c5aedc7206578f89b80932999e714506d5ce0
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jul 18 16:51:17 2023 +0300

    dnsforward: save prev proxy behavior

commit 9032c2179b941bec6d43b3e6bafdca5125a462b4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jul 17 17:45:10 2023 +0500

    dnsforward: use proxy ua

commit f658c031957fe45243e66a589ed32294e9aa4e27
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jul 17 17:37:03 2023 +0500

    dnsforward: fix private rdns ups conf for dns64

commit 70080e347dbc32cbdcb7d757514da13f865f8381
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 13 16:56:34 2023 +0300

    all: upd dnsproxy
This commit is contained in:
Stanislav Chzhen 2023-07-18 20:02:01 +03:00 committed by Eugene Burkov
parent dee7c0681d
commit 33ce24abe4
6 changed files with 54 additions and 29 deletions

5
go.mod
View File

@ -3,8 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
go 1.19 go 1.19
require ( require (
// TODO(a.garipov): Update to a tagged version when it's released. github.com/AdguardTeam/dnsproxy v0.52.0
github.com/AdguardTeam/dnsproxy v0.50.3-0.20230628054307-31e374065768
github.com/AdguardTeam/golibs v0.13.4 github.com/AdguardTeam/golibs v0.13.4
github.com/AdguardTeam/urlfilter v0.16.1 github.com/AdguardTeam/urlfilter v0.16.1
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
@ -28,7 +27,7 @@ require (
// own code for that. Perhaps, use gopacket. // own code for that. Perhaps, use gopacket.
github.com/mdlayher/raw v0.1.0 github.com/mdlayher/raw v0.1.0
github.com/miekg/dns v1.1.55 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/stretchr/testify v1.8.4
github.com/ti-mo/netfilter v0.5.0 github.com/ti-mo/netfilter v0.5.0
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7

8
go.sum
View File

@ -1,5 +1,5 @@
github.com/AdguardTeam/dnsproxy v0.50.3-0.20230628054307-31e374065768 h1:5Ia6wA+tqAlTyzuaOVGSlHmb0osLWXeJUs3NxCuC4gA= github.com/AdguardTeam/dnsproxy v0.52.0 h1:uZxCXflHSAwtJ7uTYXP6qgWcxaBsH0pJvldpwTqIDJk=
github.com/AdguardTeam/dnsproxy v0.50.3-0.20230628054307-31e374065768/go.mod h1:CQhZTkqC8X0ID6glrtyaxgqRRdiYfn1gJulC1cZ5Dn8= 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.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw= github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.13.4 h1:ACTwIR1pEENBijHcEWtiMbSh4wWQOlIHRxmUB8oBHf8= 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-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 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= 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.36.1 h1:WsG73nVtnDy1TiACxFxhQ3TqaW+DipmqzLEtNlAwZyY=
github.com/quic-go/quic-go v0.35.1/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g= 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 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA=
github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= 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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

View File

@ -344,6 +344,7 @@ func (s *Server) createProxyConfig() (conf proxy.Config, err error) {
UpstreamConfig: srvConf.UpstreamConfig, UpstreamConfig: srvConf.UpstreamConfig,
BeforeRequestHandler: s.beforeRequestHandler, BeforeRequestHandler: s.beforeRequestHandler,
RequestHandler: s.handleDNSRequest, RequestHandler: s.handleDNSRequest,
HTTPSServerName: aghhttp.UserAgent(),
EnableEDNSClientSubnet: srvConf.EDNSClientSubnet.Enabled, EnableEDNSClientSubnet: srvConf.EDNSClientSubnet.Enabled,
MaxGoroutines: int(srvConf.MaxGoroutines), MaxGoroutines: int(srvConf.MaxGoroutines),
UseDNS64: srvConf.UseDNS64, UseDNS64: srvConf.UseDNS64,

View File

@ -100,12 +100,17 @@ type Server struct {
// must be a valid domain name plus dots on each side. // must be a valid domain name plus dots on each side.
localDomainSuffix string localDomainSuffix string
ipset ipsetCtx
privateNets netutil.SubnetSet
// addrProc, if not nil, is used to process clients' IP addresses with rDNS, // addrProc, if not nil, is used to process clients' IP addresses with rDNS,
// WHOIS, etc. // WHOIS, etc.
addrProc client.AddressProcessor addrProc client.AddressProcessor
ipset ipsetCtx // localResolvers is a DNS proxy instance used to resolve PTR records for
privateNets netutil.SubnetSet // addresses considered private as per the [privateNets].
//
// TODO(e.burkov): Remove once the local resolvers logic moved to dnsproxy.
localResolvers *proxy.Proxy localResolvers *proxy.Proxy
sysResolvers aghnet.SystemResolvers sysResolvers aghnet.SystemResolvers
@ -452,23 +457,27 @@ func (s *Server) filterOurDNSAddrs(addrs []string) (filtered []string, err error
return stringutil.FilterOut(addrs, ourAddrsSet.Has), nil return stringutil.FilterOut(addrs, ourAddrsSet.Has), nil
} }
// setupResolvers initializes the resolvers for local addresses. For internal // setupLocalResolvers initializes the resolvers for local addresses. For
// use only. // internal use only.
func (s *Server) setupResolvers(localAddrs []string) (err error) { func (s *Server) setupLocalResolvers() (err error) {
bootstraps := s.conf.BootstrapDNS bootstraps := s.conf.BootstrapDNS
if len(localAddrs) == 0 { resolvers := s.conf.LocalPTRResolvers
localAddrs = s.sysResolvers.Get()
if len(resolvers) == 0 {
resolvers = s.sysResolvers.Get()
bootstraps = nil bootstraps = nil
} else {
resolvers = stringutil.FilterOut(resolvers, IsCommentOrEmpty)
} }
localAddrs, err = s.filterOurDNSAddrs(localAddrs) resolvers, err = s.filterOurDNSAddrs(resolvers)
if err != nil { if err != nil {
return err 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, Bootstrap: bootstraps,
Timeout: defaultLocalTimeout, Timeout: defaultLocalTimeout,
// TODO(e.burkov): Should we verify server's certificates? // 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{ s.localResolvers = &proxy.Proxy{
Config: proxy.Config{ 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 return nil
} }
@ -534,20 +550,16 @@ func (s *Server) Prepare(conf *ServerConfig) (err error) {
return fmt.Errorf("preparing access: %w", err) 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. // 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 { if err != nil {
return fmt.Errorf("setting up resolvers: %w", err) 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() s.recDetector.clear()
if s.conf.AddrProcConf == nil { if s.conf.AddrProcConf == nil {
@ -568,6 +580,8 @@ func (s *Server) Prepare(conf *ServerConfig) (err error) {
c.InitialAddresses = nil c.InitialAddresses = nil
} }
s.registerHandlers()
return nil return nil
} }

View File

@ -719,6 +719,18 @@ func (s *Server) processLocalPTR(dctx *dnsContext) (rc resultCode) {
if s.conf.UsePrivateRDNS { if s.conf.UsePrivateRDNS {
s.recDetector.add(*pctx.Req) s.recDetector.add(*pctx.Req)
if err := s.localResolvers.Resolve(pctx); err != nil { 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 dctx.err = err
return resultCodeError return resultCodeError

View File

@ -15,7 +15,6 @@ import (
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil" "github.com/AdguardTeam/golibs/netutil"
"github.com/NYTimes/gziphandler" "github.com/NYTimes/gziphandler"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3" "github.com/quic-go/quic-go/http3"
"golang.org/x/net/http2" "golang.org/x/net/http2"
"golang.org/x/net/http2/h2c" "golang.org/x/net/http2/h2c"
@ -295,7 +294,7 @@ func (web *webAPI) mustStartHTTP3(address string) {
log.Debug("web: starting http/3 server") log.Debug("web: starting http/3 server")
err := web.httpsServer.server3.ListenAndServe() err := web.httpsServer.server3.ListenAndServe()
if !errors.Is(err, quic.ErrServerClosed) { if !errors.Is(err, http.ErrServerClosed) {
cleanupAlways() cleanupAlways()
log.Fatalf("web: http3: %s", err) log.Fatalf("web: http3: %s", err)
} }