dns: serve reverse lookup queries for all RFC 1918 reserved networks
This commit is contained in:
parent
fdd2201ef5
commit
02c7fa7e0d
@ -2,6 +2,7 @@ package dns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -45,6 +46,50 @@ func (s *Server) SetLeases(leases []dhcp4d.Lease) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustParseCIDR(s string) *net.IPNet {
|
||||||
|
_, ipnet, err := net.ParseCIDR(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return ipnet
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
localNets = []*net.IPNet{
|
||||||
|
// reversed: https://tools.ietf.org/html/rfc1918#section-3
|
||||||
|
mustParseCIDR("10.0.0.0/8"),
|
||||||
|
mustParseCIDR("172.16.0.0/12"),
|
||||||
|
mustParseCIDR("192.168.0.0/16"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func reverse(ss []string) {
|
||||||
|
last := len(ss) - 1
|
||||||
|
for i := 0; i < len(ss)/2; i++ {
|
||||||
|
ss[i], ss[last-i] = ss[last-i], ss[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isLocalInAddrArpa(q string) bool {
|
||||||
|
if !strings.HasSuffix(q, ".in-addr.arpa.") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
parts := strings.Split(strings.TrimSuffix(q, ".in-addr.arpa."), ".")
|
||||||
|
reverse(parts)
|
||||||
|
ip := net.ParseIP(strings.Join(parts, "."))
|
||||||
|
if ip == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var local bool
|
||||||
|
for _, l := range localNets {
|
||||||
|
if l.Contains(ip) {
|
||||||
|
local = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return local
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: is handleRequest called in more than one goroutine at a time?
|
// TODO: is handleRequest called in more than one goroutine at a time?
|
||||||
// TODO: require search domains to be present, then use HandleFunc("lan.", internalName)
|
// TODO: require search domains to be present, then use HandleFunc("lan.", internalName)
|
||||||
func (s *Server) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
func (s *Server) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
@ -69,7 +114,7 @@ func (s *Server) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if q.Qtype == dns.TypePTR && q.Qclass == dns.ClassINET {
|
if q.Qtype == dns.TypePTR && q.Qclass == dns.ClassINET {
|
||||||
if strings.HasSuffix(q.Name, "168.192.in-addr.arpa.") {
|
if isLocalInAddrArpa(q.Name) {
|
||||||
if host, ok := s.hostsByIP[q.Name]; ok {
|
if host, ok := s.hostsByIP[q.Name]; ok {
|
||||||
rr, err := dns.NewRR(q.Name + " 3600 IN PTR " + host + "." + s.domain)
|
rr, err := dns.NewRR(q.Name + " 3600 IN PTR " + host + "." + s.domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -75,16 +75,41 @@ func TestDHCP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDHCPReverse(t *testing.T) {
|
func TestDHCPReverse(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
ip net.IP
|
||||||
|
question string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ip: net.IP{192, 168, 42, 23},
|
||||||
|
question: "23.42.168.192.in-addr.arpa.",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
ip: net.IP{10, 0, 0, 2},
|
||||||
|
question: "2.0.0.10.in-addr.arpa.",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
ip: net.IP{172, 16, 0, 1}, // 172.16/12 HostMin
|
||||||
|
question: "1.0.16.172.in-addr.arpa.",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
ip: net.IP{172, 31, 255, 254}, // 172.16/12 HostMax
|
||||||
|
question: "254.255.31.172.in-addr.arpa.",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(test.question, func(t *testing.T) {
|
||||||
r := &recorder{}
|
r := &recorder{}
|
||||||
s := NewServer("localhost:0", "lan")
|
s := NewServer("localhost:0", "lan")
|
||||||
s.SetLeases([]dhcp4d.Lease{
|
s.SetLeases([]dhcp4d.Lease{
|
||||||
{
|
{
|
||||||
Hostname: "xps",
|
Hostname: "xps",
|
||||||
Addr: net.IP{192, 168, 42, 23},
|
Addr: test.ip,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetQuestion("23.42.168.192.in-addr.arpa.", dns.TypePTR)
|
m.SetQuestion(test.question, dns.TypePTR)
|
||||||
s.handleRequest(r, m)
|
s.handleRequest(r, m)
|
||||||
if got, want := len(r.response.Answer), 1; got != want {
|
if got, want := len(r.response.Answer), 1; got != want {
|
||||||
t.Fatalf("unexpected number of answers: got %d, want %d", got, want)
|
t.Fatalf("unexpected number of answers: got %d, want %d", got, want)
|
||||||
@ -96,6 +121,8 @@ func TestDHCPReverse(t *testing.T) {
|
|||||||
if got, want := a.(*dns.PTR).Ptr, "xps.lan."; got != want {
|
if got, want := a.(*dns.PTR).Ptr, "xps.lan."; got != want {
|
||||||
t.Fatalf("unexpected response record: got %q, want %q", got, want)
|
t.Fatalf("unexpected response record: got %q, want %q", got, want)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: multiple questions
|
// TODO: multiple questions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user