diff options
| author | galaxyzm <[email protected]> | 2024-08-25 22:18:55 +0800 |
|---|---|---|
| committer | galaxyzm <[email protected]> | 2024-08-25 22:18:55 +0800 |
| commit | b5637149276de6bacc039953e234ce677e73e879 (patch) | |
| tree | 0ad4230e46525a4c416b0ec451f870aba9bde575 | |
Initial commit
| -rw-r--r-- | .DS_Store | bin | 0 -> 6148 bytes | |||
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | cmd/false/false.go | 91 | ||||
| -rw-r--r-- | cmd/test/test.go | 115 | ||||
| -rw-r--r-- | cmd/true/true.go | 91 | ||||
| -rw-r--r-- | go.mod | 15 | ||||
| -rw-r--r-- | go.sum | 22 | ||||
| -rw-r--r-- | internal/query.go | 65 | ||||
| -rw-r--r-- | internal/readfile.go | 59 | ||||
| -rw-r--r-- | main.go | 5 | ||||
| -rw-r--r-- | readme.md | 17 |
11 files changed, 482 insertions, 0 deletions
diff --git a/.DS_Store b/.DS_Store Binary files differnew file mode 100644 index 0000000..4ac29df --- /dev/null +++ b/.DS_Store diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7d2810 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +db +files/**.csv
\ No newline at end of file diff --git a/cmd/false/false.go b/cmd/false/false.go new file mode 100644 index 0000000..b439296 --- /dev/null +++ b/cmd/false/false.go @@ -0,0 +1,91 @@ +package main + +import ( + "dnssecpool/internal" + "encoding/csv" + "fmt" + "log" + "os" + "sync" + "time" +) + +const ( + domainToQuery = "dnssec-false.ncache.site" // 替换为你想查询的域名 + outputFile = "files/resolvers_dnssec.csv" // 输出的 CSV 文件 + numWorkers = 20 // 并发的 goroutine 数量 +) + +func main() { + start := time.Now() + + resolvers, err1 := internal.ReadResolversCSV("files/resolvers_ad.csv") + if err1 != nil { + log.Fatalf("Failed to read resolvers: %v", err1) + } + + // 创建 CSV 文件 + csvFile, err := os.Create(outputFile) + if err != nil { + log.Fatalf("Failed to create CSV file: %v", err) + } + defer csvFile.Close() + + csvWriter := csv.NewWriter(csvFile) + defer csvWriter.Flush() + + var wg sync.WaitGroup + jobs := make(chan string, len(resolvers)) + results := make(chan []string, len(resolvers)) + + // 启动 worker goroutines + for i := 0; i < numWorkers; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for resolver := range jobs { + response, err := internal.QueryDNS(resolver, domainToQuery) + if err != nil { + // results <- [][]string{[][]string, err.Error()} + // results <- []string{resolver, "err", "err", "err"} + + // results <- []string{resolver, "err", "err"} + } else { + csvData := internal.PrepareCSVData(resolver, &response) + if csvData[2] != "NOERROR" { + results <- csvData + } + } + } + }() + } + + // 发送解析器到 jobs 通道 + for _, resolver := range resolvers { + jobs <- resolver + } + close(jobs) + + // 等待所有 worker 完成 + go func() { + wg.Wait() + close(results) + }() + header := []string{"Resolver", "AD", "Response Code"} + // header := []string{"Resolver", "AD", "Response Code", "Answers"} + if err := csvWriter.Write(header); err != nil { + log.Printf("Failed to write to CSV: %v", err) + } + // 处理结果并写入 CSV 文件 + for result := range results { + if err := csvWriter.Write(result); err != nil { + log.Printf("Failed to write to CSV: %v", err) + } + } + + // 记录程序结束时间 + end := time.Now() + // 计算和输出执行时间 + elapsed := end.Sub(start) + fmt.Printf("程序执行时间: %s\n", elapsed) +} diff --git a/cmd/test/test.go b/cmd/test/test.go new file mode 100644 index 0000000..2f37213 --- /dev/null +++ b/cmd/test/test.go @@ -0,0 +1,115 @@ +package main + +import ( + "dnssecpool/internal" + "encoding/csv" + "fmt" + "log" + "os" + "strings" + + "github.com/miekg/dns" +) + +// 在这个代码里完成以下操作: +// 发起对正确域名的查询并记录响应 +func main() { + //从文件中读取解析器列表 + resolvers, err1 := internal.ReadResolversTXT("db/resolver_test.txt") + fmt.Println(resolvers) + //对解析器列表进行多线程DNS查询,同时记录收到查询的结果,记录ad字段、rcode、三部分答案 + if err1 != nil { + log.Fatalf("Failed to read resolvers: %v", err1) + } + domain := "ftp.isc.org" + filePath := "files/dns_responses.csv" + file, err := os.Create(filePath) + if err != nil { + log.Fatalf("Failed to create file: %v", err) + } + defer file.Close() + + writer := csv.NewWriter(file) + defer writer.Flush() + + // Write CSV header + header := []string{"Resolver", "AD", "Response Code", "Answers"} + // header := []string{"Resolver", "AD", "Response Code", "Answers", "Authority", "Additional"} + if err := writer.Write(header); err != nil { + log.Fatalf("Error writing header to CSV: %v", err) + } + + // Create a DNS client + client := dns.Client{} + + for _, resolver := range resolvers { + // Prepare the DNS message + resolver += ":53" + msg := dns.Msg{} + // msg.set + msg.SetQuestion(domain+".", dns.TypeA) + msg.SetEdns0(4096, true) + msg.RecursionDesired = true + // Send the DNS query to the resolver + response, _, err := client.Exchange(&msg, resolver) + if err != nil { + log.Printf("Query error for resolver %s: %v", resolver, err) + continue + } + + // Prepare CSV data for this resolver's response + csvData := prepareCSVData(resolver, response) + fmt.Println(csvData) + // Write to CSV file + if err := writer.Write(csvData); err != nil { + log.Printf("Error writing CSV data for resolver %s: %v", resolver, err) + } + } + + fmt.Println("DNS responses written to", filePath) +} +func prepareCSVData(resolver string, response *dns.Msg) []string { + ad := "" + if response.MsgHdr.AuthenticatedData { + ad = "1" + fmt.Println("-1-1-1") + } else { + ad = "0" + } + if response.MsgHdr.Truncated { + fmt.Println(000) + } + if response.MsgHdr.Authoritative { + fmt.Println(111) + } + if response.MsgHdr.RecursionAvailable { + fmt.Println(222) + } + if response.MsgHdr.RecursionDesired { + fmt.Println(333) + } + var answers []string + for _, answer := range response.Answer { + // fmt.Println(answer.String()) + answers = append(answers, answer.String()) + } + // fmt.Println(answers) + + // var authority []string + // for _, ns := range response.Ns { + // authority = append(authority, ns.String()) + // } + + // var additional []string + // for _, extra := range response.Extra { + // additional = append(additional, extra.String()) + // } + return []string{ + resolver, + ad, + dns.RcodeToString[response.Rcode], + strings.Join(answers, "||"), + // strings.Join(authority, "||"), + // strings.Join(additional, "||"), + } +} diff --git a/cmd/true/true.go b/cmd/true/true.go new file mode 100644 index 0000000..57ea5fc --- /dev/null +++ b/cmd/true/true.go @@ -0,0 +1,91 @@ +package main + +import ( + "dnssecpool/internal" + "encoding/csv" + "fmt" + "log" + "os" + "sync" + "time" +) + +const ( + domainToQuery = "ftp.isc.org" // 替换为你想查询的域名 + outputFile = "files/resolvers_ad.csv" // 输出的 CSV 文件 + numWorkers = 50 // 并发的 goroutine 数量 +) + +func main() { + start := time.Now() + + resolvers, err1 := internal.ReadResolversTXT("db/stable_open_resolvers_240726.txt") + if err1 != nil { + log.Fatalf("Failed to read resolvers: %v", err1) + } + + // 创建 CSV 文件 + csvFile, err := os.Create(outputFile) + if err != nil { + log.Fatalf("Failed to create CSV file: %v", err) + } + defer csvFile.Close() + + csvWriter := csv.NewWriter(csvFile) + defer csvWriter.Flush() + + var wg sync.WaitGroup + jobs := make(chan string, len(resolvers)) + results := make(chan []string, len(resolvers)) + + // 启动 worker goroutines + for i := 0; i < numWorkers; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for resolver := range jobs { + response, err := internal.QueryDNS(resolver, domainToQuery) + if err != nil { + // results <- [][]string{[][]string, err.Error()} + // results <- []string{resolver, "err", "err", "err"} + + // results <- []string{resolver, "err", "err"} + } else { + csvData := internal.PrepareCSVData(resolver, &response) + if csvData[1] == "1" { + results <- csvData + } + } + } + }() + } + + // 发送解析器到 jobs 通道 + for _, resolver := range resolvers { + jobs <- resolver + } + close(jobs) + + // 等待所有 worker 完成 + go func() { + wg.Wait() + close(results) + }() + // header := []string{"Resolver", "AD", "Response Code"} + // // header := []string{"Resolver", "AD", "Response Code", "Answers"} + // if err := csvWriter.Write(header); err != nil { + // log.Printf("Failed to write to CSV: %v", err) + // } + // 处理结果并写入 CSV 文件 + for result := range results { + if err := csvWriter.Write(result); err != nil { + log.Printf("Failed to write to CSV: %v", err) + } + } + + // 记录程序结束时间 + end := time.Now() + // 计算和输出执行时间 + elapsed := end.Sub(start) + fmt.Printf("程序执行时间: %s\n", elapsed) +} @@ -0,0 +1,15 @@ +module dnssecpool + +go 1.21.6 + +require github.com/miekg/dns v1.1.61 + +require ( + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect +) + +replace example.com/internal => ./internal @@ -0,0 +1,22 @@ +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= diff --git a/internal/query.go b/internal/query.go new file mode 100644 index 0000000..17710ff --- /dev/null +++ b/internal/query.go @@ -0,0 +1,65 @@ +package internal + +import ( + "github.com/miekg/dns" +) + +// 使用 DNS 解析器查询指定的域名 +func QueryDNS(resolver, domain string) (dns.Msg, error) { + client := new(dns.Client) + msg := new(dns.Msg) + msg.SetQuestion(dns.Fqdn(domain), dns.TypeA) // 查询 A 记录 + msg.SetEdns0(4096, true) + msg.RecursionDesired = true + + resp, _, err := client.Exchange(msg, resolver+":53") + if err != nil { + return dns.Msg{}, err + } + return *resp, err +} +func PrepareCSVData(resolver string, response *dns.Msg) []string { + ad := "" + if response.MsgHdr.AuthenticatedData { + ad = "1" + // fmt.Println("-1-1-1") + } else { + ad = "0" + } + // if response.MsgHdr.Truncated { + // fmt.Println(000) + // } + // if response.MsgHdr.Authoritative { + // fmt.Println(111) + // } + // if response.MsgHdr.RecursionAvailable { + // fmt.Println(222) + // } + // if response.MsgHdr.RecursionDesired { + // fmt.Println(333) + // } + // var answers []string + // for _, answer := range response.Answer { + // // fmt.Println(answer.String()) + // answers = append(answers, answer.String()) + // } + // fmt.Println(answers) + + // var authority []string + // for _, ns := range response.Ns { + // authority = append(authority, ns.String()) + // } + + // var additional []string + // for _, extra := range response.Extra { + // additional = append(additional, extra.String()) + // } + return []string{ + resolver, + ad, + dns.RcodeToString[response.Rcode], + // strings.Join(answers, "||"), + // strings.Join(authority, "||"), + // strings.Join(additional, "||"), + } +} diff --git a/internal/readfile.go b/internal/readfile.go new file mode 100644 index 0000000..bf81ac7 --- /dev/null +++ b/internal/readfile.go @@ -0,0 +1,59 @@ +package internal + +import ( + "bufio" + "encoding/csv" + "os" + "strings" +) + +func ReadResolversTXT(filename string) ([]string, error) { + file, err := os.Open(filename) + if err != nil { + return nil, err + } + defer file.Close() + + var resolvers []string + scanner := bufio.NewScanner(file) + for scanner.Scan() { + resolver := strings.TrimSpace(scanner.Text()) + if resolver != "" { + resolvers = append(resolvers, resolver) + } + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + return resolvers, nil +} + +func ReadResolversCSV(filename string) ([]string, error) { + file, err := os.Open(filename) + if err != nil { + return nil, err + } + defer file.Close() + + var resolvers []string + reader := csv.NewReader(file) + for { + record, err := reader.Read() + if err != nil { + if err.Error() == "EOF" { + break + } + return nil, err + } + if len(record) > 0 { + resolver := strings.TrimSpace(record[0]) + if resolver != "" { + resolvers = append(resolvers, resolver) + } + } + } + + return resolvers, nil +} @@ -0,0 +1,5 @@ +package main + +func main() { + +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..96db6b1 --- /dev/null +++ b/readme.md @@ -0,0 +1,17 @@ +## 本代码对现有进行DNSSEC验证的解析器池进行探测 +输入:所有活跃的Do53入口(四十多万个) +输出:支持DNSSEC验证的部分 +总共分几步: +1.首先在自己权威服务器配置资源记录 + dnssec-true.ncache.site A 1.2.3.4 + dnssec-false.ncache.site A 1.2.3.4 +2.对区文件签名生成db.ncache.site.signed +3.修改后者的RRSIG记录,随便改一个字母 +4.restart服务,在服务器上跑着 +5.在客户端(即该服务器)发送对两个域名的查询 + 先对所有服务器发送一遍true的查询,看看有没有ad?必要吗 + 筛掉所有没有ad的,输出列表 + 再对所有剩下的服务器发送一遍false的查询,看看是否返回fail响应 + +涉及的技术: +多线程发起DNS查询
\ No newline at end of file |
