diff --git a/AGHTechDoc.md b/AGHTechDoc.md index e5e582ec..50ad9d90 100644 --- a/AGHTechDoc.md +++ b/AGHTechDoc.md @@ -986,6 +986,7 @@ Response: { "upstream_dns": ["tls://...", ...], + "upstream_dns_file": "", "bootstrap_dns": ["1.2.3.4", ...], "protection_enabled": true | false, @@ -1011,6 +1012,7 @@ Request: { "upstream_dns": ["tls://...", ...], + "upstream_dns_file": "", "bootstrap_dns": ["1.2.3.4", ...], "protection_enabled": true | false, diff --git a/dnsforward/config.go b/dnsforward/config.go index 69af11eb..db224ea2 100644 --- a/dnsforward/config.go +++ b/dnsforward/config.go @@ -5,6 +5,7 @@ import ( "crypto/x509" "errors" "fmt" + "io/ioutil" "net" "net/http" "sort" @@ -13,6 +14,7 @@ import ( "github.com/joomcode/errorx" "github.com/AdguardTeam/AdGuardHome/dnsfilter" + "github.com/AdguardTeam/AdGuardHome/util" "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" ) @@ -55,10 +57,11 @@ type FilteringConfig struct { // Upstream DNS servers configuration // -- - UpstreamDNS []string `yaml:"upstream_dns"` - BootstrapDNS []string `yaml:"bootstrap_dns"` // a list of bootstrap DNS for DoH and DoT (plain DNS only) - AllServers bool `yaml:"all_servers"` // if true, parallel queries to all configured upstream servers are enabled - FastestAddr bool `yaml:"fastest_addr"` // use Fastest Address algorithm + UpstreamDNS []string `yaml:"upstream_dns"` + UpstreamDNSFileName string `yaml:"upstream_dns_file"` + BootstrapDNS []string `yaml:"bootstrap_dns"` // a list of bootstrap DNS for DoH and DoT (plain DNS only) + AllServers bool `yaml:"all_servers"` // if true, parallel queries to all configured upstream servers are enabled + FastestAddr bool `yaml:"fastest_addr"` // use Fastest Address algorithm // Access settings // -- @@ -215,7 +218,22 @@ func (s *Server) initDefaultSettings() { // prepareUpstreamSettings - prepares upstream DNS server settings func (s *Server) prepareUpstreamSettings() error { - upstreamConfig, err := proxy.ParseUpstreamsConfig(s.conf.UpstreamDNS, s.conf.BootstrapDNS, DefaultTimeout) + var upstreams []string + if s.conf.UpstreamDNSFileName != "" { + data, err := ioutil.ReadFile(s.conf.UpstreamDNSFileName) + if err != nil { + return err + } + d := string(data) + for len(d) != 0 { + s := util.SplitNext(&d, '\n') + upstreams = append(upstreams, s) + } + log.Debug("DNS: using %d upstream servers from file %s", len(upstreams), s.conf.UpstreamDNSFileName) + } else { + upstreams = s.conf.UpstreamDNS + } + upstreamConfig, err := proxy.ParseUpstreamsConfig(upstreams, s.conf.BootstrapDNS, DefaultTimeout) if err != nil { return fmt.Errorf("DNS: proxy.ParseUpstreamsConfig: %s", err) } diff --git a/dnsforward/dnsforward_http.go b/dnsforward/dnsforward_http.go index 63e82d95..286e9b81 100644 --- a/dnsforward/dnsforward_http.go +++ b/dnsforward/dnsforward_http.go @@ -22,8 +22,9 @@ func httpError(r *http.Request, w http.ResponseWriter, code int, format string, } type dnsConfigJSON struct { - Upstreams []string `json:"upstream_dns"` - Bootstraps []string `json:"bootstrap_dns"` + 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"` @@ -43,6 +44,7 @@ func (s *Server) handleGetConfig(w http.ResponseWriter, r *http.Request) { resp := dnsConfigJSON{} s.RLock() resp.Upstreams = stringArrayDup(s.conf.UpstreamDNS) + resp.UpstreamsFile = s.conf.UpstreamDNSFileName resp.Bootstraps = stringArrayDup(s.conf.BootstrapDNS) resp.ProtectionEnabled = s.conf.ProtectionEnabled @@ -157,6 +159,11 @@ func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) { restart = true } + if js.Exists("upstream_dns_file") { + s.conf.UpstreamDNSFileName = req.UpstreamsFile + restart = true + } + if js.Exists("bootstrap_dns") { s.conf.BootstrapDNS = req.Bootstraps restart = true diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 57d63c70..4b5da50e 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -997,6 +997,8 @@ components: example: - tls://1.1.1.1 - tls://1.0.0.1 + upstream_dns_file: + type: string protection_enabled: type: boolean dhcp_available: