-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathblackhole.go
More file actions
128 lines (109 loc) · 3 KB
/
Copy pathblackhole.go
File metadata and controls
128 lines (109 loc) · 3 KB
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
128
package main
import (
"fmt"
"io/ioutil"
"net"
"os"
"github.com/miekg/dns"
"github.com/unixvoid/glogger"
"gopkg.in/gcfg.v1"
"gopkg.in/redis.v5"
)
type Config struct {
Blackhole struct {
Loglevel string
DNSPort int
}
Redis struct {
UseRedis bool
Host string
Password string
}
}
var (
config = Config{}
)
func main() {
readConf()
initLogger(config.Blackhole.Loglevel)
redisClient, redisErr := initRedisConnection()
if redisErr != nil {
// only print if we are using redis
if config.Redis.UseRedis {
glogger.Error.Println("redis connection cannot be made.")
glogger.Error.Println("the blackhole will continue to function in passthrough mode only")
}
} else {
// only print if we are using redis
if config.Redis.UseRedis {
glogger.Debug.Println("connection to redis succeeded.")
}
}
println(` _ _ _ _ _
| |_| |___ ___| |_| |_ ___| |___
| . | | .'| _| '_| | . | | -_|
|___|_|__,|___|_,_|_|_|___|_|___|`)
if config.Redis.UseRedis {
println("Running with redis connection..")
} else {
println("Running in standalone mode..")
}
// format the string to be :port
fPort := fmt.Sprint(":", config.Blackhole.DNSPort)
udpServer := &dns.Server{Addr: fPort, Net: "udp"}
tcpServer := &dns.Server{Addr: fPort, Net: "tcp"}
glogger.Info.Println("started server on", config.Blackhole.DNSPort)
dns.HandleFunc(".", func(w dns.ResponseWriter, req *dns.Msg) {
// reutrn nonexistent reply to all requests
hostname := req.Question[0].Name
glogger.Debug.Printf("request received: %s", hostname)
glogger.Debug.Printf("%v\n", req)
rr := new(dns.A)
rr.Hdr = dns.RR_Header{Name: hostname, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 1}
rr.A = net.ParseIP("")
// craft reply
rep := new(dns.Msg)
rep.SetReply(req)
rep.SetRcode(req, dns.RcodeNameError)
rep.Answer = append(rep.Answer, rr)
// send it
w.WriteMsg(rep)
// add hostname to redis db
if config.Redis.UseRedis {
redisClient.SAdd("index:domains", hostname)
}
})
go func() {
glogger.Error.Println(udpServer.ListenAndServe())
}()
glogger.Error.Println(tcpServer.ListenAndServe())
}
func readConf() {
// init config file
err := gcfg.ReadFileInto(&config, "config.gcfg")
if err != nil {
panic(fmt.Sprintf("Could not load config.gcfg, error: %s\n", err))
}
}
func initLogger(logLevel string) {
// init logger
if logLevel == "debug" {
glogger.LogInit(os.Stdout, os.Stdout, os.Stdout, os.Stderr)
} else if logLevel == "cluster" {
glogger.LogInit(os.Stdout, os.Stdout, ioutil.Discard, os.Stderr)
} else if logLevel == "info" {
glogger.LogInit(os.Stdout, ioutil.Discard, ioutil.Discard, os.Stderr)
} else {
glogger.LogInit(ioutil.Discard, ioutil.Discard, ioutil.Discard, os.Stderr)
}
}
func initRedisConnection() (*redis.Client, error) {
// init redis connection
redisClient := redis.NewClient(&redis.Options{
Addr: config.Redis.Host,
Password: config.Redis.Password,
DB: 0,
})
_, redisErr := redisClient.Ping().Result()
return redisClient, redisErr
}