From feabc21864dd8d08b2ceed359169f542ac866e92 Mon Sep 17 00:00:00 2001 From: Eugene Bujak Date: Wed, 28 Nov 2018 16:45:30 +0300 Subject: [PATCH] Unplug coreDNS and plug dnsforward library. --- config.go | 97 +---------------------------------- coredns.go | 145 ++++++++++++----------------------------------------- go.mod | 1 + go.sum | 2 + 4 files changed, 38 insertions(+), 207 deletions(-) diff --git a/config.go b/config.go index 59cff6bc..5d114538 100644 --- a/config.go +++ b/config.go @@ -1,14 +1,11 @@ package main import ( - "bytes" "io/ioutil" "log" "os" "path/filepath" - "regexp" "sync" - "text/template" "time" "gopkg.in/yaml.v2" @@ -56,7 +53,7 @@ type coreDNSConfig struct { SafeSearchEnabled bool `yaml:"safesearch_enabled"` ParentalEnabled bool `yaml:"parental_enabled"` ParentalSensitivity int `yaml:"parental_sensitivity"` - BlockedResponseTTL int `yaml:"blocked_response_ttl"` + BlockedResponseTTL uint32 `yaml:"blocked_response_ttl"` QueryLogEnabled bool `yaml:"querylog_enabled"` Ratelimit int `yaml:"ratelimit"` RefuseAny bool `yaml:"refuse_any"` @@ -188,98 +185,8 @@ func (c *configuration) write() error { return nil } -// -------------- -// coredns config -// -------------- -func writeCoreDNSConfig() error { - coreFile := filepath.Join(config.ourBinaryDir, config.CoreDNS.coreFile) - log.Printf("Writing DNS config: %s", coreFile) - configText, err := generateCoreDNSConfigText() - if err != nil { - log.Printf("Couldn't generate DNS config: %s", err) - return err - } - err = safeWriteFile(coreFile, []byte(configText)) - if err != nil { - log.Printf("Couldn't save DNS config: %s", err) - return err - } - return nil -} - func writeAllConfigs() error { - err := config.write() - if err != nil { - log.Printf("Couldn't write our config: %s", err) - return err - } - err = writeCoreDNSConfig() - if err != nil { - log.Printf("Couldn't write DNS config: %s", err) - return err - } - return nil -} - -const coreDNSConfigTemplate = `.:{{.Port}} { - {{if .ProtectionEnabled}}dnsfilter { - {{if .SafeBrowsingEnabled}}safebrowsing{{end}} - {{if .ParentalEnabled}}parental {{.ParentalSensitivity}}{{end}} - {{if .SafeSearchEnabled}}safesearch{{end}} - {{if .QueryLogEnabled}}querylog{{end}} - blocked_ttl {{.BlockedResponseTTL}} - {{if .FilteringEnabled}}{{range .Filters}}{{if and .Enabled .Contents}} - filter {{.ID}} "{{.Path}}" - {{end}}{{end}}{{end}} - }{{end}} - {{.Pprof}} - {{if .RefuseAny}}refuseany{{end}} - {{if gt .Ratelimit 0}}ratelimit {{.Ratelimit}}{{end}} - hosts { - fallthrough - } - {{if .UpstreamDNS}}upstream {{range .UpstreamDNS}}{{.}} {{end}} { bootstrap {{.BootstrapDNS}} }{{end}} - {{.Cache}} - {{.Prometheus}} -} -` - -var removeEmptyLines = regexp.MustCompile("([\t ]*\n)+") - -// generate CoreDNS config text -func generateCoreDNSConfigText() (string, error) { - t, err := template.New("config").Parse(coreDNSConfigTemplate) - if err != nil { - log.Printf("Couldn't generate DNS config: %s", err) - return "", err - } - - var configBytes bytes.Buffer - temporaryConfig := config.CoreDNS - - // generate temporary filter list, needed to put userfilter in coredns config - filters := []filter{} - - // first of all, append the user filter - userFilter := userFilter() - - filters = append(filters, userFilter) - - // then go through other filters - filters = append(filters, config.Filters...) - temporaryConfig.Filters = filters - - // run the template - err = t.Execute(&configBytes, &temporaryConfig) - if err != nil { - log.Printf("Couldn't generate DNS config: %s", err) - return "", err - } - configText := configBytes.String() - - // remove empty lines from generated config - configText = removeEmptyLines.ReplaceAllString(configText, "\n") - return configText, nil + return config.write() } // Set the next filter ID to max(filter.ID) + 1 diff --git a/coredns.go b/coredns.go index 376e6210..df91b1a6 100644 --- a/coredns.go +++ b/coredns.go @@ -3,130 +3,51 @@ package main import ( "fmt" "log" - "os" - "path/filepath" - "sync" // Include all plugins. + "net" - _ "github.com/AdguardTeam/AdGuardHome/coredns_plugin" - _ "github.com/AdguardTeam/AdGuardHome/coredns_plugin/ratelimit" - _ "github.com/AdguardTeam/AdGuardHome/coredns_plugin/refuseany" - _ "github.com/AdguardTeam/AdGuardHome/upstream" - "github.com/coredns/coredns/core/dnsserver" - "github.com/coredns/coredns/coremain" - _ "github.com/coredns/coredns/plugin/auto" - _ "github.com/coredns/coredns/plugin/autopath" - _ "github.com/coredns/coredns/plugin/bind" - _ "github.com/coredns/coredns/plugin/cache" - _ "github.com/coredns/coredns/plugin/chaos" - _ "github.com/coredns/coredns/plugin/debug" - _ "github.com/coredns/coredns/plugin/dnssec" - _ "github.com/coredns/coredns/plugin/dnstap" - _ "github.com/coredns/coredns/plugin/erratic" - _ "github.com/coredns/coredns/plugin/errors" - _ "github.com/coredns/coredns/plugin/file" - _ "github.com/coredns/coredns/plugin/forward" - _ "github.com/coredns/coredns/plugin/health" - _ "github.com/coredns/coredns/plugin/hosts" - _ "github.com/coredns/coredns/plugin/loadbalance" - _ "github.com/coredns/coredns/plugin/log" - _ "github.com/coredns/coredns/plugin/loop" - _ "github.com/coredns/coredns/plugin/metadata" - _ "github.com/coredns/coredns/plugin/metrics" - _ "github.com/coredns/coredns/plugin/nsid" - _ "github.com/coredns/coredns/plugin/pprof" - _ "github.com/coredns/coredns/plugin/proxy" - _ "github.com/coredns/coredns/plugin/reload" - _ "github.com/coredns/coredns/plugin/rewrite" - _ "github.com/coredns/coredns/plugin/root" - _ "github.com/coredns/coredns/plugin/secondary" - _ "github.com/coredns/coredns/plugin/template" - _ "github.com/coredns/coredns/plugin/tls" - _ "github.com/coredns/coredns/plugin/whoami" - _ "github.com/mholt/caddy/onevent" + "github.com/AdguardTeam/AdGuardHome/dnsforward" + "github.com/joomcode/errorx" ) -// Directives are registered in the order they should be -// executed. -// -// Ordering is VERY important. Every plugin will -// feel the effects of all other plugin below -// (after) them during a request, but they must not -// care what plugin above them are doing. - -var directives = []string{ - "metadata", - "tls", - "reload", - "nsid", - "root", - "bind", - "debug", - "health", - "pprof", - "prometheus", - "errors", - "log", - "refuseany", - "ratelimit", - "dnsfilter", - "dnstap", - "chaos", - "loadbalance", - "cache", - "rewrite", - "dnssec", - "autopath", - "template", - "hosts", - "file", - "auto", - "secondary", - "loop", - "forward", - "proxy", - "upstream", - "erratic", - "whoami", - "on", -} - -func init() { - dnsserver.Directives = directives -} - -var ( - isCoreDNSRunningLock sync.Mutex - isCoreDNSRunning = false -) +var dnsServer = dnsforward.Server{} func isRunning() bool { - isCoreDNSRunningLock.Lock() - value := isCoreDNSRunning - isCoreDNSRunningLock.Unlock() - return value + return dnsServer.IsRunning() } func startDNSServer() error { - isCoreDNSRunningLock.Lock() - if isCoreDNSRunning { - isCoreDNSRunningLock.Unlock() + if isRunning() { return fmt.Errorf("Unable to start coreDNS: Already running") } - isCoreDNSRunning = true - isCoreDNSRunningLock.Unlock() - configpath := filepath.Join(config.ourBinaryDir, config.CoreDNS.coreFile) - os.Args = os.Args[:1] - os.Args = append(os.Args, "-conf") - os.Args = append(os.Args, configpath) - - err := writeCoreDNSConfig() - if err != nil { - errortext := fmt.Errorf("Unable to write coredns config: %s", err) - log.Println(errortext) - return errortext + filters := []dnsforward.Filter{} + for _, filter := range config.Filters { + filters = append(filters, dnsforward.Filter{ + ID: filter.ID, + Rules: filter.Rules, + }) + } + + newconfig := dnsforward.ServerConfig{ + UDPListenAddr: &net.UDPAddr{Port: config.CoreDNS.Port}, + BlockedTTL: config.CoreDNS.BlockedResponseTTL, + Filters: filters, + } + + for _, u := range config.CoreDNS.UpstreamDNS { + upstream, err := dnsforward.GetUpstream(u) + if err != nil { + log.Printf("Couldn't get upstream: %s", err) + // continue, just ignore the upstream + continue + } + newconfig.Upstreams = append(newconfig.Upstreams, upstream) + } + + err := dnsServer.Start(&newconfig) + if err != nil { + return errorx.Decorate(err, "Couldn't start forwarding DNS server") } - go coremain.Run() return nil } diff --git a/go.mod b/go.mod index dae96b71..1b8d78e6 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/gobuffalo/packr v1.19.0 github.com/google/uuid v1.0.0 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect + github.com/joomcode/errorx v0.1.0 github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mholt/caddy v0.11.0 github.com/miekg/dns v1.0.15 diff --git a/go.sum b/go.sum index 06efaa9e..4ecb93be 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joomcode/errorx v0.1.0 h1:QmJMiI1DE1UFje2aI1ZWO/VMT5a32qBoXUclGOt8vsc= +github.com/joomcode/errorx v0.1.0/go.mod h1:kgco15ekB6cs+4Xjzo7SPeXzx38PbJzBwbnu9qfVNHQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4 h1:Mlji5gkcpzkqTROyE4ZxZ8hN7osunMb2RuGVrbvMvCc= github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=