Knot DNS と isc-kea による DHCP-DDNS を構築してみた with TSIG

## 前提
Knot DNS ならびに isc-kea の構築は以下の環境、手順で行われたと仮定します。

https://qiita.com/ahra_/items/273394cf29fbfb546ce1

https://qiita.com/ahra_/items/4c167c235b52c9869be8

Knot DNS サーバーの IP アドレスが`192.168.182.10`、isc-kea DHCP サーバーが`192.168.182.15`です。
DHCP サーバーから `example.com.` および `182.168.192.in-addr.arpa.` ゾーンの名前解決が可能であることを前提とします。
## Knot DNS の設定
まずは更新を許可する ACL を追加します。
```diff:/etc/knot/knot.conf
server:
    rundir: "/run/knot"
    user: knot:knot
    listen: [ 127.0.0.1@53, 192.168.182.10@53 ]
    identity:
    version:
    
log:
  - target: /var/log/knot.log
    any: info

database:
    storage: "/var/lib/knot"
    
mod-queryacl: # 通常の DNS クエリを受け付ける範囲を制限
  - id: default
    address: [192.168.182.0/24,192.168.207.0/24,127.0.0.0/8]
    interface: [192.168.182.10,127.0.0.1]

+ acl:
+  - id: ddns
+    address: 192.168.182.15
+    action: update

    
template:
  - id: default
    storage: "/var/lib/knot/zonefile"
    file: "%s.zone"
    semantic-checks: on
    module: mod-queryacl/default
+    acl: ddns
    
zone:
  - domain: example.com

  - domain: 182.168.192.in-addr.arpa
    file: 182.168.192.in-addr.arpa.zone
    reverse-generate: example.com # example.com ゾーンの A/AAAA から PTR を生成
```
設定をリロードします。
```
# knotc conf-check
# knotc reload
```
この状態であれば、`192.168.182.15` から `nsupdate` による更新が可能です。
```
# nsupdate
> update add test2.example.com. 3600 A 192.168.182.22
> update add 23.182.168.192.in-addr.arpa. 3600 PTR test3.example.com. 
```
```
# knotc zone-read --
（前略）
[182.168.192.in-addr.arpa.] 22.182.168.192.in-addr.arpa. 3600 PTR test2.example.com.
[182.168.192.in-addr.arpa.] 23.182.168.192.in-addr.arpa. 3600 PTR test3.example.com.
（中略）
[example.com.] test2.example.com. 3600 A 192.168.182.22
```
### TSIG の設定
TSIG 鍵を生成します。
生成した TSIG 鍵は DDNS サーバーの設定の際にも使用するので、メモしておきましょう。（実行結果の `secret: <この文字列>` がTSIG 鍵です）
```
# keymgr -t ddns hmac-sha512
```
TSIG 鍵と ACL に TSIG 鍵を使用するようにする設定を追加します。
```/etc/knot/tsig-keys.conf
key: 
  - id: ddns
    algorithm: hmac-sha512
    secret: <TSIG 鍵>
```
```diff:/etc/knot/knot.conf
server:
    rundir: "/run/knot"
    user: knot:knot
    listen: [ 127.0.0.1@53, 192.168.182.23@53 ]
    identity:
    version:
    
log:
  - target: syslog
    any: info

database:
    storage: "/var/lib/knot"
    
mod-queryacl: # 通常の DNS クエリを受け付ける範囲を制限
  - id: default
    address: [192.168.182.0/24,192.168.207.0/24,127.0.0.0/8]
    interface: [192.168.182.23,127.0.0.1]

+ include: tsig-keys.conf

acl:
  - id: ddns
    address: 192.168.182.25
    action: update
+    key: ddns
    
template:
  - id: default
    storage: "/var/lib/knot/zonefile"
    file: "%s.zone"
    semantic-checks: on
    module: mod-queryacl/default
    acl: ddns
    
zone:
  - domain: test.example.com

  - domain: 182.168.192.in-addr.arpa
    file: 182.168.192.in-addr.arpa 
    reverse-generate: test.example.com # test.example.com ゾーンの A/AAAA から PTR を生成
```
TSIG 鍵が意図しないユーザーに確認されないよう、所有者とパーミッションを変更します。
その後、設定をリロードします。
```
# chown knot:knot /etc/knot/tsig-keys.conf
# chmod 600 /etc/knot/tsig-keys.conf
# knotc conf-check
# knotc reload
```
これで、TSIG 鍵なしでの更新が不可能になります。
```
# nsupdate
> update add test3.example.com. 3600 A 192.168.182.23
update failed: NOTAUTH
> update add 24.182.168.192.in-addr.arpa. 3600 PTR test4.example.com.
update failed: NOTAUTH
```
TSIG 鍵を用いた `nsupdate` は可能です。
```
# nsupdate -y hmac-sha512:ddns:<TSIG鍵>
> update add test3.example.com. 3600 A 192.168.182.23
> update add 24.182.168.192.in-addr.arpa. 3600 PTR test4.example.com.
```
```
# knotc zone-read --
（前略）
[182.168.192.in-addr.arpa.] 24.182.168.192.in-addr.arpa. 3600 PTR test4.example.com.
（中略）
[example.com.] test3.example.com. 3600 A 192.168.182.23
```
## isc-kea の設定
[他記事の手順](https://qiita.com/ahra_/items/7d66c2a84b0b132cabd3#isc-kea-%E3%81%AE%E8%A8%AD%E5%AE%9A)と同一なため割愛します。
## 確認
DHCP によるアドレスのリースが発生すると、リースされた IP アドレスとリース先クライアントのホスト名での A レコード、PTR レコード、DHCID レコードが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900965/cb59bccd-fc25-4a72-bb0f-f92a73183db4.png)
```
# knotc zone-read --
（前略）
[182.168.192.in-addr.arpa.] 16.182.168.192.in-addr.arpa. 28800 PTR dhcp-test.example.com.
[182.168.192.in-addr.arpa.] 16.182.168.192.in-addr.arpa. 28800 DHCID <DHCID>
（中略）
[example.com.] dhcp-test.example.com. 28800 A 192.168.182.16
[example.com.] dhcp-test.example.com. 28800 DHCID <DHCID>
（後略）
```