-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathdns.go
127 lines (110 loc) · 2.99 KB
/
dns.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"bufio"
"crypto/tls"
"fmt"
"net/http"
"os"
"strings"
log "github.com/sirupsen/logrus"
"github.com/miekg/dns"
)
var routeDomainList [][]string
// checkSkipDomainList returns true if the domain exists in the domainList
func checkBypassDomainList(domainName string, domainList [][]string) bool {
for _, item := range domainList {
if len(item) == 2 {
if item[1] == "suffix" {
if strings.HasSuffix(domainName, item[0]) {
return true
}
} else if item[1] == "fqdn" {
if domainName == item[0] {
return true
}
} else if item[1] == "prefix" {
if strings.HasPrefix(domainName, item[0]) {
return true
}
}
}
}
return false
}
// func loadDomainsToList(Filename string) [][]string {
// file, err := os.Open(Filename)
// handleError(err)
// log.Println("(re)loading File: ", Filename)
// defer file.Close()
// var lines [][]string
// scanner := bufio.NewScanner(file)
// for scanner.Scan() {
// lines = append(lines, strings.Split(scanner.Text(), ","))
// }
// return lines
// }
func loadDomainsToList(Filename string) [][]string {
log.Info("Loading the domain from file/url to a list")
var lines [][]string
var scanner *bufio.Scanner
if strings.HasPrefix(Filename, "http://") || strings.HasPrefix(Filename, "https://") {
log.Info("domain list is a URL, trying to fetch")
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := http.Client{
CheckRedirect: func(r *http.Request, via []*http.Request) error {
r.URL.Opaque = r.URL.Path
return nil
},
}
resp, err := client.Get(Filename)
if err != nil {
log.Fatal(err)
}
log.Info("(re)fetching URL: ", Filename)
defer resp.Body.Close()
scanner = bufio.NewScanner(resp.Body)
} else {
file, err := os.Open(Filename)
if err != nil {
log.Fatal(err)
}
log.Info("(re)loading File: ", Filename)
defer file.Close()
scanner = bufio.NewScanner(file)
}
for scanner.Scan() {
lowerCaseLine := strings.ToLower(scanner.Text())
lines = append(lines, strings.Split(lowerCaseLine, ","))
}
log.Infof("%s loaded with %d lines", Filename, len(lines))
return lines
}
func performExternalQuery(question dns.Question, server string) (*dns.Msg, error) {
c := new(dns.Client)
m1 := new(dns.Msg)
m1.Id = dns.Id()
m1.RecursionDesired = true
m1.Question = make([]dns.Question, 1)
m1.Question[0] = question
in, _, err := c.Exchange(m1, fmt.Sprintf("%s:53", server))
return in, err
}
func parseQuery(m *dns.Msg, ip string) {
for _, q := range m.Question {
if !checkBypassDomainList(q.Name, routeDomainList) && !*allDomains {
log.Printf("Bypassing Traffic for %s\n", q.Name)
in, err := performExternalQuery(q, *upstreamDNS)
if err != nil {
log.Println(err)
}
m.Answer = append(m.Answer, in.Answer...)
} else {
rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, ip))
if err == nil {
log.Printf("Routing Traffic for %s\n", q.Name)
m.Answer = append(m.Answer, rr)
return
}
}
}
}