Pull request 2009: 4569-blocked-response-ttl

Updates #4569.

Squashed commit of the following:

commit cc5842fd9d19e6d8bc19f9f88a587c2dd102828d
Merge: 2e1e59e1b 5c6b3ace4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Sep 13 13:41:59 2023 +0300

    Merge branch 'master' into 4569-blocked-response-ttl

commit 2e1e59e1b787d461819d01a99ceb70d21e882dc1
Author: Ildar Kamalov <ik@adguard.com>
Date:   Tue Sep 12 20:28:34 2023 +0300

    client: fix input length

commit 05bfa8cff7bff020a5b655779513612bc353267f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Sep 12 12:16:35 2023 +0300

    openapi: bump version

commit f4f36111265aea8927b9a5154d74954ba05e5f10
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Sep 11 19:36:38 2023 +0300

    all: upg chlog

commit 09c1e6d75ee7a95a5286aed526521a0206026986
Merge: ff3e2dc9f fb332dfc2
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Sep 11 19:35:30 2023 +0300

    Merge branch 'master' into 4569-blocked-response-ttl

commit ff3e2dc9f1ed1aacf023821160c6973ee98506b7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Sep 11 19:34:59 2023 +0300

    client: add blocked response ttl

commit 31064d160e361f9e88f545fa42d8eb824ecc5c86
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Sep 11 15:58:06 2023 +0300

    all: add blocked response ttl
This commit is contained in:
Stanislav Chzhen 2023-09-13 13:58:12 +03:00
parent 5c6b3ace4a
commit a59fca2da3
12 changed files with 150 additions and 17 deletions

View File

@ -23,6 +23,13 @@ See also the [v0.107.39 GitHub milestone][ms-v0.107.39].
NOTE: Add new changes BELOW THIS COMMENT.
-->
### Added
- Ability to specify for how long clients should cache a filtered response,
using the *Blocked response TTL* field on the *DNS settings* page ([#4569]).
[#4569]: https://github.com/AdguardTeam/AdGuardHome/issues/4569
<!--
NOTE: Add new changes ABOVE THIS COMMENT.
-->

View File

@ -283,6 +283,9 @@
"custom_ip": "Custom IP",
"blocking_ipv4": "Blocking IPv4",
"blocking_ipv6": "Blocking IPv6",
"blocked_response_ttl": "Blocked response TTL",
"blocked_response_ttl_desc": "Specifies for how many seconds the clients should cache a filtered response",
"form_enter_blocked_response_ttl": "Enter blocked response TTL (seconds)",
"dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",

View File

@ -68,10 +68,10 @@ const Form = ({
return <form onSubmit={handleSubmit}>
<div className="row">
<div className="col-12 col-sm-6">
<div className="col-12 col-md-7">
<div className="form__group form__group--settings">
<label htmlFor="ratelimit"
className="form__label form__label--with-desc">
className="form__label form__label--with-desc">
<Trans>rate_limit</Trans>
</label>
<div className="form__desc form__desc--top">
@ -160,24 +160,46 @@ const Form = ({
name,
validateIp,
}) => <div className="col-12 col-sm-6" key={name}>
<div className="form__group form__group--settings">
<label className="form__label form__label--with-desc"
htmlFor={name}><Trans>{name}</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>{description}</Trans>
<div className="form__group form__group--settings">
<label className="form__label form__label--with-desc"
htmlFor={name}><Trans>{name}</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>{description}</Trans>
</div>
<Field
name={name}
component={renderInputField}
className="form-control"
placeholder={t('form_enter_ip')}
validate={[validateIp, validateRequiredValue]}
/>
</div>
<Field
name={name}
component={renderInputField}
className="form-control"
placeholder={t('form_enter_ip')}
validate={[validateIp, validateRequiredValue]}
/>
</div>
</div>)}
</div>)}
</>
)}
<div className="col-12 col-md-7">
<div className="form__group form__group--settings">
<label htmlFor="blocked_response_ttl"
className="form__label form__label--with-desc">
<Trans>blocked_response_ttl</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>blocked_response_ttl_desc</Trans>
</div>
<Field
name="blocked_response_ttl"
type="number"
component={renderInputField}
className="form-control"
placeholder={t('form_enter_blocked_response_ttl')}
normalize={toNumber}
validate={validateRequiredValue}
min={UINT32_RANGE.MIN}
max={UINT32_RANGE.MAX}
/>
</div>
</div>
</div>
<button
type="submit"

View File

@ -13,6 +13,7 @@ const Config = () => {
ratelimit,
blocking_ipv4,
blocking_ipv6,
blocked_response_ttl,
edns_cs_enabled,
edns_cs_use_custom,
edns_cs_custom_ip,
@ -38,6 +39,7 @@ const Config = () => {
blocking_mode,
blocking_ipv4,
blocking_ipv6,
blocked_response_ttl,
edns_cs_enabled,
disable_ipv6,
dnssec_enabled,

View File

@ -49,6 +49,7 @@ const dnsConfig = handleActions(
ratelimit: 20,
blocking_ipv4: DEFAULT_BLOCKING_IPV4,
blocking_ipv6: DEFAULT_BLOCKING_IPV6,
blocked_response_ttl: 10,
edns_cs_enabled: false,
disable_ipv6: false,
dnssec_enabled: false,

View File

@ -65,6 +65,9 @@ type jsonDNSConfig struct {
// UpstreamMode defines the way DNS requests are constructed.
UpstreamMode *string `json:"upstream_mode"`
// BlockedResponseTTL is the TTL for blocked responses.
BlockedResponseTTL *uint32 `json:"blocked_response_ttl"`
// CacheSize in bytes.
CacheSize *uint32 `json:"cache_size"`
@ -115,6 +118,7 @@ func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
bootstraps := stringutil.CloneSliceOrEmpty(s.conf.BootstrapDNS)
fallbacks := stringutil.CloneSliceOrEmpty(s.conf.FallbackDNS)
blockingMode, blockingIPv4, blockingIPv6 := s.dnsFilter.BlockingMode()
blockedResponseTTL := s.dnsFilter.BlockedResponseTTL()
ratelimit := s.conf.Ratelimit
customIP := s.conf.EDNSClientSubnet.CustomIP
@ -158,6 +162,7 @@ func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
EDNSCSUseCustom: &useCustom,
DNSSECEnabled: &enableDNSSEC,
DisableIPv6: &aaaaDisabled,
BlockedResponseTTL: &blockedResponseTTL,
CacheSize: &cacheSize,
CacheMinTTL: &cacheMinTTL,
CacheMaxTTL: &cacheMaxTTL,
@ -321,6 +326,10 @@ func (s *Server) setConfig(dc *jsonDNSConfig) (shouldRestart bool) {
s.dnsFilter.SetBlockingMode(*dc.BlockingMode, dc.BlockingIPv4, dc.BlockingIPv6)
}
if dc.BlockedResponseTTL != nil {
s.dnsFilter.SetBlockedResponseTTL(*dc.BlockedResponseTTL)
}
if dc.ProtectionEnabled != nil {
s.dnsFilter.SetProtectionEnabled(*dc.ProtectionEnabled)
}

View File

@ -60,6 +60,7 @@ func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
filterConf := &filtering.Config{
ProtectionEnabled: true,
BlockingMode: filtering.BlockingModeDefault,
BlockedResponseTTL: 10,
SafeBrowsingEnabled: true,
SafeBrowsingCacheSize: 1000,
SafeSearchConf: filtering.SafeSearchConfig{Enabled: true},
@ -137,6 +138,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
filterConf := &filtering.Config{
ProtectionEnabled: true,
BlockingMode: filtering.BlockingModeDefault,
BlockedResponseTTL: 10,
SafeBrowsingEnabled: true,
SafeBrowsingCacheSize: 1000,
SafeSearchConf: filtering.SafeSearchConfig{Enabled: true},
@ -229,6 +231,9 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
}, {
name: "fallbacks",
wantSet: "",
}, {
name: "blocked_response_ttl",
wantSet: "",
}}
var data map[string]struct {

View File

@ -20,6 +20,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -55,6 +56,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -90,6 +92,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,

View File

@ -25,6 +25,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -62,6 +63,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -100,6 +102,7 @@
"blocking_mode": "refused",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -138,6 +141,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -176,6 +180,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -214,6 +219,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": true,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -254,6 +260,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": true,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -294,6 +301,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -332,6 +340,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": true,
"disable_ipv6": false,
@ -370,6 +379,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -408,6 +418,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -446,6 +457,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -486,6 +498,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -526,6 +539,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -565,6 +579,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -603,6 +618,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -643,6 +659,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -686,6 +703,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -724,6 +742,7 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
@ -766,6 +785,46 @@
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 10,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,
"upstream_mode": "",
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": [],
"edns_cs_use_custom": false,
"edns_cs_custom_ip": ""
}
},
"blocked_response_ttl": {
"req": {
"blocked_response_ttl": 11
},
"want": {
"upstream_dns": [
"8.8.8.8:53",
"8.8.4.4:53"
],
"upstream_dns_file": "",
"bootstrap_dns": [
"9.9.9.10",
"149.112.112.10",
"2620:fe::10",
"2620:fe::fe:10"
],
"fallback_dns": [],
"protection_enabled": true,
"protection_disabled_until": null,
"ratelimit": 0,
"blocking_mode": "default",
"blocking_ipv4": "",
"blocking_ipv6": "",
"blocked_response_ttl": 11,
"edns_cs_enabled": false,
"dnssec_enabled": false,
"disable_ipv6": false,

View File

@ -514,8 +514,19 @@ func (d *DNSFilter) BlockingMode() (mode BlockingMode, bIPv4, bIPv6 netip.Addr)
return d.conf.BlockingMode, d.conf.BlockingIPv4, d.conf.BlockingIPv6
}
// SetBlockedResponseTTL sets TTL for blocked responses.
func (d *DNSFilter) SetBlockedResponseTTL(ttl uint32) {
d.confMu.Lock()
defer d.confMu.Unlock()
d.conf.BlockedResponseTTL = ttl
}
// BlockedResponseTTL returns TTL for blocked responses.
func (d *DNSFilter) BlockedResponseTTL() (ttl uint32) {
d.confMu.Lock()
defer d.confMu.Unlock()
return d.conf.BlockedResponseTTL
}

View File

@ -4,6 +4,13 @@
## v0.108.0: API changes
## v0.107.39: API changes
### The new field `"blocked_response_ttl"` in `DNSConfig` object
* The new field `"blocked_response_ttl"` in `GET /control/dns_info` and `POST
/control/dns_config` is the TTL for blocked responses.
## v0.107.37: API changes
### The new field `"fallback_dns"` in `UpstreamsConfig` object

View File

@ -1460,6 +1460,10 @@
'type': 'string'
'blocking_ipv6':
'type': 'string'
'blocked_response_ttl':
'type': 'integer'
'minimum': 0
'description': 'TTL for blocked responses.'
'protection_disabled_until':
'type': 'string'
'description': 'Protection is pause until this time. Nullable.'