diff --git a/CHANGELOG.md b/CHANGELOG.md index ddad8fa8..12c69286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,12 @@ and this project adheres to ## [v0.108.0] - 2022-12-01 (APPROX.) --> +### Added + +- The new optional `dns.ipset_file` property in the configuration file. It + allows loading the `ipset` list from a file, just like `dns.upstream_dns_file` + does for upstream servers ([#4686]). + ### Changed - The minimum DHCP message size is reassigned back to BOOTP's constraint of 300 @@ -26,6 +32,7 @@ and this project adheres to operation have been disabled ([#2993]). [#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993 +[#4686]: https://github.com/AdguardTeam/AdGuardHome/issues/4686 [#4904]: https://github.com/AdguardTeam/AdGuardHome/issues/4904 diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go index 2b2ba2e8..747767c4 100644 --- a/internal/dnsforward/config.go +++ b/internal/dnsforward/config.go @@ -128,9 +128,14 @@ type FilteringConfig struct { // IpsetList is the ipset configuration that allows AdGuard Home to add // IP addresses of the specified domain names to an ipset list. Syntax: // - // DOMAIN[,DOMAIN].../IPSET_NAME + // DOMAIN[,DOMAIN].../IPSET_NAME // + // This field is ignored if [IpsetListFileName] is set. IpsetList []string `yaml:"ipset"` + + // IpsetListFileName, if set, points to the file with ipset configuration. + // The format is the same as in [IpsetList]. + IpsetListFileName string `yaml:"ipset_file"` } // TLSConfig is the TLS configuration for HTTPS, DNS-over-HTTPS, and DNS-over-TLS @@ -400,6 +405,26 @@ func setProxyUpstreamMode( } } +// prepareIpsetListSettings reads and prepares the ipset configuration either +// from a file or from the data in the configuration file. +func (s *Server) prepareIpsetListSettings() (err error) { + fn := s.conf.IpsetListFileName + if fn == "" { + return s.ipset.init(s.conf.IpsetList) + } + + data, err := os.ReadFile(fn) + if err != nil { + return err + } + + ipsets := stringutil.SplitTrimmed(string(data), "\n") + + log.Debug("dns: using %d ipset rules from file %q", len(ipsets), fn) + + return s.ipset.init(ipsets) +} + // prepareTLS - prepares TLS configuration for the DNS proxy func (s *Server) prepareTLS(proxyConfig *proxy.Config) error { if len(s.conf.CertificateChainData) == 0 || len(s.conf.PrivateKeyData) == 0 { diff --git a/internal/dnsforward/dnsforward.go b/internal/dnsforward/dnsforward.go index 33be1e83..4af874b4 100644 --- a/internal/dnsforward/dnsforward.go +++ b/internal/dnsforward/dnsforward.go @@ -446,10 +446,10 @@ func (s *Server) Prepare(conf *ServerConfig) (err error) { s.initDefaultSettings() - err = s.ipset.init(s.conf.IpsetList) + err = s.prepareIpsetListSettings() if err != nil { // Don't wrap the error, because it's informative enough as is. - return err + return fmt.Errorf("preparing ipset settings: %w", err) } err = s.prepareUpstreamSettings()