Pull request 1758: 1472-edns-custom-ip-api

Merge in DNS/adguard-home from 1472-edns-custom-ip-api to master

Updates #1472

Squashed commit of the following:

commit 7605ec5bd5467ddd28a650385193eb2332653bb6
Merge: 8b2ac227 194ead34
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 22 13:39:25 2023 +0300

    Merge branch 'master' into 1472-edns-custom-ip-api

commit 8b2ac22793a51d2555d32c1f5b5c118118807d1f
Merge: d5ca8b6e c3edab43
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 21 18:26:55 2023 +0300

    Merge branch 'master' into 1472-edns-custom-ip-api

commit d5ca8b6e1d87480d4ee4afd346e6bf04907fca95
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 21 18:26:24 2023 +0300

    dnsforward: imp tests

commit 1302586d22812c22755ea1c7e7fcd32330d707c5
Author: Vladislav Abdulmyanov <v.abdulmyanov@adguard.com>
Date:   Tue Mar 21 16:47:56 2023 +0200

    client: change validation for custom edns ip

commit 44e4dc6d1e47de6597ed9ee328db9639e38b4868
Author: Vladislav Abdulmyanov <v.abdulmyanov@adguard.com>
Date:   Tue Mar 21 16:31:42 2023 +0200

    client: implement edns custom ip

commit 8a3e7ad8ebf16262818821340da23baa5f004bff
Merge: 04ac1112 f736d85e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 21 15:04:40 2023 +0300

    Merge branch 'master' into 1472-edns-custom-ip-api

commit 04ac1112dda2e778243555b2f54819e5ba586e05
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 21 15:03:39 2023 +0300

    dnsforward: imp tests

commit b44f6d0ccb3ba7b7a5be07c9cf293dad9c83c794
Merge: 19c6851e 48431f8b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 20 17:55:49 2023 +0300

    Merge branch 'master' into 1472-edns-custom-ip-api

commit 19c6851e30f30b0572334822e8639e03760de986
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 10 10:40:15 2023 +0300

    all: fix chlog

commit 6dcdcbd666ebf3a56a38251e8ead09c605068ce3
Merge: a7f1bf71 a2053526
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 10 10:23:37 2023 +0300

    Merge branch 'master' into 1472-edns-custom-ip-api

commit a7f1bf715e3557c710b700b9bd923868eb07715b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 7 19:24:18 2023 +0300

    home: fix default value

commit 0311a9bb6571975963d747ef4ef427b59dca03bc
Merge: 7e0bb3df 1011b8f9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 7 19:04:18 2023 +0300

    Merge branch 'master' into 1472-edns-custom-ip-api

commit 7e0bb3df78f10f4b4ae0fd49681d1aa0040521c5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 7 19:03:24 2023 +0300

    all: fix chlog

commit 202d7ccf4721ccf39726da01d237e07317bfaa58
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 7 11:35:41 2023 +0300

    dnsforward: fix typo

commit fe95e003a0c3b316a44b5ec0b848a60ddd4c85cf
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 7 11:28:21 2023 +0300

    all: fix docs

commit 66835a9aa22b3015f9238c1d6f5aa9bd6067db8a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 7 10:48:08 2023 +0300

    dnsforward: add todo

commit b58255e1e6660a8229bb9c40f2acddebb3dbdc66
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 6 15:40:02 2023 +0300

    all: upd chlog

commit 9b2be7facba30c815144e08a7835353cad14c405
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 3 11:22:19 2023 +0300

    dnsforward: edns custom ip api
This commit is contained in:
Stanislav Chzhen
2023-03-22 13:42:20 +03:00
parent 194ead3479
commit 306c1983a2
12 changed files with 326 additions and 97 deletions

View File

@@ -23,26 +23,78 @@ import (
)
// jsonDNSConfig is the JSON representation of the DNS server configuration.
//
// TODO(s.chzhen): Split it into smaller pieces. Use aghalg.NullBool instead
// of *bool.
type jsonDNSConfig struct {
Upstreams *[]string `json:"upstream_dns"`
UpstreamsFile *string `json:"upstream_dns_file"`
Bootstraps *[]string `json:"bootstrap_dns"`
ProtectionEnabled *bool `json:"protection_enabled"`
RateLimit *uint32 `json:"ratelimit"`
BlockingMode *BlockingMode `json:"blocking_mode"`
EDNSCSEnabled *bool `json:"edns_cs_enabled"`
DNSSECEnabled *bool `json:"dnssec_enabled"`
DisableIPv6 *bool `json:"disable_ipv6"`
UpstreamMode *string `json:"upstream_mode"`
CacheSize *uint32 `json:"cache_size"`
CacheMinTTL *uint32 `json:"cache_ttl_min"`
CacheMaxTTL *uint32 `json:"cache_ttl_max"`
CacheOptimistic *bool `json:"cache_optimistic"`
ResolveClients *bool `json:"resolve_clients"`
UsePrivateRDNS *bool `json:"use_private_ptr_resolvers"`
LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"`
BlockingIPv4 net.IP `json:"blocking_ipv4"`
BlockingIPv6 net.IP `json:"blocking_ipv6"`
// Upstreams is the list of upstream DNS servers.
Upstreams *[]string `json:"upstream_dns"`
// UpstreamsFile is the file containing upstream DNS servers.
UpstreamsFile *string `json:"upstream_dns_file"`
// Bootstraps is the list of DNS servers resolving IP addresses of the
// upstream DoH/DoT resolvers.
Bootstraps *[]string `json:"bootstrap_dns"`
// ProtectionEnabled defines if protection is enabled.
ProtectionEnabled *bool `json:"protection_enabled"`
// RateLimit is the number of requests per second allowed per client.
RateLimit *uint32 `json:"ratelimit"`
// BlockingMode defines the way blocked responses are constructed.
BlockingMode *BlockingMode `json:"blocking_mode"`
// EDNSCSEnabled defines if EDNS Client Subnet is enabled.
EDNSCSEnabled *bool `json:"edns_cs_enabled"`
// EDNSCSUseCustom defines if EDNSCSCustomIP should be used.
EDNSCSUseCustom *bool `json:"edns_cs_use_custom"`
// DNSSECEnabled defines if DNSSEC is enabled.
DNSSECEnabled *bool `json:"dnssec_enabled"`
// DisableIPv6 defines if IPv6 addresses should be dropped.
DisableIPv6 *bool `json:"disable_ipv6"`
// UpstreamMode defines the way DNS requests are constructed.
UpstreamMode *string `json:"upstream_mode"`
// CacheSize in bytes.
CacheSize *uint32 `json:"cache_size"`
// CacheMinTTL is custom minimum TTL for cached DNS responses.
CacheMinTTL *uint32 `json:"cache_ttl_min"`
// CacheMaxTTL is custom maximum TTL for cached DNS responses.
CacheMaxTTL *uint32 `json:"cache_ttl_max"`
// CacheOptimistic defines if expired entries should be served.
CacheOptimistic *bool `json:"cache_optimistic"`
// ResolveClients defines if clients IPs should be resolved into hostnames.
ResolveClients *bool `json:"resolve_clients"`
// UsePrivateRDNS defines if privates DNS resolvers should be used.
UsePrivateRDNS *bool `json:"use_private_ptr_resolvers"`
// LocalPTRUpstreams is the list of local private DNS resolvers.
LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"`
// BlockingIPv4 is custom IPv4 address for blocked A requests.
BlockingIPv4 net.IP `json:"blocking_ipv4"`
// BlockingIPv6 is custom IPv6 address for blocked AAAA requests.
BlockingIPv6 net.IP `json:"blocking_ipv6"`
// EDNSCSCustomIP is custom IP for EDNS Client Subnet.
EDNSCSCustomIP netip.Addr `json:"edns_cs_custom_ip"`
// DefaultLocalPTRUpstreams is used to pass the addresses from
// systemResolvers to the front-end. It's not a pointer to the slice since
// there is no need to omit it while decoding from JSON.
DefaultLocalPTRUpstreams []string `json:"default_local_ptr_upstreams,omitempty"`
}
func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
@@ -57,7 +109,11 @@ func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
blockingIPv4 := s.conf.BlockingIPv4
blockingIPv6 := s.conf.BlockingIPv6
ratelimit := s.conf.Ratelimit
customIP := s.conf.EDNSClientSubnet.CustomIP
enableEDNSClientSubnet := s.conf.EDNSClientSubnet.Enabled
useCustom := s.conf.EDNSClientSubnet.UseCustom
enableDNSSEC := s.conf.EnableDNSSEC
aaaaDisabled := s.conf.AAAADisabled
cacheSize := s.conf.CacheSize
@@ -74,46 +130,40 @@ func (s *Server) getDNSConfig() (c *jsonDNSConfig) {
upstreamMode = "parallel"
}
return &jsonDNSConfig{
Upstreams: &upstreams,
UpstreamsFile: &upstreamFile,
Bootstraps: &bootstraps,
ProtectionEnabled: &protectionEnabled,
BlockingMode: &blockingMode,
BlockingIPv4: blockingIPv4,
BlockingIPv6: blockingIPv6,
RateLimit: &ratelimit,
EDNSCSEnabled: &enableEDNSClientSubnet,
DNSSECEnabled: &enableDNSSEC,
DisableIPv6: &aaaaDisabled,
CacheSize: &cacheSize,
CacheMinTTL: &cacheMinTTL,
CacheMaxTTL: &cacheMaxTTL,
CacheOptimistic: &cacheOptimistic,
UpstreamMode: &upstreamMode,
ResolveClients: &resolveClients,
UsePrivateRDNS: &usePrivateRDNS,
LocalPTRUpstreams: &localPTRUpstreams,
}
}
func (s *Server) handleGetConfig(w http.ResponseWriter, r *http.Request) {
defLocalPTRUps, err := s.filterOurDNSAddrs(s.sysResolvers.Get())
if err != nil {
log.Debug("getting dns configuration: %s", err)
}
resp := struct {
jsonDNSConfig
// DefautLocalPTRUpstreams is used to pass the addresses from
// systemResolvers to the front-end. It's not a pointer to the slice
// since there is no need to omit it while decoding from JSON.
DefautLocalPTRUpstreams []string `json:"default_local_ptr_upstreams,omitempty"`
}{
jsonDNSConfig: *s.getDNSConfig(),
DefautLocalPTRUpstreams: defLocalPTRUps,
return &jsonDNSConfig{
Upstreams: &upstreams,
UpstreamsFile: &upstreamFile,
Bootstraps: &bootstraps,
ProtectionEnabled: &protectionEnabled,
BlockingMode: &blockingMode,
BlockingIPv4: blockingIPv4,
BlockingIPv6: blockingIPv6,
RateLimit: &ratelimit,
EDNSCSCustomIP: customIP,
EDNSCSEnabled: &enableEDNSClientSubnet,
EDNSCSUseCustom: &useCustom,
DNSSECEnabled: &enableDNSSEC,
DisableIPv6: &aaaaDisabled,
CacheSize: &cacheSize,
CacheMinTTL: &cacheMinTTL,
CacheMaxTTL: &cacheMaxTTL,
CacheOptimistic: &cacheOptimistic,
UpstreamMode: &upstreamMode,
ResolveClients: &resolveClients,
UsePrivateRDNS: &usePrivateRDNS,
LocalPTRUpstreams: &localPTRUpstreams,
DefaultLocalPTRUpstreams: defLocalPTRUps,
}
}
// handleGetConfig handles requests to the GET /control/dns_info endpoint.
func (s *Server) handleGetConfig(w http.ResponseWriter, r *http.Request) {
resp := s.getDNSConfig()
_ = aghhttp.WriteJSONResponse(w, r, resp)
}
@@ -204,6 +254,7 @@ func (req *jsonDNSConfig) checkCacheTTL() bool {
return min <= max
}
// handleSetConfig handles requests to the POST /control/dns_config endpoint.
func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
req := &jsonDNSConfig{}
err := json.NewDecoder(r.Body).Decode(req)
@@ -231,8 +282,8 @@ func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
}
}
// setConfigRestartable sets the server parameters. shouldRestart is true if
// the server should be restarted to apply changes.
// setConfig sets the server parameters. shouldRestart is true if the server
// should be restarted to apply changes.
func (s *Server) setConfig(dc *jsonDNSConfig) (shouldRestart bool) {
s.serverLock.Lock()
defer s.serverLock.Unlock()
@@ -250,6 +301,10 @@ func (s *Server) setConfig(dc *jsonDNSConfig) (shouldRestart bool) {
s.conf.FastestAddr = *dc.UpstreamMode == "fastest_addr"
}
if dc.EDNSCSUseCustom != nil && *dc.EDNSCSUseCustom {
s.conf.EDNSClientSubnet.CustomIP = dc.EDNSCSCustomIP
}
setIfNotNil(&s.conf.ProtectionEnabled, dc.ProtectionEnabled)
setIfNotNil(&s.conf.EnableDNSSEC, dc.DNSSECEnabled)
setIfNotNil(&s.conf.AAAADisabled, dc.DisableIPv6)
@@ -281,6 +336,7 @@ func (s *Server) setConfigRestartable(dc *jsonDNSConfig) (shouldRestart bool) {
setIfNotNil(&s.conf.UpstreamDNSFileName, dc.UpstreamsFile),
setIfNotNil(&s.conf.BootstrapDNS, dc.Bootstraps),
setIfNotNil(&s.conf.EDNSClientSubnet.Enabled, dc.EDNSCSEnabled),
setIfNotNil(&s.conf.EDNSClientSubnet.UseCustom, dc.EDNSCSUseCustom),
setIfNotNil(&s.conf.CacheSize, dc.CacheSize),
setIfNotNil(&s.conf.CacheMinTTL, dc.CacheMinTTL),
setIfNotNil(&s.conf.CacheMaxTTL, dc.CacheMaxTTL),