Pull request 2018: 6231 filter local addrs
Merge in DNS/adguard-home from 6231-filter-local-addrs to master Updates #6231. Squashed commit of the following: commit 9a60d4e33f25c7dd7eaa4366d8397389196156ac Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Sep 28 18:59:51 2023 +0300 dnsforward: imp code commit f0c3452525c227b0ee6e761c4a6b68543900d5b5 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Wed Sep 27 18:12:47 2023 +0300 all: don't match nets commit 572dc0f24e74560adaa4d89ddc921dfd7e1fed02 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Wed Sep 27 13:37:48 2023 +0300 dnsforward: move some code, rm dups commit 3af627ce9c7f6f4d2aa695a7660b8a0027fa241c Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Sep 25 19:21:05 2023 +0300 dnsforward: imp naming commit cad1e4e71662836d1dfc79bc2979599b7a29fea1 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Sep 25 19:17:53 2023 +0300 dnsforward: imp code commit 23d69700789d5652bd25cc089f16afb8b38e51f8 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Sep 25 19:08:48 2023 +0300 dnsforward: add upstream matcher commit 5819c594a2a8d8bf2cd42883133e21ca7ed2681a Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Fri Sep 22 18:31:37 2023 +0300 all: imp code, docs commit d07ea96bb568161e029e22d69329a368d9eeb729 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Fri Sep 22 18:09:09 2023 +0300 all: imp code commit 38a912a62c63247c4c5bb61b67ccc9bfd255feff Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Fri Sep 22 15:48:25 2023 +0300 all: imp code commit 811212fa16bc231a8da990c075d7231c471c7e3b Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Sep 21 19:05:07 2023 +0300 all: imp addrs detection
This commit is contained in:
@@ -12,10 +12,12 @@ import (
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghtls"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/client"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
@@ -392,6 +394,124 @@ func (s *Server) prepareIpsetListSettings() (err error) {
|
||||
return s.ipset.init(ipsets)
|
||||
}
|
||||
|
||||
// collectListenAddr adds addrPort to addrs. It also adds its port to
|
||||
// unspecPorts if its address is unspecified.
|
||||
func collectListenAddr(
|
||||
addrPort netip.AddrPort,
|
||||
addrs map[netip.AddrPort]unit,
|
||||
unspecPorts map[uint16]unit,
|
||||
) {
|
||||
if addrPort == (netip.AddrPort{}) {
|
||||
return
|
||||
}
|
||||
|
||||
addrs[addrPort] = unit{}
|
||||
if addrPort.Addr().IsUnspecified() {
|
||||
unspecPorts[addrPort.Port()] = unit{}
|
||||
}
|
||||
}
|
||||
|
||||
// collectDNSAddrs returns configured set of listening addresses. It also
|
||||
// returns a set of ports of each unspecified listening address.
|
||||
func (conf *ServerConfig) collectDNSAddrs() (
|
||||
addrs map[netip.AddrPort]unit,
|
||||
unspecPorts map[uint16]unit,
|
||||
) {
|
||||
// TODO(e.burkov): Perhaps, we shouldn't allocate as much memory, since the
|
||||
// TCP and UDP listening addresses are currently the same.
|
||||
addrs = make(map[netip.AddrPort]unit, len(conf.TCPListenAddrs)+len(conf.UDPListenAddrs))
|
||||
unspecPorts = map[uint16]unit{}
|
||||
|
||||
for _, laddr := range conf.TCPListenAddrs {
|
||||
collectListenAddr(laddr.AddrPort(), addrs, unspecPorts)
|
||||
}
|
||||
|
||||
for _, laddr := range conf.UDPListenAddrs {
|
||||
collectListenAddr(laddr.AddrPort(), addrs, unspecPorts)
|
||||
}
|
||||
|
||||
return addrs, unspecPorts
|
||||
}
|
||||
|
||||
// defaultPlainDNSPort is the default port for plain DNS.
|
||||
const defaultPlainDNSPort uint16 = 53
|
||||
|
||||
// upstreamMatcher is a function that matches address of an upstream.
|
||||
type upstreamMatcher func(addr netip.AddrPort) (ok bool)
|
||||
|
||||
// filterOut filters out all the upstreams that match um. It returns all the
|
||||
// closing errors joined.
|
||||
func (um upstreamMatcher) filterOut(upsConf *proxy.UpstreamConfig) (err error) {
|
||||
var errs []error
|
||||
delFunc := func(u upstream.Upstream) (ok bool) {
|
||||
// TODO(e.burkov): We should probably consider the protocol of u to
|
||||
// only filter out the listening addresses of the same protocol.
|
||||
addr, parseErr := aghnet.ParseAddrPort(u.Address(), defaultPlainDNSPort)
|
||||
if parseErr != nil || !um(addr) {
|
||||
// Don't filter out the upstream if it either cannot be parsed, or
|
||||
// does not match um.
|
||||
return false
|
||||
}
|
||||
|
||||
errs = append(errs, u.Close())
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
upsConf.Upstreams = slices.DeleteFunc(upsConf.Upstreams, delFunc)
|
||||
for d, ups := range upsConf.DomainReservedUpstreams {
|
||||
upsConf.DomainReservedUpstreams[d] = slices.DeleteFunc(ups, delFunc)
|
||||
}
|
||||
for d, ups := range upsConf.SpecifiedDomainUpstreams {
|
||||
upsConf.SpecifiedDomainUpstreams[d] = slices.DeleteFunc(ups, delFunc)
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// filterOurAddrs filters out all the upstreams that pointing to the local
|
||||
// listening addresses to avoid recursive queries. upsConf may appear empty
|
||||
// after the filtering. All the filtered upstreams are closed and these
|
||||
// closings errors are joined.
|
||||
func (conf *ServerConfig) filterOurAddrs(upsConf *proxy.UpstreamConfig) (err error) {
|
||||
addrs, unspecPorts := conf.collectDNSAddrs()
|
||||
if len(addrs) == 0 {
|
||||
log.Debug("dnsforward: no listen addresses")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var matcher upstreamMatcher
|
||||
if len(unspecPorts) == 0 {
|
||||
log.Debug("dnsforward: filtering out addresses %s", addrs)
|
||||
|
||||
matcher = func(a netip.AddrPort) (ok bool) {
|
||||
_, ok = addrs[a]
|
||||
|
||||
return ok
|
||||
}
|
||||
} else {
|
||||
var ifaceAddrs []netip.Addr
|
||||
ifaceAddrs, err = aghnet.CollectAllIfacesAddrs()
|
||||
if err != nil {
|
||||
// Don't wrap the error since it's informative enough as is.
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug("dnsforward: filtering out addresses %s on ports %d", ifaceAddrs, unspecPorts)
|
||||
|
||||
matcher = func(a netip.AddrPort) (ok bool) {
|
||||
if _, ok = unspecPorts[a.Port()]; ok {
|
||||
return slices.Contains(ifaceAddrs, a.Addr())
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return matcher.filterOut(upsConf)
|
||||
}
|
||||
|
||||
// prepareTLS - prepares TLS configuration for the DNS proxy
|
||||
func (s *Server) prepareTLS(proxyConfig *proxy.Config) (err error) {
|
||||
if len(s.conf.CertificateChainData) == 0 || len(s.conf.PrivateKeyData) == 0 {
|
||||
|
||||
Reference in New Issue
Block a user