Skip to content

Commit 40b2f33

Browse files
committed
respond to queries on base-domains with CNAME to NS1
1 parent 20d6405 commit 40b2f33

File tree

4 files changed

+92
-35
lines changed

4 files changed

+92
-35
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## Features
66

77
* Disable IP- or Domain-Listeners if no config for them was provided
8+
* Respond to queries on base-domains with CNAME to NS1
89

910
## Fixes
1011

src/cmd/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ func main() {
6464
fmt.Printf(" > Domain Lookup: %v\n", config.BaseDomain[1:])
6565
}
6666

67+
dns.HandleFunc(config.Root, config.LookupRoot)
68+
6769
server := &dns.Server{Addr: ":" + strconv.Itoa(port), Net: "udp"}
6870
err = server.ListenAndServe()
6971
defer server.Shutdown()

src/internal/config.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type DNSBLConfigFlat struct {
3636

3737
type DNSBLRunningConfig struct {
3838
BL DNSBLConfigFlat
39+
Root string
3940
BaseIP string
4041
BaseDomain string
4142
NS []string
@@ -46,11 +47,15 @@ type DNSBLRunningConfig struct {
4647
}
4748

4849
func (config *DNSBLRunningConfig) LookupIP(w dns.ResponseWriter, r *dns.Msg) {
49-
HandleDnsRequest(w, r, config, LOOKUP_IP)
50+
HandleDnsBLRequest(w, r, config, LOOKUP_IP)
5051
}
5152

5253
func (config *DNSBLRunningConfig) LookupDomain(w dns.ResponseWriter, r *dns.Msg) {
53-
HandleDnsRequest(w, r, config, LOOKUP_DOMAIN)
54+
HandleDnsBLRequest(w, r, config, LOOKUP_DOMAIN)
55+
}
56+
57+
func (config *DNSBLRunningConfig) LookupRoot(w dns.ResponseWriter, r *dns.Msg) {
58+
HandleDNSRootDomain(w, r, config)
5459
}
5560

5661
func LoadConfig(config_file string, d *DNSBLConfigFile) error {
@@ -80,6 +85,7 @@ func ValidateFlattenConfig(c *DNSBLConfigFile, r *DNSBLRunningConfig) {
8085
c.Domain += "."
8186
}
8287

88+
r.Root = c.Domain
8389
r.BaseIP = fmt.Sprintf(".ip.%v", c.Domain)
8490
r.BaseDomain = fmt.Sprintf(".d.%v", c.Domain)
8591

src/internal/server.go

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,49 @@ func getBaseDomain(t int, c *DNSBLRunningConfig) string {
8585
}
8686
}
8787

88+
func sendCNAMEofNS1(m *dns.Msg, d string, c *DNSBLRunningConfig) {
89+
rr, err := dns.NewRR(fmt.Sprintf("%s CNAME %s", d, c.NS[0]))
90+
if err == nil {
91+
m.Answer = append(m.Answer, rr)
92+
}
93+
m.Rcode = dns.RcodeSuccess
94+
}
95+
96+
func sendNS(m *dns.Msg, q dns.Question, d string, c *DNSBLRunningConfig) {
97+
for _, host := range c.NS {
98+
rr, err := dns.NewRR(fmt.Sprintf("%s 3600 IN NS %s", d, host))
99+
if err == nil {
100+
if q.Name == d {
101+
m.Answer = append(m.Answer, rr)
102+
} else {
103+
m.Ns = append(m.Ns, rr)
104+
}
105+
m.Rcode = dns.RcodeSuccess
106+
107+
} else {
108+
fmt.Println("NS ERROR:", q.Name, d, err)
109+
m.Rcode = dns.RcodeServerFailure
110+
}
111+
}
112+
}
113+
114+
func sendSOA(m *dns.Msg, q dns.Question, d string, c *DNSBLRunningConfig) {
115+
rr, err := dns.NewRR(soaResponse(d, c))
116+
117+
if err == nil {
118+
if q.Name == d {
119+
m.Answer = append(m.Answer, rr)
120+
} else {
121+
m.Ns = append(m.Ns, rr)
122+
}
123+
m.Rcode = dns.RcodeSuccess
124+
125+
} else {
126+
fmt.Println("SOA ERROR:", q.Name, d, err)
127+
m.Rcode = dns.RcodeServerFailure
128+
}
129+
}
130+
88131
func parseQuery(m *dns.Msg, w dns.ResponseWriter, c *DNSBLRunningConfig, t int) {
89132
for _, q := range m.Question {
90133
q.Name = strings.ToLower(q.Name)
@@ -94,10 +137,19 @@ func parseQuery(m *dns.Msg, w dns.ResponseWriter, c *DNSBLRunningConfig, t int)
94137
var res string
95138
cli := ""
96139
query := ""
140+
97141
if c.Log {
98142
cli = strings.Split(w.RemoteAddr().String(), ":")[0]
99143
}
100144

145+
// send client to first nameserver if base-domain was queried (maybe the user wants to host a website on it?)
146+
baseDomain := getBaseDomain(t, c)
147+
if q.Name == baseDomain {
148+
sendCNAMEofNS1(m, baseDomain, c)
149+
return
150+
}
151+
152+
// check if IP or Domain is listed
101153
if t == LOOKUP_IP {
102154
res, query = checkIP(q, c)
103155
} else {
@@ -122,45 +174,15 @@ func parseQuery(m *dns.Msg, w dns.ResponseWriter, c *DNSBLRunningConfig, t int)
122174
}
123175

124176
case dns.TypeSOA:
125-
baseDomain := getBaseDomain(t, c)
126-
rr, err := dns.NewRR(soaResponse(baseDomain, c))
127-
128-
if err == nil {
129-
if q.Name == baseDomain {
130-
m.Answer = append(m.Answer, rr)
131-
} else {
132-
m.Ns = append(m.Ns, rr)
133-
}
134-
m.Rcode = dns.RcodeSuccess
135-
136-
} else {
137-
fmt.Println("SOA ERROR:", q.Name, baseDomain, err)
138-
m.Rcode = dns.RcodeServerFailure
139-
}
177+
sendSOA(m, q, getBaseDomain(t, c), c)
140178

141179
case dns.TypeNS:
142-
baseDomain := getBaseDomain(t, c)
143-
144-
for _, host := range c.NS {
145-
rr, err := dns.NewRR(fmt.Sprintf("%s 3600 IN NS %s", baseDomain, host))
146-
if err == nil {
147-
if q.Name == baseDomain {
148-
m.Answer = append(m.Answer, rr)
149-
} else {
150-
m.Ns = append(m.Ns, rr)
151-
}
152-
m.Rcode = dns.RcodeSuccess
153-
154-
} else {
155-
fmt.Println("NS ERROR:", q.Name, baseDomain, err)
156-
m.Rcode = dns.RcodeServerFailure
157-
}
158-
}
180+
sendNS(m, q, getBaseDomain(t, c), c)
159181
}
160182
}
161183
}
162184

163-
func HandleDnsRequest(w dns.ResponseWriter, r *dns.Msg, c *DNSBLRunningConfig, l int) {
185+
func HandleDnsBLRequest(w dns.ResponseWriter, r *dns.Msg, c *DNSBLRunningConfig, l int) {
164186
m := new(dns.Msg)
165187
m.SetReply(r)
166188
m.Compress = false
@@ -172,3 +194,29 @@ func HandleDnsRequest(w dns.ResponseWriter, r *dns.Msg, c *DNSBLRunningConfig, l
172194

173195
w.WriteMsg(m)
174196
}
197+
198+
func HandleDNSRootDomain(w dns.ResponseWriter, r *dns.Msg, c *DNSBLRunningConfig) {
199+
m := new(dns.Msg)
200+
m.SetReply(r)
201+
m.Compress = false
202+
203+
switch r.Opcode {
204+
case dns.OpcodeQuery:
205+
for _, q := range m.Question {
206+
q.Name = strings.ToLower(q.Name)
207+
208+
switch q.Qtype {
209+
case dns.TypeSOA:
210+
sendSOA(m, q, c.Root, c)
211+
212+
case dns.TypeNS:
213+
sendNS(m, q, c.Root, c)
214+
215+
default:
216+
sendCNAMEofNS1(m, c.Root, c)
217+
}
218+
}
219+
}
220+
221+
w.WriteMsg(m)
222+
}

0 commit comments

Comments
 (0)