Yann Stepienik 1 год назад
Родитель
Сommit
9206dbade8
7 измененных файлов с 222 добавлено и 4 удалено
  1. 1 0
      .gitignore
  2. 2 2
      package.json
  3. 196 0
      src/constellation/api_DNS.go
  4. 13 1
      src/constellation/nebula.go
  5. 2 0
      src/index.go
  6. 5 0
      src/utils/types.go
  7. 3 1
      src/utils/utils.go

+ 1 - 0
.gitignore

@@ -13,6 +13,7 @@ LICENCE
 tokens.json
 .vscode
 GeoLite2-Country.mmdb
+dns-blacklist.txt
 zz_test_config
 nebula-arm
 nebula-arm-cert

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "cosmos-server",
-  "version": "0.10.0-unstable7",
+  "version": "0.10.0-unstable8",
   "description": "",
   "main": "test-server.js",
   "bugs": {
@@ -67,7 +67,7 @@
     "build": "sh build.sh",
     "dev": "npm run build && npm run start",
     "dockerdevbuild": "sh build.sh && docker build -f dockerfile.local --tag cosmos-dev .",
-    "dockerdevrun": "docker stop cosmos-dev; docker rm cosmos-dev; docker run --cap-add NET_ADMIN -d -p 7200:443 -p 80:80 -p 443:443 -p 4242:4242 -e DOCKER_HOST=tcp://host.docker.internal:2375 -e COSMOS_MONGODB=$MONGODB -e COSMOS_LOG_LEVEL=DEBUG -v /:/mnt/host  --restart=unless-stopped -h cosmos-dev --name cosmos-dev cosmos-dev",
+    "dockerdevrun": "docker stop cosmos-dev; docker rm cosmos-dev; docker run --cap-add NET_ADMIN -d -p 7200:443 -p 80:80 -p 53:53 -p 443:443 -p 4242:4242 -e DOCKER_HOST=tcp://host.docker.internal:2375 -e COSMOS_MONGODB=$MONGODB -e COSMOS_LOG_LEVEL=DEBUG -v /:/mnt/host  --restart=unless-stopped -h cosmos-dev --name cosmos-dev cosmos-dev",
     "dockerdev": "npm run client-build && npm run dockerdevbuild && npm run dockerdevrun",
     "demo": "vite build --base=/cosmos-ui/ --mode demo",
     "devdemo": "vite --mode demo"

+ 196 - 0
src/constellation/api_DNS.go

@@ -0,0 +1,196 @@
+package constellation
+
+import (
+	"time"
+	"strconv"
+	"strings"
+	"io/ioutil"
+	"fmt"
+
+	"github.com/miekg/dns"
+	"github.com/azukaar/cosmos-server/src/utils" 
+)
+
+var DNSBlacklist = []string{}
+
+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
+	rCopy.Id = dns.Id() // Assign a new ID for the forwarded request
+	
+	// Enable DNSSEC
+	rCopy.SetEdns0(4096, true)
+	rCopy.CheckingDisabled = false
+	rCopy.MsgHdr.AuthenticatedData = true
+
+	return client.Exchange(rCopy, serverAddr)
+}
+
+func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
+	config := utils.GetMainConfig()
+	DNSFallback := config.ConstellationConfig.DNSFallback
+
+	if DNSFallback == "" {
+		DNSFallback = "8.8.8.8:53"
+	}
+
+	m := new(dns.Msg)
+	m.SetReply(r)
+	m.Authoritative = true
+
+	customHandled := false
+
+	// []string hostnames
+	hostnames := utils.GetAllHostnames(false, true)
+	originalHostname := hostnames[0]
+
+	specialQuery := false
+
+	// if lighthouse-cosmos.constellation is the query, return originalHostname's external lookup
+	for i, q := range r.Question {
+		if strings.HasSuffix(q.Name, "lighthouse-cosmos.constellation.") {
+			utils.Debug("DNS Overwrite lighthouse-cosmos.constellation with " + originalHostname)
+			
+			// Create a deep copy of the original request.
+			modifiedRequest := r.Copy()
+			
+			client := new(dns.Client)
+			
+			// Modify only the copied request.
+			modifiedRequest.Question[i].Name = originalHostname + "."
+			
+			externalResponse, time, err := externalLookup(client, modifiedRequest, DNSFallback)
+			if err != nil {
+				utils.Error("Failed to forward query:", err)
+				return
+			}
+			utils.Debug("DNS Forwarded DNS query to "+DNSFallback+" in " + time.String())
+			
+			for _, rr := range externalResponse.Answer {
+				if aRecord, ok := rr.(*dns.A); ok {
+						// 2. Replace the hostname with "lighthouse-cosmos.constellation".
+						modifiedString := fmt.Sprintf("lighthouse-cosmos.constellation. A %s", aRecord.A.String())
+		
+						// 3. Convert the string back into a dns.RR.
+						newRR, err := dns.NewRR(modifiedString)
+						if err != nil {
+								utils.Error("Failed to convert string into dns.RR:", err)
+								return
+						}
+		
+						// Replace the response RR with the new RR.
+						r.Answer = append(r.Answer, newRR)
+				}
+			}
+
+			m = r
+			
+			specialQuery = true
+		}
+	} 
+	
+	if !specialQuery {
+		// Overwrite local hostnames with Constellation IP
+		for _, q := range r.Question {
+			utils.Debug("DNS Question " + q.Name)
+			for _, hostname := range hostnames {
+				if strings.HasSuffix(q.Name, hostname + ".") && q.Qtype == dns.TypeA {
+					utils.Debug("DNS Overwrite " + hostname + " with 192.168.201.0")
+					rr, _ := dns.NewRR(q.Name + " A 192.168.201.0")
+					m.Answer = append(m.Answer, rr)
+					customHandled = true
+				}
+			}
+		}
+		
+		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
+					}
+				}
+			}
+		}
+
+		// If not custom handled, use external DNS
+		if !customHandled {
+			client := new(dns.Client)
+			externalResponse, time, err := externalLookup(client, r, DNSFallback)
+			if err != nil {
+				utils.Error("Failed to forward query:", err)
+				return
+			}
+			utils.Debug("DNS Forwarded DNS query to "+DNSFallback+" in " + time.String())
+			
+			externalResponse.Id = r.Id
+
+			m = externalResponse
+		}
+	}
+
+	w.WriteMsg(m)
+}
+
+func InitDNS() {
+	config := utils.GetMainConfig()
+	DNSPort := config.ConstellationConfig.DNSPort
+	DNSBlockBlacklist := config.ConstellationConfig.DNSBlockBlacklist
+
+	if DNSPort == "" {
+		DNSPort = "53"
+	}
+
+	if DNSBlockBlacklist {
+		DNSBlacklist = []string{}
+		blacklistPath := utils.CONFIGFOLDER + "dns-blacklist.txt"
+
+		utils.Log("Loading DNS blacklist from " + blacklistPath)
+
+		fileExist := utils.FileExists(blacklistPath)
+		if fileExist {
+			DNSBlacklistRaw, err := ioutil.ReadFile(blacklistPath)
+			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")
+			}
+		} else {
+			utils.Log("No DNS blacklist found")
+		}
+	}
+
+	if(config.ConstellationConfig.DNS) {
+		dns.HandleFunc(".", handleDNSRequest)
+		server := &dns.Server{Addr: ":" + DNSPort, Net: "udp"}
+
+		utils.Log("Starting DNS server on :" + DNSPort)
+		if err := server.ListenAndServe(); err != nil {
+			utils.Fatal("Failed to start server: %s\n", err)
+		}
+	}
+}

+ 13 - 1
src/constellation/nebula.go

@@ -85,7 +85,10 @@ func ExportConfigToYAML(overwriteConfig utils.ConstellationConfig, outputPath st
 	finalConfig := NebulaDefaultConfig
 
 	finalConfig.StaticHostMap = map[string][]string{
-		"192.168.201.0": []string{utils.GetMainConfig().HTTPConfig.Hostname + ":4242"},
+		"192.168.201.0": []string{
+			"lighthouse-cosmos.constellation:4242",
+			utils.GetMainConfig().HTTPConfig.Hostname + ":4242",
+		},
 	}
 
 	finalConfig.Relay.AMRelay = overwriteConfig.NebulaConfig.Relay.AMRelay
@@ -132,6 +135,15 @@ func getYAMLClientConfig(name, configPath string) (string, error) {
 		return "", err
 	}
 
+	if staticHostMap, ok := configMap["static_host_map"].(map[interface{}]interface{}); ok {
+		staticHostMap["192.168.201.0"] = []string{
+			"lighthouse-cosmos.constellation:4242",
+			utils.GetMainConfig().HTTPConfig.Hostname + ":4242",
+		}
+	} else {
+		return "", errors.New("static_host_map not found in nebula.yml")
+	}
+
 	// set lightHouse to false
 	if lighthouseMap, ok := configMap["lighthouse"].(map[interface{}]interface{}); ok {
 		lighthouseMap["am_lighthouse"] = false

+ 2 - 0
src/index.go

@@ -45,6 +45,8 @@ func main() {
 	
 	authorizationserver.Init()
 
+	constellation.InitDNS()
+	
 	constellation.Init()
 
 	StartServer()

+ 5 - 0
src/utils/types.go

@@ -210,6 +210,11 @@ type MarketSource struct {
 
 type ConstellationConfig struct {
 	Enabled bool
+	DNS bool
+	DNSPort string
+	DNSFallback string
+	DNSBlockBlacklist bool
+	CustomDNSEntries map[string]string
 	NebulaConfig NebulaConfig
 }
 

+ 3 - 1
src/utils/utils.go

@@ -63,7 +63,9 @@ var DefaultConfig = Config{
 		},
 	},
   ConstellationConfig: ConstellationConfig{
-    Enabled: true,
+    Enabled: false,
+		DNS: true,
+		DNSFallback: "8.8.8.8:53",
 	},
 }