Corednsをそのまま動かしてみる

k8sでcorednsって名前を見かけたりすることはあると思いますが、corednsって何なんでしょう。
プラグイン形式で機能を使えるのでコンテナ向き（むしろそのために）なDNSサーバです。
そいつを単体で動かしてみましょうという記事。

実はnanopi NEO3を買ったのでローカル用のDNSとして使うように入れてみた。

# tl;dr

実は難しくなかったのでgo buildして立ち上げるだけ。

# git pull & go build

リポジトリはここ。 https://github.com/coredns/coredns

Golangは1.13以上であれば大丈夫そう。

`go build` するとcorednsっていう実行ファイルが出来上がる。
まぁ直接バイナリを持ってきてもいい気がする。

# 設定ファイル

JSONっぽいけどJSONじゃない形式のsyntaxです。
https://coredns.io/manual/toc/#configuration

↓のような感じに書く。listenするポート番号をドメインごとに分けられたりする。

```
coredns.io:5300 {
    file db.coredns.io
}

example.io:53 {
    log
    errors
    file db.example.io
}

example.net:53 {
    file db.example.net
}

.:53 {
    kubernetes
    forward . 8.8.8.8
    log
    errors
    cache
}
```


# 立ち上げる

`-conf`でファイルを指定できる。しなかった場合には"カレント"ディレクトリのCorefileを読みに行く様子。
今回はこんな感じのCorefileを用意しました。

1055ポートで受けたものは8.8.8.8にフォワード、
10053で受けたものはderoris.netの内側IPを返す。

```
.:1055 {
    forward . 8.8.8.8
    whoami
    errors
    log
}
deroris.net:10053 {
    hosts {
        192.168.0.200 deroris.net
        192.168.0.200 rec.deroris.net

        fallthrough
    }
    whoami
}
```

立ち上がります。

```
root@NanoPi-NEO3:~/workspace/coredns# ./coredns -conf ./Corefile
.:1055
deroris.net.:10053
CoreDNS-1.8.0
linux/arm64, go1.15.3,
```

ポート指定してクエリを投げるとそれが返ってきます。

```
root@NanoPi-NEO3:~/workspace/coredns# dig @192.168.0.201 -p 1055 yahoo.co.jp # やほー返ってくる。

; <<>> DiG 9.16.1-Ubuntu <<>> @192.168.0.201 -p 1055 yahoo.co.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49911
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;yahoo.co.jp.                   IN      A

;; ANSWER SECTION:
yahoo.co.jp.            24      IN      A       182.22.59.229
yahoo.co.jp.            24      IN      A       183.79.135.206

;; Query time: 52 msec
;; SERVER: 192.168.0.201#1055(192.168.0.201)
;; WHEN: Thu Nov 05 03:56:51 UTC 2020
;; MSG SIZE  rcvd: 94

root@NanoPi-NEO3:~/workspace/coredns# dig @192.168.0.201 -p 1055 yahoo.co.jp # deroris.netのほうに聞いているので返ってこない。

; <<>> DiG 9.16.1-Ubuntu <<>> @192.168.0.201 -p 1055 yahoo.co.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59948
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;yahoo.co.jp.                   IN      A

;; ANSWER SECTION:
yahoo.co.jp.            243     IN      A       182.22.59.229
yahoo.co.jp.            243     IN      A       183.79.135.206

;; Query time: 48 msec
;; SERVER: 192.168.0.201#1055(192.168.0.201)
;; WHEN: Thu Nov 05 03:58:32 UTC 2020
;; MSG SIZE  rcvd: 94

root@NanoPi-NEO3:~/workspace/coredns# dig @192.168.0.201 -p 10053 deroris.net # 返ってくる。

; <<>> DiG 9.16.1-Ubuntu <<>> @192.168.0.201 -p 10053 deroris.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24578
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 1833cc8f28194fd3 (echoed)
;; QUESTION SECTION:
;deroris.net.                   IN      A

;; ANSWER SECTION:
deroris.net.            3600    IN      A       192.168.0.200

;; Query time: 0 msec
;; SERVER: 192.168.0.201#10053(192.168.0.201)
;; WHEN: Thu Nov 05 03:58:41 UTC 2020
;; MSG SIZE  rcvd: 79
```

ログも出る。

```
root@NanoPi-NEO3:~/workspace/coredns# ./coredns -conf ./Corefile
.:1055
deroris.net.:10053
CoreDNS-1.8.0
linux/arm64, go1.15.3,
[INFO] 192.168.0.201:38939 - 48721 "A IN yahoo.co.jp. udp 52 false 4096" NOERROR qr,rd,ra 94 0.034145548s
```

設定ファイルを変更した場合には、 `pkill -10 coredns` でリロードされます。

↑の直接Corefileにhostを書く書き方だとワイルドカードの指定はできないようです。zoneファイルで作ればいけるかな。
裏のDBにredisを使ったりと、DBはいろいろ選べるのがプラグイン形式の良いところか。
あとポート毎にクエリを分ける使い道が思いつかないｗ

# Dockerにしてみよう。

これだけだと寂しいのでDockerにしてみましょう。リポジトリにあるやつだとCorefileをコピーしていないので、下記のような感じでDockerfileとCorefileを作ってみました。


```
root@NanoPi-NEO3:~/workspace/coredns-deroris# ll
total 16
drwxr-xr-x 2 root root 4096 Nov  4 09:44 ./
drwxr-xr-x 4 root root 4096 Nov  4 09:42 ../
-rw-r--r-- 1 root root  227 Nov  4 09:42 Corefile
-rw-r--r-- 1 root root  117 Nov  4 09:44 Dockerfile
root@NanoPi-NEO3:~/workspace/coredns-deroris# cat Dockerfile
FROM coredns/coredns:latest

COPY Corefile /Corefile

EXPOSE 53 53/udp
ENTRYPOINT ["/coredns", "-conf", "/Corefile"]
root@NanoPi-NEO3:~/workspace/coredns-deroris# cat Corefile
. {
    forward . 8.8.8.8
    whoami
    errors
    log
}
deroris.net {
    hosts {
        192.168.0.200 deroris.net
        192.168.0.200 rec.deroris.net

        fallthrough
    }
#    forward . 8.8.8.8
    whoami
}
```

起動させればOK。deroris.netクエリが来たときはそれをみて、それ以外は8.8.8.8フォワード。

```
root@NanoPi-NEO3:~/workspace/coredns-deroris# docker run -p 53:53/udp coredns-deroris
deroris.net.:53
.:53
CoreDNS-1.8.0
linux/arm64, go1.15.3, 054c9ae
```

この2ファイルを用意しておけばお手軽にDNSサーバを移動できますね。

# まとめ

まぁこの用途だとdnsmasq, systemd-resolve等でもよさそうですが、せっかくなのでお試ししてみました。設定ファイルの書式がちょっと特殊なので毎度ググるマンですね。hosts, forward, whoami, logなどすべてプラグイン形式みたいです。
https://coredns.io/plugins/