Add BlockIP dns responder, update ZeroIP responder

This commit is contained in:
Daniel 2021-08-23 14:40:01 +02:00
parent 5b7d28d7ac
commit 1b312f5ce4
3 changed files with 36 additions and 42 deletions

View file

@ -197,7 +197,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
return reply(nsutil.NxDomain("nxdomain: " + err.Error())) return reply(nsutil.NxDomain("nxdomain: " + err.Error()))
case errors.Is(err, resolver.ErrBlocked): case errors.Is(err, resolver.ErrBlocked):
tracer.Tracef("nameserver: %s", err) tracer.Tracef("nameserver: %s", err)
return reply(nsutil.ZeroIP("blocked: " + err.Error())) return reply(nsutil.BlockIP("blocked: " + err.Error()))
case errors.Is(err, resolver.ErrLocalhost): case errors.Is(err, resolver.ErrLocalhost):
tracer.Tracef("nameserver: returning localhost records") tracer.Tracef("nameserver: returning localhost records")
return reply(nsutil.Localhost()) return reply(nsutil.Localhost())

View file

@ -45,50 +45,42 @@ func (rf ResponderFunc) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns
return rf(ctx, request) return rf(ctx, request)
} }
// BlockIP is a ResponderFunc than replies with either 0.0.0.17 or ::17 for
// each A or AAAA question respectively. If there is no A or AAAA question, it
// defaults to replying with NXDomain.
func BlockIP(msgs ...string) ResponderFunc {
return createResponderFunc(
"blocking",
"0.0.0.17",
"::17",
msgs...,
)
}
// ZeroIP is a ResponderFunc than replies with either 0.0.0.0 or :: for each A // ZeroIP is a ResponderFunc than replies with either 0.0.0.0 or :: for each A
// or AAAA question respectively. If there is no A or AAAA question, it // or AAAA question respectively. If there is no A or AAAA question, it
// defaults to replying with NXDomain. // defaults to replying with NXDomain.
func ZeroIP(msgs ...string) ResponderFunc { func ZeroIP(msgs ...string) ResponderFunc {
return func(ctx context.Context, request *dns.Msg) *dns.Msg { return createResponderFunc(
reply := new(dns.Msg) "zero ip",
hasErr := false "0.0.0.0",
"::",
for _, question := range request.Question { msgs...,
var rr dns.RR )
var err error
switch question.Qtype {
case dns.TypeA:
rr, err = dns.NewRR(question.Name + " 1 IN A 0.0.0.17")
case dns.TypeAAAA:
rr, err = dns.NewRR(question.Name + " 1 IN AAAA ::17")
}
switch {
case err != nil:
log.Tracer(ctx).Errorf("nameserver: failed to create zero-ip response for %s: %s", question.Name, err)
hasErr = true
case rr != nil:
reply.Answer = append(reply.Answer, rr)
}
}
switch {
case hasErr || len(reply.Answer) == 0:
reply.SetRcode(request, dns.RcodeServerFailure)
default:
reply.SetRcode(request, dns.RcodeSuccess)
}
AddMessagesToReply(ctx, reply, log.InfoLevel, msgs...)
return reply
}
} }
// Localhost is a ResponderFunc than replies with localhost IP addresses. // Localhost is a ResponderFunc than replies with localhost IP addresses.
// If there is no A or AAAA question, it defaults to replying with NXDomain. // If there is no A or AAAA question, it defaults to replying with NXDomain.
func Localhost(msgs ...string) ResponderFunc { func Localhost(msgs ...string) ResponderFunc {
return createResponderFunc(
"localhost",
"127.0.0.1",
"::1",
msgs...,
)
}
func createResponderFunc(responderName, aAnswer, aaaaAnswer string, msgs ...string) ResponderFunc {
return func(ctx context.Context, request *dns.Msg) *dns.Msg { return func(ctx context.Context, request *dns.Msg) *dns.Msg {
reply := new(dns.Msg) reply := new(dns.Msg)
hasErr := false hasErr := false
@ -99,14 +91,14 @@ func Localhost(msgs ...string) ResponderFunc {
switch question.Qtype { switch question.Qtype {
case dns.TypeA: case dns.TypeA:
rr, err = dns.NewRR("localhost. 1 IN A 127.0.0.1") rr, err = dns.NewRR(question.Name + " 1 IN A " + aAnswer)
case dns.TypeAAAA: case dns.TypeAAAA:
rr, err = dns.NewRR("localhost. 1 IN AAAA ::1") rr, err = dns.NewRR(question.Name + " 1 IN AAAA " + aaaaAnswer)
} }
switch { switch {
case err != nil: case err != nil:
log.Tracer(ctx).Errorf("nameserver: failed to create localhost response for %s: %s", question.Name, err) log.Tracer(ctx).Errorf("nameserver: failed to create %s response for %s: %s", responderName, question.Name, err)
hasErr = true hasErr = true
case rr != nil: case rr != nil:
reply.Answer = append(reply.Answer, rr) reply.Answer = append(reply.Answer, rr)
@ -114,8 +106,10 @@ func Localhost(msgs ...string) ResponderFunc {
} }
switch { switch {
case hasErr || len(reply.Answer) == 0: case hasErr && len(reply.Answer) == 0:
reply.SetRcode(request, dns.RcodeServerFailure) reply.SetRcode(request, dns.RcodeServerFailure)
case len(reply.Answer) == 0:
reply.SetRcode(request, dns.RcodeNameError)
default: default:
reply.SetRcode(request, dns.RcodeSuccess) reply.SetRcode(request, dns.RcodeSuccess)
} }

View file

@ -103,11 +103,11 @@ func (conn *Connection) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns
// Select request responder. // Select request responder.
switch conn.Verdict { switch conn.Verdict {
case VerdictBlock: case VerdictBlock:
return nsutil.ZeroIP().ReplyWithDNS(ctx, request) return nsutil.BlockIP().ReplyWithDNS(ctx, request)
case VerdictDrop: case VerdictDrop:
return nil // Do not respond to request. return nil // Do not respond to request.
case VerdictFailed: case VerdictFailed:
return nsutil.ZeroIP().ReplyWithDNS(ctx, request) return nsutil.BlockIP().ReplyWithDNS(ctx, request)
default: default:
reply := nsutil.ServerFailure().ReplyWithDNS(ctx, request) reply := nsutil.ServerFailure().ReplyWithDNS(ctx, request)
nsutil.AddMessagesToReply(ctx, reply, log.ErrorLevel, "INTERNAL ERROR: incorrect use of Connection DNS Responder") nsutil.AddMessagesToReply(ctx, reply, log.ErrorLevel, "INTERNAL ERROR: incorrect use of Connection DNS Responder")