AnsibleでPowerDNSのRecursor(キャッシュDNS)を動かす

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

PowerDNSのインストール記事は幾つか見つかるのですが、Ansibleでインストールした記事がなかったので、書いてみました。Dockerで動かすのもよいのですが、別に頻繁に更新するものでも無し、Dockerで動かす必要もないなぁと思ったのがきっかけです。

# 1. PowerDNS Recursorてなに？

DNSのキャッシュサーバーのことです。以上

# 2. PowerDNS RecursorのAnsibleのPlaybookのGalaxy

PowerDNS社がAnsible GalaxyでAnsibleスクリプトを公開していますのでこちらをありがたく使わせていただきましょう。

Ansible Galaxy \- PowerDNS\.pdns\_recursor 

https://galaxy.ansible.com/ui/standalone/roles/PowerDNS/pdns_recursor/

# 3. 環境

以下のような環境にインストールします。

1. HW : Proxmox 8.3 CT(LXCコンテナ)
1. OS : Ubuntu 22.04
1. IP : 192.0.2.53/24

# 4. 前準備

PowerDNSを動かすProxmox CTを普通にデプロイします。環境に依存する事もないでしょう。

追記に書いていますが、LXCコンテナ作成時に以下のDNSサーバーを入力すると、DNS Local Stub Resolverが動かなくなるという事を発見したのですが、一旦は以下の様に何も入れないで動かしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/00cf4ab7-d362-8743-7633-3addc8e3ab1c.png)

Ubuntuは、16.04から悪名高い？DNS Local stub resolverが動いています。普通に使う分にはとても便利なものですが、DNSサーバーを動かす時には厄介な代物です。
まず、こいつを停止します。
`DNSStubListener=no`を`/etc/systemd/resolved.conf`に書いて、systemd-resolvedを再起動するというのがよくある記事の内容ですが、それだけだとDNSサーバーが消えてしまうので、以下のように`DNS=192.0.2.53`も追記しています。

```configuration:/etc/systemd/resolved.conf
[Resolve]
DNS=192.0.2.53
DNSStubListener=no
```

次に、`/etc/resolv.conf`が`/run/systemd/resolve/stub-resolv.conf`にシンボリックリンクになっているので削除します。その後、`/run/systemd/resolve/resolv.conf`から`/etc/resolv.conf`にシンボリックを張り直します。

```
$ sudo rm -rf /etc/resolv.conf
$ cd /etc
$ sudo ln -sf ../run/systemd/resolve/resolv.conf resolv.conf
```

systemd-resolvedを再起動します。

```
$ sudo systemctl restart systemd-resolved
```

# 5. Ansible GalaxyからPowerDNS\.pdns\_recursor をインストール

```
$ ansible-galaxy role install PowerDNS.pdns_recursor
```

# 6. インベントリーのhostsファイルを作成

インベントリーファイルはローカルに設定するだけなので、Localだけ書いておけばいいでしょう。

```ini: hosts
[pdns_recursors]
127.0.0.1
```

# 7. Playbookファイルを作成

Playbookもlocalに接続するだけなので、`connection: local`として、varsもplaybookに直接書きましょう。


```yaml:playbook.yml
- hosts: pdns_recursors
  connection: local
  vars:
    pdns_rec_config:
      allow-from: "192.0.2.0/24"
      local-address: "0.0.0.0"
  roles:
    - { role: PowerDNS.pdns_recursor }
```

ファイルの解説

|項目名|説明|
|---|---|
|pdns_rec_config.allow-from|RecursorでQueryを受け付けるIPアドレスレンジ|
|pdns_rec_config.local-address|RecursorがQueryを受け付けるIPアドレス|

# 8. Ansible Playbookの実行

インベントリーファイルとplaybookが揃ったのでAnsibleを実行します。

```
$ ansible-playbook -i ./hosts ./playbook.yml
```

# 9. テスト

```
# dig www.yahoo.co.jp

; <<>> DiG 9.18.1-1ubuntu1-Ubuntu <<>> www.yahoo.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51888
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
www.yahoo.co.jp.        900     IN      CNAME   edge12.g.yimg.jp.
edge12.g.yimg.jp.       60      IN      A       124.83.184.252

;; Query time: 68 msec
;; SERVER: 192.0.2.53#53(192.0.2.53) (UDP)
;; WHEN: Tue Dec 03 07:42:03 UTC 2024
;; MSG SIZE  rcvd: 88
```


# 10. varsの書き方

~/.ansible/roles/PowerDNS.pdns_recursor/defaults/main.yml
を見ると以下のような記述があるので、RecursorからAuthorityへの問合せ転送もできそうですね。

```yaml
pdns_rec_config:
 allow-from: '127.0.0.1/8,192.168.2.0/24'
 local-address: 0.0.0.0
 server-id: 'nothing to see here'
 forward-zones:
   - "example.com=192.0.2.2:5300;192.0.2.128"
   - "foo.example.com=2001:db8::abcd:1;[2001:db8::ef99]:5300"
```

# 11. 追記

と、ここまでかいてもう一回CTでLXCコンテナを作ってみるかと、作ったところ、DNSの部分にDNSサーバーのIPアドレスを入れると、DNS Local Stub Resolverが動かないので、4. 前準備が不要である事に気がつきました....。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/00cf4ab7-d362-8743-7633-3addc8e3ab1c.png)

# 12. 追記2

Ansible Galaxyを使うなら、requierments.ymlを書いておいて、

```yaml:requirements.yml
# Install a role from the Ansible Galaxy
- src: PowerDNS.pdns_recursor
```

README.mdに以下のように書いておけば良いのではないかと思います。

```
# Ansible Playbookを実行する前にGalaxyをインストールしてください。
ansible-galaxy install -r requirements.yml
```


# 12. まとめ

PowerDNSのキャッシュサーバーでした。昔は、BINDを使っていましたが楽になりました。

LXCコンテナ上でDockerコンテナを動かしてもいいのですが、コンテナInコンテナなのも無駄な気がしますし、これでいいんじゃないかなと思います。

# 13. 参考

https://qiita.com/suzuki_sh/items/d9d719cc6a6e1897fcf6