diff --git a/package.json b/package.json index 9d4fe70..1068b0e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.10.0-unstable10", + "version": "0.10.0-unstable11", "description": "", "main": "test-server.js", "bugs": { diff --git a/src/constellation/DNS.go b/src/constellation/DNS.go index 2d85f7b..9764c74 100644 --- a/src/constellation/DNS.go +++ b/src/constellation/DNS.go @@ -11,7 +11,7 @@ import ( "github.com/azukaar/cosmos-server/src/utils" ) -var DNSBlacklist = []string{} +var DNSBlacklist = map[string]bool{} func externalLookup(client *dns.Client, r *dns.Msg, serverAddr string) (*dns.Msg, time.Duration, error) { rCopy := r.Copy() // Create a copy of the request to forward @@ -88,6 +88,22 @@ func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) { } } + if !customHandled { + customDNSEntries := config.ConstellationConfig.CustomDNSEntries + + // Overwrite local hostnames with custom entries + for _, q := range r.Question { + for hostname, ip := range customDNSEntries { + if strings.HasSuffix(q.Name, hostname + ".") && q.Qtype == dns.TypeA { + utils.Debug("DNS Overwrite " + hostname + " with " + ip) + rr, _ := dns.NewRR(q.Name + " A " + ip) + m.Answer = append(m.Answer, rr) + customHandled = true + } + } + } + } + if !specialQuery { // Overwrite local hostnames with Constellation IP for _, q := range r.Question { @@ -101,37 +117,19 @@ func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) { } } } - - if !customHandled { - // map[string]string customEntries - customDNSEntries := config.ConstellationConfig.CustomDNSEntries - - // Overwrite local hostnames with custom entries - for _, q := range r.Question { - for hostname, ip := range customDNSEntries { - if strings.HasSuffix(q.Name, hostname + ".") && q.Qtype == dns.TypeA { - utils.Debug("DNS Overwrite " + hostname + " with " + ip) - rr, _ := dns.NewRR(q.Name + " A " + ip) - m.Answer = append(m.Answer, rr) - customHandled = true - } - } - } - } if !customHandled { // Block blacklisted domains for _, q := range r.Question { - for _, hostname := range DNSBlacklist { - if strings.HasSuffix(q.Name, hostname + ".") { - if q.Qtype == dns.TypeA { - utils.Debug("DNS Block " + hostname) - rr, _ := dns.NewRR(q.Name + " A 0.0.0.0") - m.Answer = append(m.Answer, rr) - } - - customHandled = true + noDot := strings.TrimSuffix(q.Name, ".") + if DNSBlacklist[noDot] { + if q.Qtype == dns.TypeA { + utils.Debug("DNS Block " + noDot) + rr, _ := dns.NewRR(q.Name + " A 0.0.0.0") + m.Answer = append(m.Answer, rr) } + + customHandled = true } } } @@ -155,6 +153,32 @@ func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) { w.WriteMsg(m) } +func isDomain(domain string) bool { + // contains . and at least a letter and no special characters invalid in a domain + if strings.Contains(domain, ".") && strings.ContainsAny(domain, "abcdefghijklmnopqrstuvwxyz") && !strings.ContainsAny(domain, " !@#$%^&*()+=[]{}\\|;:'\",/<>?") { + return true + } + return false +} + +func loadRawBlockList(DNSBlacklistRaw string) { + DNSBlacklistArray := strings.Split(string(DNSBlacklistRaw), "\n") + for _, domain := range DNSBlacklistArray { + if domain != "" && !strings.HasPrefix(domain, "#") { + splitDomain := strings.Split(domain, " ") + if len(splitDomain) == 1 && isDomain(splitDomain[0]) { + DNSBlacklist[splitDomain[0]] = true + } else if len(splitDomain) == 2 { + if isDomain(splitDomain[0]) { + DNSBlacklist[splitDomain[0]] = true + } else if isDomain(splitDomain[1]) { + DNSBlacklist[splitDomain[1]] = true + } + } + } + } +} + func InitDNS() { config := utils.GetMainConfig() DNSPort := config.ConstellationConfig.DNSPort @@ -165,7 +189,7 @@ func InitDNS() { } if DNSBlockBlacklist { - DNSBlacklist = []string{} + DNSBlacklist = map[string]bool{} blacklistPath := utils.CONFIGFOLDER + "dns-blacklist.txt" utils.Log("Loading DNS blacklist from " + blacklistPath) @@ -176,12 +200,24 @@ func InitDNS() { if err != nil { utils.Error("Failed to load DNS blacklist", err) } else { - DNSBlacklist = strings.Split(string(DNSBlacklistRaw), "\n") - utils.Log("Loaded " + strconv.Itoa(len(DNSBlacklist)) + " domains to block") + loadRawBlockList(string(DNSBlacklistRaw)) } } else { utils.Log("No DNS blacklist found") } + + // download additional blocklists from config.DNSAdditionalBlocklists []string + for _, url := range config.ConstellationConfig.DNSAdditionalBlocklists { + utils.Log("Downloading DNS blacklist from " + url) + DNSBlacklistRaw, err := utils.DownloadFile(url) + if err != nil { + utils.Error("Failed to download DNS blacklist", err) + } else { + loadRawBlockList(DNSBlacklistRaw) + } + } + + utils.Log("Loaded " + strconv.Itoa(len(DNSBlacklist)) + " domains") } if(config.ConstellationConfig.DNS) { diff --git a/src/utils/types.go b/src/utils/types.go index f8aab17..ea8646c 100644 --- a/src/utils/types.go +++ b/src/utils/types.go @@ -214,6 +214,7 @@ type ConstellationConfig struct { DNSPort string DNSFallback string DNSBlockBlacklist bool + DNSAdditionalBlocklists []string CustomDNSEntries map[string]string NebulaConfig NebulaConfig } diff --git a/src/utils/utils.go b/src/utils/utils.go index 6e7ed5a..f131fa2 100644 --- a/src/utils/utils.go +++ b/src/utils/utils.go @@ -66,6 +66,12 @@ var DefaultConfig = Config{ Enabled: false, DNS: true, DNSFallback: "8.8.8.8:53", + DNSAdditionalBlocklists: []string{ + "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt", + "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt", + "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts", + "https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-only/hosts", + }, }, } @@ -550,6 +556,21 @@ func GetNetworkUsage() NetworkStatus { return NetworkStatus{} } +func DownloadFile(url string) (string, error) { + resp, err := http.Get(url) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(body), nil +} + func GetClientIP(req *http.Request) string { /*ip := req.Header.Get("X-Forwarded-For") if ip == "" {