Pull request: AGDNS-3870-imp-dnssec

Squashed commit of the following:

commit 0daffc441eec484e534bf7067185418ef0da57d4
Merge: b75c3829c b08e58766
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Apr 23 17:04:08 2026 +0700

    Merge remote-tracking branch 'origin/master' into AGDNS-3870-imp-dnssec

commit b75c3829cd8d2a17c05a93983fe1faffe78bd902
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Apr 23 17:02:23 2026 +0700

    all: upd dnsproxy

commit c9c133bb58a64628da2874d8a30b4ae1c7896c42
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Apr 23 10:39:15 2026 +0700

    docs: upd changelog

commit cbd9d3b027aef9c0354137c2d13e638d51700b83
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Apr 22 09:42:37 2026 +0700

    docs: upd changelog

commit c7f204f54582d6c96ecebba0f423d9dc7384512d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Apr 21 11:54:02 2026 +0700

    docs: upd changelog

commit 1036e3290e335927375fdcf57fdaf87805af286b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Apr 21 11:23:47 2026 +0700

    home: dnssec default

commit c043669f8be40f9dbf4a3d0aecf632c3437066e8
Merge: c8eb8145b 9e153fbd9
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Apr 21 11:09:37 2026 +0700

    Merge remote-tracking branch 'origin/master' into AGDNS-3870-imp-dnssec

commit c8eb8145b4fbb340f0d84b8981445b24665b5a99
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Apr 15 11:41:11 2026 +0700

    all: upd dnsproxy
This commit is contained in:
Dimitry Kolyshev 2026-04-23 12:30:05 +00:00
parent b08e587660
commit f7c9078781
10 changed files with 23 additions and 52 deletions

View file

@ -18,10 +18,16 @@ See also the [v0.107.75 GitHub milestone][ms-v0.107.75].
NOTE: Add new changes BELOW THIS COMMENT.
-->
### Changed
- `enable_dnssec` in `dns` configuration now defines whether the proxy should set the DO flag in the upstream requests, the default is `true` ([#7046]).
### Fixed
- Safe Browsing and Parental Control labels on the General Settings page not updating after changing the UI language.
[#7046]: https://github.com/AdguardTeam/AdGuardHome/issues/7046
<!--
NOTE: Add new changes ABOVE THIS COMMENT.
-->

2
go.mod
View file

@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
go 1.26.2
require (
github.com/AdguardTeam/dnsproxy v0.81.1
github.com/AdguardTeam/dnsproxy v0.81.2
github.com/AdguardTeam/golibs v0.35.11
github.com/AdguardTeam/urlfilter v0.23.2
github.com/NYTimes/gziphandler v1.1.1

4
go.sum
View file

@ -4,8 +4,8 @@ cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA=
cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
github.com/AdguardTeam/dnsproxy v0.81.1 h1:LM0JYsm3tMRVbJAtjbPcZ9vVmWV9NDmpb+ZsW8I/apU=
github.com/AdguardTeam/dnsproxy v0.81.1/go.mod h1:5lTCQqVQ8Kt4KnTOmdV0Ab3k58KZFOazupVfXJezwq8=
github.com/AdguardTeam/dnsproxy v0.81.2 h1:j1p74pbzyrrE21OL1lmNEWxuhHXNykk+NDH4hgDD9Eg=
github.com/AdguardTeam/dnsproxy v0.81.2/go.mod h1:5lTCQqVQ8Kt4KnTOmdV0Ab3k58KZFOazupVfXJezwq8=
github.com/AdguardTeam/golibs v0.35.11 h1:LooiyPNtsfv32reFz4qD8KpWQm9jIFuPwHxHyVgtaRg=
github.com/AdguardTeam/golibs v0.35.11/go.mod h1:wBe9Vgrcn6M4T7p7z/vnRZANLzVO72myRggnCKBx+sQ=
github.com/AdguardTeam/urlfilter v0.23.2 h1:EiS/PQZO/X2S6cduFW6BBoRLyjd6SqZj1ZiFbU1KaFE=

View file

@ -140,7 +140,8 @@ type Config struct {
// requests.
AAAADisabled bool `yaml:"aaaa_disabled"`
// EnableDNSSEC, if true, set AD flag in outcoming DNS request.
// EnableDNSSEC defines whether the proxy should set the AD/DO bits in the
// upstream requests.
EnableDNSSEC bool `yaml:"enable_dnssec"`
// EDNSClientSubnet is the settings list for EDNS Client Subnet.
@ -365,7 +366,8 @@ func (s *Server) newProxyConfig(ctx context.Context) (conf *proxy.Config, err er
PendingRequests: &proxy.PendingRequestsConfig{
Enabled: srvConf.PendingRequestsEnabled,
},
HTTPConfig: httpConf,
HTTPConfig: httpConf,
DNSSECEnabled: srvConf.EnableDNSSEC,
}
if srvConf.EDNSClientSubnet.UseCustom {

View file

@ -806,6 +806,7 @@ func TestServerCustomClientUpstream(t *testing.T) {
Config: Config{
CacheSize: defaultCacheSize,
UpstreamMode: UpstreamModeLoadBalance,
EnableDNSSEC: true,
EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false,
},

View file

@ -471,8 +471,6 @@ func (s *Server) processUpstream(
s.setCustomUpstream(ctx, l, pctx, dctx.clientID)
reqWantsDNSSEC := s.setReqAD(req)
// Process the request further since it wasn't filtered.
prx := s.proxy()
if prx == nil {
@ -488,54 +486,9 @@ func (s *Server) processUpstream(
dctx.responseFromUpstream = true
dctx.responseAD = pctx.Res.AuthenticatedData
s.setRespAD(pctx, reqWantsDNSSEC)
return resultCodeSuccess
}
// setReqAD changes the request based on the server settings. wantsDNSSEC is
// false if the response should be cleared of the AD bit.
//
// TODO(a.garipov, e.burkov): This should probably be done in module dnsproxy.
func (s *Server) setReqAD(req *dns.Msg) (wantsDNSSEC bool) {
if !s.conf.EnableDNSSEC {
return false
}
origReqAD := req.AuthenticatedData
req.AuthenticatedData = true
// Per [RFC 6840] says, validating resolvers should only set the AD bit when
// the response has the AD bit set and the request contained either a set DO
// bit or a set AD bit. So, if neither of these is true, clear the AD bits
// in [Server.setRespAD].
//
// [RFC 6840]: https://datatracker.ietf.org/doc/html/rfc6840#section-5.8
return origReqAD || hasDO(req)
}
// hasDO returns true if msg has EDNS(0) options and the DNSSEC OK flag is set
// in there.
//
// TODO(a.garipov): Move to golibs/dnsmsg when it's there.
func hasDO(msg *dns.Msg) (do bool) {
o := msg.IsEdns0()
if o == nil {
return false
}
return o.Do()
}
// setRespAD changes the request and response based on the server settings and
// the original request data.
func (s *Server) setRespAD(pctx *proxy.DNSContext, reqWantsDNSSEC bool) {
if s.conf.EnableDNSSEC && !reqWantsDNSSEC {
pctx.Req.AuthenticatedData = false
pctx.Res.AuthenticatedData = false
}
}
// dhcpHostFromRequest returns a hostname from question, if the request is for a
// DHCP client's hostname when DHCP is enabled, and an empty string otherwise.
func (s *Server) dhcpHostFromRequest(q *dns.Question) (reqHost string) {

View file

@ -494,6 +494,7 @@ var config = &configuration{
CacheSize: 4 * 1024 * 1024,
CacheOptimisticAnswerTTL: timeutil.Duration(30 * time.Second),
CacheOptimisticMaxAge: timeutil.Duration(12 * time.Hour),
EnableDNSSEC: true,
EDNSClientSubnet: &dnsforward.EDNSClientSubnet{
CustomIP: netip.Addr{},

View file

@ -52,6 +52,10 @@ type Config struct {
// CacheEnabled defines if the response cache should be used.
CacheEnabled bool
// DNSSECEnabled specifies if the proxy should set the DO bits in the
// upstream requests.
DNSSECEnabled bool
// RefuseAny, if true, refuses DNS queries with the type ANY.
RefuseAny bool

View file

@ -77,6 +77,7 @@ func New(c *Config) (svc *Service, err error) {
CacheSizeBytes: c.CacheSize,
CacheEnabled: c.CacheEnabled,
RefuseAny: c.RefuseAny,
DNSSECEnabled: c.DNSSECEnabled,
UseDNS64: c.UseDNS64,
},
bootstraps: c.BootstrapServers,
@ -109,6 +110,7 @@ func New(c *Config) (svc *Service, err error) {
RequestHandler: rlMw.Wrap(proxy.DefaultHandler{}),
DNS64Prefs: svc.proxyConf.DNS64Prefs,
CacheEnabled: svc.proxyConf.CacheEnabled,
DNSSECEnabled: svc.proxyConf.DNSSECEnabled,
RefuseAny: svc.proxyConf.RefuseAny,
UseDNS64: svc.proxyConf.UseDNS64,
})

View file

@ -29,6 +29,7 @@ type ReqPatchSettingsDNS struct {
Ratelimit jsonpatch.NonRemovable[int] `json:"ratelimit"`
BootstrapPreferIPv6 jsonpatch.NonRemovable[bool] `json:"bootstrap_prefer_ipv6"`
DNSSECEnabled jsonpatch.NonRemovable[bool] `json:"dnssec"`
RefuseAny jsonpatch.NonRemovable[bool] `json:"refuse_any"`
UseDNS64 jsonpatch.NonRemovable[bool] `json:"use_dns64"`
}
@ -92,6 +93,7 @@ func (svc *Service) handlePatchSettingsDNS(w http.ResponseWriter, r *http.Reques
req.Ratelimit.Set(&newConf.Ratelimit)
req.BootstrapPreferIPv6.Set(&newConf.BootstrapPreferIPv6)
req.DNSSECEnabled.Set(&newConf.DNSSECEnabled)
req.RefuseAny.Set(&newConf.RefuseAny)
req.UseDNS64.Set(&newConf.UseDNS64)