@@ -4,16 +4,24 @@ import (
4
4
"fmt"
5
5
6
6
"github.com/miekg/dns"
7
+ "math/rand"
7
8
log "github.com/sirupsen/logrus"
9
+ ns1 "gopkg.in/ns1/ns1-go.v2/rest"
10
+ "net/http"
11
+ "time"
12
+ "os"
13
+ "strings"
8
14
)
9
15
16
+ var ns1Client * ns1.Client
17
+
10
18
type dnsServerHandler struct {
11
19
ds * dns.Server
12
20
}
13
21
14
- // TODO: Move in-memory mapping toa real datastore
15
- var records = map [ string ] string {
16
- "foo.com." : "192.168.0.1" ,
22
+ func getRandomAnswer ( max int ) int {
23
+ rand . Seed ( time . Now (). Unix ())
24
+ return rand . Intn ( max - 0 ) + 0
17
25
}
18
26
19
27
func parseQuery (m * dns.Msg ) {
@@ -22,16 +30,29 @@ func parseQuery(m *dns.Msg) {
22
30
for _ , q := range m .Question {
23
31
switch q .Qtype {
24
32
case dns .TypeA :
25
- rl .Info ("Query for: " , q .Name )
26
- ip := records [q .Name ]
27
- if ip != "" {
28
- rr , err := dns .NewRR (fmt .Sprintf ("%s A %s" , q .Name , ip ))
33
+ zone := q .Name [strings .IndexAny (q .Name , "." )+ 1 :len (q .Name )- 1 ]
34
+ domain := q .Name [:strings .LastIndex (q .Name , "." )]
35
+
36
+ rl .Info ("Query for > " , "domain: " , domain , " zone: " , zone , " type: " , q .Qtype )
37
+ record , _ , err := ns1Client .Records .Get (zone , domain , "A" )
38
+ if err != nil {
39
+ rl .Error ("Record: " , q .Name , err )
40
+ } else {
41
+ rl .Info (record .Answers )
42
+ var answers []string
43
+ for _ , answer := range record .Answers {
44
+ answers = append (answers , answer .String ())
45
+ }
46
+ // TODO: Implement RR answer retrieval
47
+ rr , err := dns .NewRR (fmt .Sprintf ("%s A %s" , q .Name , answers [getRandomAnswer (len (answers ))]))
29
48
if err == nil {
30
49
m .Answer = append (m .Answer , rr )
50
+ } else {
51
+ rl .Error (err )
31
52
}
32
- } else {
33
- rl .Error ("Record: " , q .Name , " not found" )
34
53
}
54
+
55
+ // TODO: Add IPv6 support
35
56
default :
36
57
rl .Info ("Query type: " , q .Qtype , " is currently not supported" )
37
58
}
@@ -63,12 +84,19 @@ func newDefaultDNSServerHandler() *dnsServerHandler {
63
84
ds : newDNSServerHandler (DNS_SERVER_ADDR , DNS_SERVER_PORT , "udp" ),
64
85
}
65
86
}
87
+ func init () {
88
+ k := os .Getenv ("NS1_APIKEY" )
89
+ if k == "" {
90
+ fmt .Println ("NS1_APIKEY environment variable is not set, stopping DNS server" )
91
+ }
92
+ httpClient := & http.Client {Timeout : time .Second * 10 }
93
+ ns1Client = ns1 .NewClient (httpClient , ns1 .SetAPIKey (k ))
94
+ }
66
95
67
96
func (h * dnsServerHandler ) RouteDNS () error {
68
97
rl := NewLogger (log .New ().Writer ())
69
98
70
- // TODO: Add more domains to the serving list
71
- dns .HandleFunc ("com." , serve )
99
+ dns .HandleFunc ("." , serve )
72
100
err := h .ds .ListenAndServe ()
73
101
if err != nil {
74
102
rl .Error ("Failed to start DNS server" , err )
0 commit comments