Skip to content

Commit

Permalink
Resolve CNAME record like Route 53 alias record
Browse files Browse the repository at this point in the history
  • Loading branch information
wadahiro committed Feb 27, 2018
1 parent 75e1bd5 commit 9ee9408
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 12 deletions.
56 changes: 48 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ amazondns ZONE [ADDRESS] {

## Examples

Create your Route 53 private hostead zone with `sub.example.org` and attach your VPC. Then add A record for `test.sub.example.org` into the zone.
Setup Route 53 as below.

* Create your Route 53 private hostead zone with `sub.example.org` and attach your VPC.
* Add A record as `test.sub.example.org` into the zone.
* Add CNAME record as `lb.sub.example.org` for your ELB into the zone.

Next, boot EC2 instance and deploy CoreDNS binary, and configure CoreDNS config file as below.

Expand Down Expand Up @@ -60,14 +64,14 @@ The `test.sub.example.org` is resolved with *AUTHORITY SECTION* and *ADDITIONAL
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 23246de45b4a3601 (echoed)
;; QUESTION SECTION:
;test.sub.example.org. IN A
;test.sub.example.org. IN A
;; ANSWER SECTION:
test.sub.example.org. 60 IN A 10.0.0.10
test.sub.example.org. 60 IN A 10.0.0.10
;; AUTHORITY SECTION:
sub.example.org. 60 IN NS ns1.sub.example.org.
sub.example.org. 60 IN NS ns2.sub.example.org.
sub.example.org. 60 IN NS ns1.sub.example.org.
sub.example.org. 60 IN NS ns2.sub.example.org.
;; ADDITIONAL SECTION:
ns1.sub.example.org. 60 IN A 192.168.0.1
Expand Down Expand Up @@ -95,11 +99,11 @@ Also it can return NS record(s) for subdomain as below.
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: c1c3332966dba8fd (echoed)
;; QUESTION SECTION:
;sub.example.org. IN NS
;sub.example.org. IN NS
;; ANSWER SECTION:
sub.example.org. 60 IN NS ns1.sub.example.org.
sub.example.org. 60 IN NS ns2.sub.example.org.
sub.example.org. 60 IN NS ns1.sub.example.org.
sub.example.org. 60 IN NS ns2.sub.example.org.
;; ADDITIONAL SECTION:
ns1.sub.example.org. 60 IN A 192.168.0.1
Expand All @@ -111,3 +115,39 @@ ns2.sub.example.org. 60 IN A 192.168.0.2
;; MSG SIZE rcvd: 125
```
And it works like Route 53 alias record when answering CNAME record.
Your CNAME record will be removed and A/AAAA records of the CNAME record will be replaces.
```bash
> dig @localhost lb.sub.example.org
; <<>> DiG 9.11.1 <<>> @localhost test.sub.example.org +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63630
;; flags: qr aa ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 89a840e16b4d3fc7 (echoed)
;; QUESTION SECTION:
;lb.sub.example.org. IN A
;; ANSWER SECTION:
lb.sub.example.org. 54 IN A 10.0.0.16
lb.sub.example.org. 54 IN A 10.0.0.132
;; AUTHORITY SECTION:
sub.example.org. 60 IN NS ns1.sub.example.org.
sub.example.org. 60 IN NS ns2.sub.example.org.
;; ADDITIONAL SECTION:
ns1.sub.example.org. 60 IN A 192.168.0.1
ns2.sub.example.org. 60 IN A 192.168.0.2
;; Query time: 11 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Feb 27 11:20:08 JST 2018
;; MSG SIZE rcvd: 174
```
57 changes: 56 additions & 1 deletion amazondns.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ L:
m.Answer = resp.Answer
m.Rcode = resp.Rcode

// It's useful resolving CNAME for DNS of ELB, RDS and so on
resolveCNAME(name, m)

// Overwrite authority and additional section
if len(m.Answer) > 0 {
m.Ns = zone.ns
Expand Down Expand Up @@ -96,6 +99,7 @@ L:

state.SizeAndDo(m)
m, _ = state.Scrub(m)

w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
Expand Down Expand Up @@ -124,7 +128,58 @@ func handleNotFound(zone *Zone, name string, m *dns.Msg) {
m.Rcode = dns.RcodeNameError
}

func (ad *AmazonDNS) fillResponse(state request.Request, m *dns.Msg) {
func resolveCNAME(reqName string, res *dns.Msg) {
ignore := map[string]struct{}{}

for {
var name string
var cname string
var ttl uint32
cnameIndex := -1

// Find CNAME record
for i, rr := range res.Answer {
if rr.Header().Rrtype == dns.TypeCNAME {
name = rr.Header().Name

if name != reqName {
continue
}

if _, ok := ignore[name]; ok {
continue
}

cname = rr.(*dns.CNAME).Target
ttl = rr.Header().Ttl

cnameIndex = i
break
}
}

if cnameIndex == -1 {
break
}

var replaced bool

// Replace records belong to CNAME record
for _, rr := range res.Answer {
if rr.Header().Name == cname {
rr.Header().Name = name
rr.Header().Ttl = ttl
replaced = true
}
}

// Remove CNAME record
if replaced {
res.Answer = append(res.Answer[:cnameIndex], res.Answer[cnameIndex+1:]...)
} else {
ignore[name] = struct{}{}
}
}
}

// Name implements the Handler interface.
Expand Down
12 changes: 9 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
#!/bin/sh

VERSION=0.1
TAG=master
VERSION=0.2
TAG=b1ce9ed6e5b6178fbfa73d3764d25a6e1f20fc82
CADDY_TAG=37b291f82c2083a378b698577640389686b0baf4

if [ "$1" = "" ]; then
docker run --rm \
-v $(pwd):/go/src/github.com/wadahiro/coredns-amazondns \
-v $(pwd)/.tmp:/go \
-w /go/src/github.com/wadahiro/coredns-amazondns \
golang:1.9 ./build.sh $TAG
golang:1.9 ./build.sh $TAG $CADDY_TAG
else
echo "Building CoreDNS:$1 with amazondns..."

go get github.com/coredns/coredns

cd /go/src/github.com/mholt/caddy

git checkout $2

cd /go/src/github.com/coredns/coredns

git reset --hard HEAD
Expand Down

0 comments on commit 9ee9408

Please sign in to comment.