Skip to content

Commit

Permalink
Pull request 1979: AG-25263 filtering config
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit a5607f8
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 30 15:44:26 2023 +0300

    home: upgrade yaml

commit 0593e4d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 30 15:01:14 2023 +0300

    home: upgrade yaml

commit 59ec4ba
Merge: 6555941 a325c9b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 30 14:57:41 2023 +0300

    Merge remote-tracking branch 'origin/master' into AG-25263-filtering-config

    # Conflicts:
    #	internal/dnsforward/http.go
    #	internal/dnsforward/http_test.go
    #	internal/dnsforward/process.go
    #	internal/dnsforward/process_internal_test.go

commit 6555941
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 30 14:38:01 2023 +0300

    docs: changelog

commit c66d14c
Merge: a50ff16 aac36a2
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 30 12:58:41 2023 +0300

    Merge remote-tracking branch 'origin/master' into AG-25263-filtering-config

commit a50ff16
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 30 11:22:12 2023 +0300

    home: imp code

commit ef40d07
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 29 16:19:14 2023 +0300

    home: imp code

commit 5fa09a9
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 29 14:47:48 2023 +0300

    home: imp code

commit 52bb295
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 29 13:33:01 2023 +0300

    home: imp code

commit 24cfccf
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 29 12:24:20 2023 +0300

    filtering: imp code

commit 758242b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 29 10:32:51 2023 +0300

    home: imp code

commit 906deaa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 14:46:01 2023 +0300

    dnsforward: imp code

commit 978bb50
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 14:40:31 2023 +0300

    home: imp code

commit d5b8dd5
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 12:34:32 2023 +0300

    filtering: imp code

commit d3e5726
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 11:57:33 2023 +0300

    home: upgrade yaml

commit 75d7015
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 11:46:55 2023 +0300

    home: upgrade yaml

commit cd8cb62
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 11:29:16 2023 +0300

    docs: changelog

commit 31c098d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Aug 28 11:08:48 2023 +0300

    docs: changelog

commit 24c88dd
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Sun Aug 27 19:12:55 2023 +0300

    home: imp code

commit 94f2d38
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Sun Aug 27 16:15:05 2023 +0300

    home: upgrade yaml

... and 10 more commits
  • Loading branch information
Mizzick authored and ainar-g committed Aug 30, 2023
1 parent a325c9b commit a2ca8b5
Show file tree
Hide file tree
Showing 20 changed files with 664 additions and 320 deletions.
72 changes: 71 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,77 @@ NOTE: Add new changes BELOW THIS COMMENT.

#### Configuration Changes

In this release, the schema version has changed from 24 to 25.
In this release, the schema version has changed from 24 to 26.

- Filtering-related settings have been moved from `dns` section of the YAML
configuration file to the new section `filtering`:

```yaml
# BEFORE:
'dns':
'filtering_enabled': true
'filters_update_interval': 24
'parental_enabled': false
'safebrowsing_enabled': false
'safebrowsing_cache_size': 1048576
'safesearch_cache_size': 1048576
'parental_cache_size': 1048576
'safe_search':
'enabled': false
'bing': true
'duckduckgo': true
'google': true
'pixabay': true
'yandex': true
'youtube': true
'rewrites': []
'blocked_services':
'schedule':
'time_zone': 'Local'
'ids': []
'protection_enabled': true,
'blocking_mode': 'custom_ip',
'blocking_ipv4': '1.2.3.4',
'blocking_ipv6': '1:2:3::4',
'blocked_response_ttl': 10,
'protection_disabled_until': 'null',
'parental_block_host': 'p.dns.adguard.com',
'safebrowsing_block_host': 's.dns.adguard.com'

# AFTER:
'filtering':
'filtering_enabled': true
'filters_update_interval': 24
'parental_enabled': false
'safebrowsing_enabled': false
'safebrowsing_cache_size': 1048576
'safesearch_cache_size': 1048576
'parental_cache_size': 1048576
'safe_search':
'enabled': false
'bing': true
'duckduckgo': true
'google': true
'pixabay': true
'yandex': true
'youtube': true
'rewrites': []
'blocked_services':
'schedule':
'time_zone': 'Local'
'ids': []
'protection_enabled': true,
'blocking_mode': 'custom_ip',
'blocking_ipv4': '1.2.3.4',
'blocking_ipv6': '1:2:3::4',
'blocked_response_ttl': 10,
'protection_disabled_until': 'null',
'parental_block_host': 'p.dns.adguard.com',
'safebrowsing_block_host': 's.dns.adguard.com',
```
To rollback this change, remove the new object `filtering`, set back filtering
properties in `dns` section, and change the `schema_version` back to `25`.

- Property `debug_pprof` which used to setup profiling HTTP handler, is now
moved to the new `pprof` object under `http` section. The new object contains
Expand Down
97 changes: 12 additions & 85 deletions internal/dnsforward/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,9 @@ import (
"golang.org/x/exp/slices"
)

// BlockingMode is an enum of all allowed blocking modes.
type BlockingMode string

// Allowed blocking modes.
const (
// BlockingModeCustomIP means respond with a custom IP address.
BlockingModeCustomIP BlockingMode = "custom_ip"

// BlockingModeDefault is the same as BlockingModeNullIP for
// Adblock-style rules, but responds with the IP address specified in
// the rule when blocked by an `/etc/hosts`-style rule.
BlockingModeDefault BlockingMode = "default"

// BlockingModeNullIP means respond with a zero IP address: "0.0.0.0"
// for A requests and "::" for AAAA ones.
BlockingModeNullIP BlockingMode = "null_ip"

// BlockingModeNXDOMAIN means respond with the NXDOMAIN code.
BlockingModeNXDOMAIN BlockingMode = "nxdomain"

// BlockingModeREFUSED means respond with the REFUSED code.
BlockingModeREFUSED BlockingMode = "refused"
)

// FilteringConfig represents the DNS filtering configuration of AdGuard Home
// The zero FilteringConfig is empty and ready for use.
type FilteringConfig struct {
// Config represents the DNS filtering configuration of AdGuard Home. The zero
// Config is empty and ready for use.
type Config struct {
// Callbacks for other modules

// FilterHandler is an optional additional filtering callback.
Expand All @@ -62,37 +38,6 @@ type FilteringConfig struct {
// nil if there are no custom upstreams for the client.
GetCustomUpstreamByClient func(id string) (conf *proxy.UpstreamConfig, err error) `yaml:"-"`

// Protection configuration

// ProtectionEnabled defines whether or not use any of filtering features.
ProtectionEnabled bool `yaml:"protection_enabled"`

// BlockingMode defines the way how blocked responses are constructed.
BlockingMode BlockingMode `yaml:"blocking_mode"`

// BlockingIPv4 is the IP address to be returned for a blocked A request.
BlockingIPv4 netip.Addr `yaml:"blocking_ipv4"`

// BlockingIPv6 is the IP address to be returned for a blocked AAAA
// request.
BlockingIPv6 netip.Addr `yaml:"blocking_ipv6"`

// BlockedResponseTTL is the time-to-live value for blocked responses. If
// 0, then default value is used (3600).
BlockedResponseTTL uint32 `yaml:"blocked_response_ttl"`

// ProtectionDisabledUntil is the timestamp until when the protection is
// disabled.
ProtectionDisabledUntil *time.Time `yaml:"protection_disabled_until"`

// ParentalBlockHost is the IP (or domain name) which is used to respond to
// DNS requests blocked by parental control.
ParentalBlockHost string `yaml:"parental_block_host"`

// SafeBrowsingBlockHost is the IP (or domain name) which is used to
// respond to DNS requests blocked by safe-browsing.
SafeBrowsingBlockHost string `yaml:"safebrowsing_block_host"`

// Anti-DNS amplification

// Ratelimit is the maximum number of requests per second from a given IP
Expand Down Expand Up @@ -137,7 +82,7 @@ type FilteringConfig struct {

// AllowedClients is the slice of IP addresses, CIDR networks, and
// ClientIDs of allowed clients. If not empty, only these clients are
// allowed, and [FilteringConfig.DisallowedClients] are ignored.
// allowed, and [Config.DisallowedClients] are ignored.
AllowedClients []string `yaml:"allowed_clients"`

// DisallowedClients is the slice of IP addresses, CIDR networks, and
Expand Down Expand Up @@ -283,7 +228,7 @@ type ServerConfig struct {
// Remove that.
AddrProcConf *client.DefaultAddrProcConfig

FilteringConfig
Config
TLSConfig
DNSCryptConfig
TLSAllowUnencryptedDoH bool
Expand Down Expand Up @@ -324,13 +269,6 @@ type ServerConfig struct {
UseHTTP3Upstreams bool
}

// if any of ServerConfig values are zero, then default values from below are used
var defaultValues = ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{Port: 53}},
TCPListenAddrs: []*net.TCPAddr{{Port: 53}},
FilteringConfig: FilteringConfig{BlockedResponseTTL: 3600},
}

// createProxyConfig creates and validates configuration for the main proxy.
func (s *Server) createProxyConfig() (conf proxy.Config, err error) {
srvConf := s.conf
Expand Down Expand Up @@ -403,10 +341,7 @@ func (s *Server) createProxyConfig() (conf proxy.Config, err error) {
return conf, nil
}

const (
defaultSafeBrowsingBlockHost = "standard-block.dns.adguard.com"
defaultParentalBlockHost = "family-block.dns.adguard.com"
)
const defaultBlockedResponseTTL = 3600

// initDefaultSettings initializes default settings if nothing
// is configured
Expand All @@ -419,20 +354,12 @@ func (s *Server) initDefaultSettings() {
s.conf.BootstrapDNS = defaultBootstrap
}

if s.conf.ParentalBlockHost == "" {
s.conf.ParentalBlockHost = defaultParentalBlockHost
}

if s.conf.SafeBrowsingBlockHost == "" {
s.conf.SafeBrowsingBlockHost = defaultSafeBrowsingBlockHost
}

if s.conf.UDPListenAddrs == nil {
s.conf.UDPListenAddrs = defaultValues.UDPListenAddrs
s.conf.UDPListenAddrs = defaultUDPListenAddrs
}

if s.conf.TCPListenAddrs == nil {
s.conf.TCPListenAddrs = defaultValues.TCPListenAddrs
s.conf.TCPListenAddrs = defaultTCPListenAddrs
}

if len(s.conf.BlockedHosts) == 0 {
Expand Down Expand Up @@ -565,9 +492,9 @@ func (s *Server) UpdatedProtectionStatus() (enabled bool, disabledUntil *time.Ti
s.serverLock.RLock()
defer s.serverLock.RUnlock()

disabledUntil = s.conf.ProtectionDisabledUntil
disabledUntil = s.dnsFilter.ProtectionDisabledUntil
if disabledUntil == nil {
return s.conf.ProtectionEnabled, nil
return s.dnsFilter.ProtectionEnabled, nil
}

if time.Now().Before(*disabledUntil) {
Expand Down Expand Up @@ -599,8 +526,8 @@ func (s *Server) enableProtectionAfterPause() {
s.serverLock.Lock()
defer s.serverLock.Unlock()

s.conf.ProtectionEnabled = true
s.conf.ProtectionDisabledUntil = nil
s.dnsFilter.ProtectionEnabled = true
s.dnsFilter.ProtectionDisabledUntil = nil

log.Info("dns: protection is restarted after pause")
}
6 changes: 4 additions & 2 deletions internal/dnsforward/dns64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,13 @@ func TestServer_HandleDNSRequest_dns64(t *testing.T) {
// right after stop, due to a data race in [proxy.Proxy.Init] method
// when setting an OOB size. As a temporary workaround, recreate the
// whole server for each test case.
s := createTestServer(t, &filtering.Config{}, ServerConfig{
s := createTestServer(t, &filtering.Config{
BlockingMode: filtering.BlockingModeDefault,
}, ServerConfig{
UDPListenAddrs: []*net.UDPAddr{{}},
TCPListenAddrs: []*net.TCPAddr{{}},
UseDNS64: true,
FilteringConfig: FilteringConfig{
Config: Config{
EDNSClientSubnet: &EDNSClientSubnet{Enabled: false},
},
}, localUps)
Expand Down
33 changes: 24 additions & 9 deletions internal/dnsforward/dnsforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ var defaultBootstrap = []string{"9.9.9.10", "149.112.112.10", "2620:fe::10", "26
// Often requested by all kinds of DNS probes
var defaultBlockedHosts = []string{"version.bind", "id.server", "hostname.bind"}

var (
// defaultUDPListenAddrs are the default UDP addresses for the server.
defaultUDPListenAddrs = []*net.UDPAddr{{Port: 53}}

// defaultTCPListenAddrs are the default TCP addresses for the server.
defaultTCPListenAddrs = []*net.TCPAddr{{Port: 53}}
)

var webRegistered bool

// DHCP is an interface for accesing DHCP lease data needed in this package.
Expand Down Expand Up @@ -255,11 +263,11 @@ func (s *Server) Close() {
}

// WriteDiskConfig - write configuration
func (s *Server) WriteDiskConfig(c *FilteringConfig) {
func (s *Server) WriteDiskConfig(c *Config) {
s.serverLock.RLock()
defer s.serverLock.RUnlock()

sc := s.conf.FilteringConfig
sc := s.conf.Config
*c = sc
c.RatelimitWhitelist = stringutil.CloneSlice(sc.RatelimitWhitelist)
c.BootstrapDNS = stringutil.CloneSlice(sc.BootstrapDNS)
Expand Down Expand Up @@ -534,7 +542,11 @@ func (s *Server) setupLocalResolvers() (err error) {
func (s *Server) Prepare(conf *ServerConfig) (err error) {
s.conf = *conf

err = validateBlockingMode(s.conf.BlockingMode, s.conf.BlockingIPv4, s.conf.BlockingIPv6)
err = validateBlockingMode(
s.dnsFilter.BlockingMode,
s.dnsFilter.BlockingIPv4,
s.dnsFilter.BlockingIPv6,
)
if err != nil {
return fmt.Errorf("checking blocking mode: %w", err)
}
Expand Down Expand Up @@ -645,15 +657,18 @@ func (s *Server) setupAddrProc() {
}

// validateBlockingMode returns an error if the blocking mode data aren't valid.
func validateBlockingMode(mode BlockingMode, blockingIPv4, blockingIPv6 netip.Addr) (err error) {
func validateBlockingMode(
mode filtering.BlockingMode,
blockingIPv4, blockingIPv6 netip.Addr,
) (err error) {
switch mode {
case
BlockingModeDefault,
BlockingModeNXDOMAIN,
BlockingModeREFUSED,
BlockingModeNullIP:
filtering.BlockingModeDefault,
filtering.BlockingModeNXDOMAIN,
filtering.BlockingModeREFUSED,
filtering.BlockingModeNullIP:
return nil
case BlockingModeCustomIP:
case filtering.BlockingModeCustomIP:
if !blockingIPv4.Is4() {
return fmt.Errorf("blocking_ipv4 must be valid ipv4 on custom_ip blocking_mode")
} else if !blockingIPv6.Is6() {
Expand Down
Loading

0 comments on commit a2ca8b5

Please sign in to comment.