Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Debian 9 (Stretch)で Dnstap を利用した KnotDNS におけるクエリログの取得

More than 1 year has passed since last update.

1. KnotDNS / Dnstap とは

KnotDNS は CZ-NIC 社によって開発された権威DNSサーバです.
Dnstap は パケットキャプチャを利用せずに高速にDNSクエリを取得出来る仕組み及びツールです.

KnotDNS はDNSクエリログを取得する機能を標準で持たないため, Dnstap を外部モジュールという形で呼び出す必要があります. Bind や Unbound では参考記事があったのですが, KnotDNS に関する記事は無かったので, 備忘録として残してみます.

2. 想定環境

- OS: Debian 9.3 (Stretch)
- Utilities (Main):
  - Gcc: 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
  - G++: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
  - Fstrm: v0.4.0
  - Protobuf: v3.5.2
  - Protobuf-c: v1.3.0
  - Golang: go1.10.3 linux/amd64

- Tools:
  - KnotDNS: v2.6.8
  - Dnstap: ? (Master Branch)

上記環境を構築していきます. 今回の作業は全て root ユーザで行います.
※ 但し, OSに関しては予め展開されている事を想定しています.

3. 環境構築

ビルド用ツールの展開

# apt install -y tar wget curl unzip git vim resolvconf
# apt install -y git-core make gcc g++ libtool \
                 autoconf pkg-config liburcu-dev liblmdb-dev \
                 libgnutls28-dev libedit-dev libidn11-dev libevent-dev

Fstrm の展開

# git clone -b v0.4.0 https://github.com/farsightsec/fstrm.git /opt/fstrm
# cd /opt/fstrm
# ./autogen.sh
# ./configure 
# make
# make install
# ldconfig

Protobuf の展開
 Protobuf 3.6.x はビルドエラーにより断念, 代替として v3.5.2 を利用した

# git clone -b v3.5.2 https://github.com/google/protobuf.git /opt/protobuf
# cd /opt/protobuf
# ./autogen.sh
# ./configure
# make
# make install
# ldconfig

Protobuf-c の展開

# git clone -b v1.3.0 https://github.com/protobuf-c/protobuf-c.git /opt/protobuf-c
# cd /opt/protobuf-c
# ./autogen.sh
# ./configure
# make
# make install

KnotDNS の展開

# git clone -b v2.6.8 https://gitlab.labs.nic.cz/knot/knot-dns.git /opt/knot
# cd /opt/knot
# autoreconf -if
# ./configure \
  --sysconfdir=/etc
  --localstatedir=/var/lib
  --bindir=/usr/sbin
  --libexecdir=/usr/sbin
  --sbindir=/usr/sbin
  --with-rundir=/var/run/knot
  --with-storage=/var/lib/knot
  --enable-dnstap
  --with-module-dnstap=yes
  --enable-fastparser
  --enable-recvmmsg=yes
  --disable-silent-rules
  --disable-static
  --disable-documentation
# make
# make install
# ldconfig

KnotDNS の Systemd 設定

# cat << EOS > /lib/systemd/system/knot.service
[Unit]
Description=Knot DNS server
Wants=network-online.target
After=network-online.target

[Service]
EnvironmentFile=/etc/default/knot
ExecReload=/usr/sbin/knotc reload
ExecStart=/usr/sbin/knotd $KNOTD_ARGS
Restart=on-abort

[Install]
WantedBy=multi-user.target
EOS

# systemctl daemon-reload
# systemctl status knot.service

Golang の展開

# wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz -P /tmp
# cd /tmp
# tar -zxvf go1.10.3.linux-amd64.tar.gz
# mv go /usr/local/bin

Golang の有効化
 Golang におけるルートプロジェクトを /root/dnstap-golang に設定していますが,
 本番環境では適切なディレクトリに設定すべきです

# mkdir -p /root/dnstap-golang
# echo "export GOROOT=/usr/local/bin/go" >> ~/.bash_proifle
# echo "export GOPATH=/root/dnstap-golang" >> ~/.bash_profile
# echo "export PATH=$GOPATH/bin:$GOROOT/bin:$PATH" >> ~/.bash_profile
# source ~/.bash_profile

Dnstap の展開

# go get -u github.com/dnstap/golang-dnstap/dnstap

4. KnotDNS の初期起動及び設定

# knotc conf-init
# systemctl start knot.service
# systemctl status knot.service

5. KnotDNS への Dnstap の設定

 現在の KnotDNS では静的な設定ファイルからの Dnstap モジュール読込が何故か出来ないようです.
 なので, Dnstap 有効化の設定はCLI上から一つ一つ行う必要があります.

# knotc conf-begin
# knotc conf-set mod-dnstap.id capture_all
# knotc conf-set mod-dnstap.sink unix://var/run/knot/dnstap.sock
# knotc conf-set template.id default
# knotc conf-set template.global-module mode-dnstap/capture_all
# knotc conf-diff
# knotc conf-commit
# knotc reload

6. Dnstap の起動

 dnstap を実行する事で, 以下のログを得る事が出来るはずです.
 また, dnstap は何らかの方法 (Systemd, Supervisorctl) を利用して, BackGround で実行した方が良さそうです.
 ちなみに, オプション -y はデバッグモードでの起動を意味しています.

# dnstap -u /var/run/knot/dnstap.sock -w /var/log/dnstap.log -y
dnstap: opened input socket /var/run/knot/dnstap.sock
dnstap.FrameStreamSockInput: accepted a socket connection

7. DNSリクエストの送信

 dnstap を維持した状態で下記コマンドを実行します.
 レコード未登録の場合でも, クエリログは閲覧出来るため, 適当にDNSへリクエストを送信します

# kdig @localhost www.hogehoge.com
# kdig @localhost www.example.com

8. Dnstap でのクエリログの確認

 mod-dnstap の標準オプションでは, リクエスト及びレスポンスの両方が出力されます.

# cat /var/log/dnstap.log

type: MESSAGE
identity: "stretch.localdomain"
version: "Knot DNS 2.6.8"
message:
  type: AUTH_QUERY
  query_time: !!timestamp 2018-07-16 08:46:37
  socket_family: INET6
  socket_protocol: UDP
  query_address: ::1
  query_port: 42718
  query_message: |
    ;; opcode: QUERY, status: NOERROR, id: 1116
    ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;www.example.com.   IN       A
---
type: MESSAGE
identity: "stretch.localdomain"
version: "Knot DNS 2.6.8"
message:
  type: AUTH_RESPONSE
  response_time: !!timestamp 2018-07-16 08:46:37
  socket_family: INET6
  socket_protocol: UDP
  query_address: ::1
  query_port: 42718
  response_message: |
    ;; opcode: QUERY, status: REFUSED, id: 1116
    ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;www.example.com.   IN       A
---
type: MESSAGE
identity: "stretch.localdomain"
version: "Knot DNS 2.6.8"
message:
  type: AUTH_QUERY
  query_time: !!timestamp 2018-07-16 08:46:40
  socket_family: INET6
  socket_protocol: UDP
  query_address: ::1
  query_port: 35661
  query_message: |
    ;; opcode: QUERY, status: NOERROR, id: 61958
    ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;www.hogehoge.com.  IN       A
---
type: MESSAGE
identity: "stretch.localdomain"
version: "Knot DNS 2.6.8"
message:
  type: AUTH_RESPONSE
  response_time: !!timestamp 2018-07-16 08:46:40
  socket_family: INET6
  socket_protocol: UDP
  query_address: ::1
  query_port: 35661
  response_message: |
    ;; opcode: QUERY, status: REFUSED, id: 61958
    ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;www.hogehoge.com.  IN       A
---

9. おまけ

 dnstap のオプションに -q を付けると以下のようなクエリログ結果を出力する事が出来ます.

# cat /var/log/dnstap.log
08:51:13.000000 AQ ::1 UDP 34b "www.hogehoge.com." IN A
08:51:13.000000 AR ::1 UDP 34b "www.hogehoge.com." IN A
08:51:19.000000 AQ ::1 UDP 33b "www.example.com." IN A
08:51:19.000000 AR ::1 UDP 33b "www.example.com." IN A

10. 所感

  • CLI 上で動的にゾーンを変更出来るのはとても良い (予め定義した設定ファイルを読み込む事も出来る)
  • ネットワークデバイスへの設定を彷彿とさせるようなコマンドの使用感が良い
  • ドキュメントに一通り設定方法が書かれているが, 内容が割とざっくりなので読み解く必要があるのは辛い
  • レートリミットの設定や Any リクエストを無効化する方法など, DNSを介した攻撃への対策も一通りある (気がする)
  • RestAPI とかあったら良かったかな... PowerDNS を使えと言われればそれまでだけど...
ofumi3
Let it be
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away