aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2016-06-08 10:29:46 +0100
committerGravatar Miek Gieben <miek@miek.nl> 2016-06-08 10:29:46 +0100
commit713f10f6afca6c64b826ee90105d52c820d80b42 (patch)
treef5104898dc890d60fa449a9b84b35f5731dd541c
parent3165084a7bfa0679993e27d5bf3a90688eae9a2d (diff)
downloadcoredns-713f10f6afca6c64b826ee90105d52c820d80b42.tar.gz
coredns-713f10f6afca6c64b826ee90105d52c820d80b42.tar.zst
coredns-713f10f6afca6c64b826ee90105d52c820d80b42.zip
middleware/etcd: reverse addresses (#162)
* middleware/etcd: reverse addresses Implement reverse (PTR) addresses. Update the documentation on how to configure test. Added tests as well. Fixes: #157 #159 * Cleanup readme a little
-rw-r--r--middleware/etcd/README.md45
-rw-r--r--middleware/etcd/handler.go2
-rw-r--r--middleware/etcd/lookup.go15
-rw-r--r--middleware/etcd/lookup_test.go15
-rw-r--r--middleware/etcd/msg/service.go5
-rw-r--r--middleware/etcd/setup_test.go2
6 files changed, 79 insertions, 5 deletions
diff --git a/middleware/etcd/README.md b/middleware/etcd/README.md
index c3717ae58..a424244c6 100644
--- a/middleware/etcd/README.md
+++ b/middleware/etcd/README.md
@@ -72,3 +72,48 @@ This is the default SkyDNS setup, with everying specified in full:
proxy . 8.8.8.8:53 8.8.4.4:53
}
~~~
+
+### Reverse zones
+
+Reverse zones are supported. You need to make CoreDNS aware of the fact that you are also
+authoritative for the reverse. For instance if you want to add the reverse for 10.0.0.0/24, you'll
+need to add the zone `10.in-addr.arpa` to the list of zones (the fun starts with reverse IPv6 zones
+in the ip6.arpa domain). Showing a snippet of a Corefile:
+
+~~~
+ etcd skydns.local 10.in-addr.arpa {
+ stubzones
+ ...
+~~~
+
+Next you'll need to populate the zone with reverse records, here we add a reverse for
+10.0.0.127 pointing to reverse.skydns.local.
+
+~~~
+% curl -XPUT http://127.0.0.1:4001/v2/keys/skydns/arpa/in-addr/10/0/0/127 \
+ -d value='{"host":"reverse.skydns.local."}'
+~~~
+
+Querying with dig:
+
+~~~
+% dig @localhost -x 10.0.0.127 +short
+reverse.atoom.net.
+~~~
+
+Or with *debug* queries enabled:
+
+~~~
+% dig @localhost -p 1053 o-o.debug.127.0.0.10.in-addr.arpa. PTR
+
+;; OPT PSEUDOSECTION:
+; EDNS: version: 0, flags:; udp: 4096
+;; QUESTION SECTION:
+;o-o.debug.127.0.0.10.in-addr.arpa. IN PTR
+
+;; ANSWER SECTION:
+127.0.0.10.in-addr.arpa. 300 IN PTR reverse.atoom.net.
+
+;; ADDITIONAL SECTION:
+127.0.0.10.in-addr.arpa. 300 CH TXT "reverse.atoom.net.:0(10,0,,false)[0,]"
+~~~
diff --git a/middleware/etcd/handler.go b/middleware/etcd/handler.go
index d27b274cd..a270e1983 100644
--- a/middleware/etcd/handler.go
+++ b/middleware/etcd/handler.go
@@ -58,6 +58,8 @@ func (e Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
records, debug, err = e.TXT(zone, state)
case "CNAME":
records, debug, err = e.CNAME(zone, state)
+ case "PTR":
+ records, debug, err = e.PTR(zone, state)
case "MX":
records, extra, debug, err = e.MX(zone, state)
case "SRV":
diff --git a/middleware/etcd/lookup.go b/middleware/etcd/lookup.go
index 1223f85a4..5d7d89ce3 100644
--- a/middleware/etcd/lookup.go
+++ b/middleware/etcd/lookup.go
@@ -305,6 +305,21 @@ func (e Etcd) CNAME(zone string, state middleware.State) (records []dns.RR, debu
return records, debug, nil
}
+// PTR returns the PTR records, only services that have a domain name as host are included.
+func (e Etcd) PTR(zone string, state middleware.State) (records []dns.RR, debug []msg.Service, err error) {
+ services, debug, err := e.records(state, true)
+ if err != nil {
+ return nil, debug, err
+ }
+
+ for _, serv := range services {
+ if ip := net.ParseIP(serv.Host); ip == nil {
+ records = append(records, serv.NewPTR(state.QName(), serv.Host))
+ }
+ }
+ return records, debug, nil
+}
+
func (e Etcd) TXT(zone string, state middleware.State) (records []dns.RR, debug []msg.Service, err error) {
services, debug, err := e.records(state, false)
if err != nil {
diff --git a/middleware/etcd/lookup_test.go b/middleware/etcd/lookup_test.go
index ffc8c737e..14b9d0c98 100644
--- a/middleware/etcd/lookup_test.go
+++ b/middleware/etcd/lookup_test.go
@@ -15,20 +15,22 @@ var services = []*msg.Service{
{Host: "10.0.0.1", Port: 8080, Key: "a.server1.prod.region1.skydns.test."},
{Host: "10.0.0.2", Port: 8080, Key: "b.server1.prod.region1.skydns.test."},
{Host: "::1", Port: 8080, Key: "b.server6.prod.region1.skydns.test."},
- // Unresolvable internal name
+ // Unresolvable internal name.
{Host: "unresolvable.skydns.test", Key: "cname.prod.region1.skydns.test."},
- // priority
+ // Priority.
{Host: "priority.server1", Priority: 333, Port: 8080, Key: "priority.skydns.test."},
- // Subdomain
+ // Subdomain.
{Host: "sub.server1", Port: 0, Key: "a.sub.region1.skydns.test."},
{Host: "sub.server2", Port: 80, Key: "b.sub.region1.skydns.test."},
{Host: "10.0.0.1", Port: 8080, Key: "c.sub.region1.skydns.test."},
- // Cname loop
+ // Cname loop.
{Host: "a.cname.skydns.test", Key: "b.cname.skydns.test."},
{Host: "b.cname.skydns.test", Key: "a.cname.skydns.test."},
// Nameservers.
{Host: "10.0.0.2", Key: "a.ns.dns.skydns.test."},
{Host: "10.0.0.3", Key: "b.ns.dns.skydns.test."},
+ // Reverse.
+ {Host: "reverse.example.com", Key: "1.0.0.10.in-addr.arpa."}, // 10.0.0.1
}
var dnsTestCases = []test.Case{
@@ -198,4 +200,9 @@ var dnsTestCases = []test.Case{
Qname: "skydns_extra.test.", Qtype: dns.TypeSOA,
Answer: []dns.RR{test.SOA("skydns_extra.test. 300 IN SOA ns.dns.skydns_extra.test. hostmaster.skydns_extra.test. 1460498836 14400 3600 604800 60")},
},
+ // Reverse lookup
+ {
+ Qname: "1.0.0.10.in-addr.arpa.", Qtype: dns.TypePTR,
+ Answer: []dns.RR{test.PTR("1.0.0.10.in-addr.arpa. 300 PTR reverse.example.com.")},
+ },
}
diff --git a/middleware/etcd/msg/service.go b/middleware/etcd/msg/service.go
index 76d74a463..059b3263b 100644
--- a/middleware/etcd/msg/service.go
+++ b/middleware/etcd/msg/service.go
@@ -102,6 +102,11 @@ func (s *Service) NewTXT(name string) *dns.TXT {
return &dns.TXT{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: s.Ttl}, Txt: split255(s.Text)}
}
+// NewPTR returns a new PTR record based on the Service.
+func (s *Service) NewPTR(name string, target string) *dns.PTR {
+ return &dns.PTR{Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: s.Ttl}, Ptr: dns.Fqdn(target)}
+}
+
// NewNS returns a new NS record based on the Service.
func (s *Service) NewNS(name string) *dns.NS {
host := targetStrip(dns.Fqdn(s.Host), s.TargetStrip)
diff --git a/middleware/etcd/setup_test.go b/middleware/etcd/setup_test.go
index 1810e8e70..b1a7b9615 100644
--- a/middleware/etcd/setup_test.go
+++ b/middleware/etcd/setup_test.go
@@ -37,7 +37,7 @@ func init() {
PathPrefix: "skydns",
Ctx: context.Background(),
Inflight: &singleflight.Group{},
- Zones: []string{"skydns.test.", "skydns_extra.test."},
+ Zones: []string{"skydns.test.", "skydns_extra.test.", "in-addr.arpa."},
Client: etcdc.NewKeysAPI(cli),
}
}