Add DNS filtering with dnsmasq address=/ directives for wildcard blocking

Adds Pi-hole-style DNS filtering using dnsmasq's native address=/ directives,
which block domains and all subdomains. Users subscribe to blocklists by URL
or upload files, with suggested lists from Hagezi, Steven Black, and OISD.
Background runner refreshes lists on a configurable interval (default 24h).
This commit is contained in:
2026-07-12 12:44:19 +00:00
parent 134c01fe5e
commit 518cdbbce5
12 changed files with 2009 additions and 2 deletions

View File

@@ -26,7 +26,8 @@ type DNSEntry struct {
// ConfigGenerator handles dnsmasq configuration generation
type ConfigGenerator struct {
configPath string
configPath string
filterConfPath string // path to addn-hosts file for DNS filtering
}
// NewConfigGenerator creates a new dnsmasq config generator
@@ -44,6 +45,12 @@ func (g *ConfigGenerator) GetConfigPath() string {
return g.configPath
}
// SetFilterConfPath sets the path to an additional hosts file for DNS filtering.
// When set, the generated config includes an addn-hosts= directive.
func (g *ConfigGenerator) SetFilterConfPath(path string) {
g.filterConfPath = path
}
// Generate creates a dnsmasq configuration from registered domain entries.
// It auto-detects the Wild Central server's IP address for the listen directive.
func (g *ConfigGenerator) Generate(cfg *config.State, entries []DNSEntry) string {
@@ -94,10 +101,16 @@ log-queries
log-dhcp
`
return fmt.Sprintf(template,
result := fmt.Sprintf(template,
dnsIP,
resolution_section,
)
if g.filterConfPath != "" {
result += fmt.Sprintf("\n# DNS Filtering\nconf-file=%s\n", g.filterConfPath)
}
return result
}
// RestartService reloads the dnsmasq service (SIGHUP — no downtime).
@@ -270,6 +283,10 @@ log-dhcp
}
}
if g.filterConfPath != "" {
fmt.Fprintf(&sb, "\n# DNS Filtering\nconf-file=%s\n", g.filterConfPath)
}
return sb.String()
}