diff --git a/blackhole.go b/blackhole.go new file mode 100644 index 0000000..afa9935 --- /dev/null +++ b/blackhole.go @@ -0,0 +1,15 @@ +package pancheri + +import "slices" + +type BlackholeFile struct { + DenyDomains []string `yaml:"deny_domains"` +} + +type Blackholer struct { + DenyDomains []string +} + +func (b *Blackholer) ShouldBlock(domain string) bool { + return slices.Contains(b.DenyDomains, domain) +} diff --git a/cmd/pancheri-compile/main.go b/cmd/pancheri-compile/main.go new file mode 100644 index 0000000..c0932b4 --- /dev/null +++ b/cmd/pancheri-compile/main.go @@ -0,0 +1,81 @@ +package main + +import ( + "flag" + "fmt" + "git.e3t.cc/e3team/pancheri" + "gopkg.in/yaml.v2" + "io" + "os" + "strings" + "time" +) + +func main() { + hostsPath := flag.String("hostsfile", "", "Hosts file to convert to a dnsbl") + voidIp := flag.String("voidip", "0.0.0.0", "IP that this hosts file uses as a void IP") + printUsage := flag.Bool("help", false, "Print command line usage") + + flag.Parse() + + if *printUsage { + flag.Usage() + os.Exit(0) + } + + f, err := os.Open(*hostsPath) + if err != nil { + fmt.Printf("error opening hosts file: %s", err) + os.Exit(1) + } + + buf := new(strings.Builder) + _, err = io.Copy(buf, f) + if err != nil { + fmt.Printf("error reading hosts file: %s", err) + os.Exit(1) + } + + err = f.Close() + if err != nil { + fmt.Printf("error closing hosts file: %s", err) + os.Exit(1) + } + + split := strings.Split(buf.String(), "\n") + + blackhole := pancheri.BlackholeFile{ + DenyDomains: *new([]string), + } + + for _, line := range split { + if strings.HasPrefix(line, "#") { + continue + } + if line == "" { + continue + } + if !strings.HasPrefix(line, *voidIp) { + continue + } + + lineSplit := strings.Split(line, " ") + + if strings.Join(lineSplit[1:], " ") == *voidIp { + continue + } + + blackhole.DenyDomains = append(blackhole.DenyDomains, strings.Join(lineSplit[1:], " ")) + } + + marshaled, err := yaml.Marshal(blackhole) + + if err != nil { + fmt.Printf("error saving blacklist file: %s", err) + os.Exit(1) + } + + fmt.Printf("# Compiled by pancheri-compile at %s\n", time.Now().Format(time.RFC3339)) + fmt.Printf("# %d hosts loaded from %s\n", len(blackhole.DenyDomains), *hostsPath) + fmt.Printf("%s", marshaled) +} diff --git a/cmd/pancheri/main.go b/cmd/pancheri/main.go index 0e03f48..66b214f 100644 --- a/cmd/pancheri/main.go +++ b/cmd/pancheri/main.go @@ -6,6 +6,7 @@ import ( "git.e3t.cc/e3team/pancheri" "github.com/miekg/dns" "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" "os" ) @@ -65,6 +66,51 @@ func main() { r = pancheri.NewResolver(c.Resolver.Upstream) } + var b *pancheri.Blackholer + + if c.Blackhole.Enable { + logrus.WithFields(logrus.Fields{ + "denyfiles": len(c.Blackhole.BlockLists), + }).Info("enabling blackholer") + + b = &pancheri.Blackholer{ + DenyDomains: *new([]string), + } + + for _, file := range c.Blackhole.BlockLists { + logrus.WithFields(logrus.Fields{ + "file": file, + }).Info("loading blocklist") + + f, err := os.Open(file) + if err != nil { + logrus.Errorf("error loading blocklist file: %s", err) + } + + var cfg pancheri.BlackholeFile + decoder := yaml.NewDecoder(f) + + err = decoder.Decode(&cfg) + if err != nil { + logrus.Errorf("error decoding blocklist file: %s", err) + } + + err = f.Close() + if err != nil { + logrus.Errorf("error closing blocklist file: %s", err) + } + + b.DenyDomains = append(b.DenyDomains, cfg.DenyDomains...) + logrus.WithFields(logrus.Fields{ + "file": file, + }).Infof("loaded %d hosts", len(cfg.DenyDomains)) + } + + logrus.WithFields(logrus.Fields{ + "hosts": len(b.DenyDomains), + }).Info("blackhole enabled") + } + handler := pancheri.Handler{ C: c, R: r, diff --git a/config.go b/config.go index b268a73..e6ed735 100644 --- a/config.go +++ b/config.go @@ -22,6 +22,10 @@ type Config struct { Zone struct { LoadFiles []string `yaml:"load_files"` } `yaml:"zone"` + Blackhole struct { + Enable bool `yaml:"enable"` + BlockLists []string `yaml:"block_lists"` + } } func LoadConfig(path string) (*Config, error) { diff --git a/handler.go b/handler.go index c2a688b..021ccba 100644 --- a/handler.go +++ b/handler.go @@ -10,6 +10,7 @@ type Handler struct { C *Config R *Resolver A *Authority + B *Blackholer } func (h *Handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {