はじめに
dnstapというものの存在を知ったので、一先ずどういったものか試してみます。
せっかくなので導入方法の日本語情報を残します。
-
dnstapとは
- http://dnstap.info/
- DNSソフトウェアのための構造化された柔軟なバイナリログ
- 高速、低負荷
- DNSリクエスト、応答をロギング可能
- 必要ライブラリ等を準備し、対応したDNSソフトウェアで設定を行うことで取得が可能
-
手順について
- 基本的には http://dnstap.info/ に記載の通りです
- パスの恒久的な設定やインストール先の変更は必要に応じて実施してください
- 手順の簡易化のためrootアカウントで作業を行っております
- 正しくsudoコマンドを使用すればrootアカウントで操作(ログイン)する必要はありません
使用した環境
- OS
- CentOS 6.6
- SELINUX=disabled
- CentOS 6.6
- DNS Server
- Unbound 1.5.10
- OTHER
- fstrm 0.2.0
- protobuf-c 1.2.1
導入手順
fstrmインストール
fstrmに必要なパッケージのインストール
./configure@fstrm
configure.ac:1: error: Autoconf version 2.64 or higher is required
./configure@fstrm
configure: error: Package requirements (libevent >= 2) were not met:
No package 'libevent' found
# yum install automake libtool libevent2-devel.x86_64[^1]
# rpm -qa | grep -e automake -e libtool -e libevent2
automake-1.11.1-4.el6.noarch
libevent2-2.0.21-2.el6.x86_64
libtool-2.2.6-15.5.el6.x86_64
libevent2-devel-2.0.21-2.el6.x86_64
# cd /usr/local/src/
# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
# tar xf autoconf-2.69.tar.gz
# cd autoconf-2.69
# ./configure
# make; echo $?
(略)
0
# make install
# autoconf --version | head -n 1
autoconf (GNU Autoconf) 2.69
fstrmインストール
# cd /usr/local/src/
# git clone https://github.com/farsightsec/fstrm.git
# cd fstrm/
# ./autogen.sh
# ./configure
(略)
fstrm 0.2.0
compiler: gcc -std=gnu99
cflags: -g -O2 -pthread
ldflags:
libs: -lrt
prefix: /usr/local
sysconfdir: ${prefix}/etc
libdir: ${exec_prefix}/lib
includedir: ${prefix}/include
pkgconfigdir: ${libdir}/pkgconfig
# make; echo $?
(略)
0
# make install
# echo '/usr/local/lib' >> /etc/ld.so.conf.d/usr-local-lib.conf
# ldconfig
# ldconfig -p | grep fstrm
libfstrm.so.0 (libc6,x86-64) => /usr/local/lib/libfstrm.so.0
libfstrm.so (libc6,x86-64) => /usr/local/lib/libfstrm.so
protobuf-cインストール
protobuf-cに必要なパッケージのインストール
- protobufは2.6.0以上のバージョン3
- protobufの最新版(3.1.0)をインストールしようとするとmakeが通りませんでした
- 力不足で解決できず、とりあえず古いバージョンを採用したところ先に進めました
# yum install gcc-c++ unzip
# rpm -qa | grep -e gcc-c++ -e unzip
gcc-c++-4.4.7-17.el6.x86_64
unzip-6.0-4.el6.x86_64
# cd /usr/local/src/
# wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
# tar xf protobuf-2.6.1.tar.gz
# cd protobuf-2.6.1
# ./autogen.sh
# ./configure
# make; echo $?
(略)
0
# make check
(略)
Testing output to jar...
./google/protobuf/compiler/zip_output_unittest.sh: line 76: jar: コマンドが見つかりません
Warning: 'jar' command not available. Skipping test.
PASS
PASS: google/protobuf/compiler/zip_output_unittest.sh
==================
All 4 tests passed
==================
(略)
# make install
# ldconfig
# protoc --version
libprotoc 2.6.1
# ls -l /usr/local/lib/pkgconfig/protobuf*
-rw-r--r-- 1 root root 397 12月 12 09:06 2016 /usr/local/lib/pkgconfig/protobuf-lite.pc
-rw-r--r-- 1 root root 412 12月 12 09:06 2016 /usr/local/lib/pkgconfig/protobuf.pc
# echo $PKG_CONFIG_PATH
# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
# echo $PKG_CONFIG_PATH
/usr/local/lib/pkgconfig
protobuf-cインストール
# cd /usr/local/src/
# git clone https://github.com/protobuf-c/protobuf-c.git
# cd protobuf-c/
# ./autogen.sh
# ./configure
(略)
protobuf-c 1.2.1
CC: gcc -std=gnu99
CFLAGS: -g -O2
CXX: g++
CXXFLAGS: -g -O2
LDFLAGS:
LIBS:
prefix: /usr/local
sysconfdir: ${prefix}/etc
libdir: ${exec_prefix}/lib
includedir: ${prefix}/include
pkgconfigdir: ${libdir}/pkgconfig
bigendian: no
protobuf version: libprotoc 2.6.1
# make; echo $?
(略)
0
# make install
# protoc-c --version
protobuf-c 1.2.1
libprotoc 2.6.1
Unboundインストール
Unboundに必要なパッケージのインストール
# yum install openssl-devel expat-devel
# rpm -qa | grep -e openssl -e expat
expat-devel-2.0.1-13.el6_8.x86_64
expat-2.0.1-13.el6_8.x86_64
openssl-devel-1.0.1e-48.el6_8.3.x86_64
openssl-1.0.1e-48.el6_8.3.x86_64
Unboundインストール
- Unboundは1.5.0以上のバージョンでdnstapに対応
# cd /usr/local/src/
# wget http://unbound.net/downloads/unbound-1.5.10.tar.gz
# tar xf unbound-1.5.10.tar.gz
# cd unbound-1.5.10
# ./configure --enable-dnstap
# make; echo $?
0
# make install
# unbound -h | grep Version
Version 1.5.10
# ldconfig
# ldconfig -p | grep unbound
libunbound.so.2 (libc6,x86-64) => /usr/local/lib/libunbound.so.2
libunbound.so (libc6,x86-64) => /usr/local/lib/libunbound.so
Unbound設定・起動
- 詳細な設定や、パフォーマンスチューニングは今回は対象外
ユーザ、グループの作成
# groupadd --system unbound
# useradd --system -g unbound unbound
# grep unbound /etc/group /etc/passwd
/etc/group:unbound:x:498:
/etc/passwd:unbound:x:498:498::/home/unbound:/bin/bash
# chown unbound:unbound /usr/local/etc/unbound
trust anchor(DNSSEC)の準備
# sudo -u unbound mkdir /usr/local/etc/unbound/key
# sudo -u unbound /usr/local/sbin/unbound-anchor -a /usr/local/etc/unbound/key/root.key
# ls -l /usr/local/etc/unbound/key/root.key
-rw-r--r-- 1 unbound unbound 759 12月 12 09:19 2016 /usr/local/etc/unbound/key/root.key
リモートコントロールの準備
# sudo -u unbound `which unbound-control-setup`
# ls -l /usr/local/etc/unbound/*{.key,.pem}
-rw-r----- 1 unbound unbound 2455 12月 12 09:38 2016 /usr/local/etc/unbound/unbound_control.key
-rw-r----- 1 unbound unbound 1330 12月 12 09:38 2016 /usr/local/etc/unbound/unbound_control.pem
-rw-r----- 1 unbound unbound 2455 12月 12 09:38 2016 /usr/local/etc/unbound/unbound_server.key
-rw-r----- 1 unbound unbound 1318 12月 12 09:38 2016 /usr/local/etc/unbound/unbound_server.pem
dustup用ディレクトリ作成
# sudo -u unbound mkdir /usr/local/etc/unbound/dnstap/
# ls -ld /usr/local/etc/unbound/dnstap/
drwxr-xr-x 2 unbound unbound 4096 12月 12 09:51 2016 /usr/local/etc/unbound/dnstap/
設定ファイル編集
# cp -ip /usr/local/etc/unbound/unbound.conf{,_org}
# ls -l /usr/local/etc/unbound/unbound.conf{,_org}
# vim /usr/local/etc/unbound/unbound.conf
# diff /usr/local/etc/unbound/unbound.conf{,_org}
664c664
< control-enable: yes
---
> # control-enable: no
721,727d720
< dnstap:
< dnstap-enable: yes
< dnstap-socket-path: "/dnstap/dnstap.sock"
< dnstap-send-identity: yes
< dnstap-send-version: yes
< dnstap-log-resolver-response-messages: yes
< dnstap-log-client-query-messages: yes
起動・確認
# unbound-control start
# unbound-control status
version: 1.5.10
verbosity: 1
threads: 1
modules: 2 [ validator iterator ]
uptime: 297 seconds
options: control(ssl)
unbound (pid 30584) is running...
# tail /var/log/messages
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: init module 0: validator
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: init module 1: iterator
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: attempting to connect to dnstap socket /dnstap/dnstap.sock
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: dnstap identity field set to "dnstap.localhost"
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: dnstap version field set to "unbound 1.5.10"
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: dnstap Message/RESOLVER_RESPONSE enabled
Dec 12 10:26:10 dnstap unbound: [30584:0] notice: dnstap Message/CLIENT_QUERY enabled
Dec 12 10:26:10 dnstap unbound: [30584:0] info: start of service (unbound 1.5.10).
dnstap(command-line tool)インストール
go-langインストール
# cd /usr/local/
# wget https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz
# tar xf go1.7.4.linux-amd64.tar.gz
# /usr/local/go/bin/go version
go version go1.7.4 linux/amd64
dnstapインストール
# mkdir /usr/local/go/work
# export GOPATH=/usr/local/go/work/
# /usr/local/go/bin/go get -u -v github.com/dnstap/golang-dnstap
# /usr/local/go/bin/go get -u -v github.com/dnstap/golang-dnstap/dnstap
dnstap使用
-
ソケットはUnboundがアクセスできる必要があるため、unboundユーザを指定します
-
Unboundはデフォルト設定でchrootが設定されるため、それを考慮したパスを指定します
unbound.conf(1.5.10)chroot: "/usr/local/etc/unbound"
-
dnstapコマンドを使ってUNIXソケットを作成、一先ず標準出力にログを出力
# sudo -u unbound /usr/local/go/work/bin/dnstap -u /usr/local/etc/unbound/dnstap/dnstap.sock
dnstap: opened input socket /usr/local/etc/unbound/dnstap/dnstap.sock
dnstap.FrameStreamSockInput: accepted a socket connection
10:37:00.867951 CQ ::1 UDP 29b "dnstap.info." IN A
10:37:00.911424 RR 193.0.14.129 UDP 1097b "." IN NS
10:37:00.946684 RR 193.0.14.129 UDP 814b "dnstap.info." IN A
10:37:01.043128 RR 199.249.121.1 UDP 604b "dnstap.info." IN A
10:37:01.069026 RR 192.5.5.241 UDP 871b "ns6.dnsmadeeasy.com." IN A
10:37:01.075176 RR 192.36.148.17 UDP 871b "ns6.dnsmadeeasy.com." IN AAAA
- verboseモードで出力
# sudo -u unbound /usr/local/go/work/bin/dnstap -u /usr/local/etc/unbound/dnstap/dnstap.sock -y
dnstap: opened input socket /usr/local/etc/unbound/dnstap/dnstap.sock
dnstap.FrameStreamSockInput: accepted a socket connection
type: MESSAGE
identity: "dnstap.localhost"
version: "unbound 1.5.10"
message:
type: CLIENT_QUERY
query_time: !!timestamp 2016-12-12 01:46:46.984486
socket_family: INET6
socket_protocol: UDP
query_address: ::1
query_port: 48319
query_message: |
;; opcode: QUERY, status: NOERROR, id: 54132
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;dnstap.info. IN A
さいごに
- dnstapはUnbound専用の機能ではなく、例えばISC BINDも対応済みです
- 複数のDNSソフトウェアを使用する環境においても同じログを得られます
- https://kb.isc.org/article/AA-01342/0/Using-DNSTAP-with-BIND-9.11.html
- dnstap(command-line tool)は今回使用した go-lang のものの他にも、ISC BINDの dnstap-read や、UnboundのNLnetLabsが提供する dnstap-ldns など多数の実装がある模様
- UNIXソケットの作成は fstrm_capture コマンドでも行うことができ、ファイルに出力を行う際のローテーと間隔(秒)も指定することができる模様
- 他のDNSソフトウェアでの使用や、クエリログとの負荷具合の比較、各種ツールの使い勝手の比較、実際の運用方法の検討といったテーマはまたの機会があれば
おまけ
- 設定の不備で上手くログが取得できないことがあったが、今回は以下のstraceコマンドで原因が判明しました
- (No such file・・・? lsしたら見えるんだけどな・・・)
- 答え:chrootされていることを忘れ、ソケットのパスを誤って指定していた
# strace -f -p `pgrep unbound` 2>&1 | grep dnstap
[pid 30585] connect(12, {sa_family=AF_LOCAL, sun_path="/dnstap/dnstap.sock"}, 110) = -1 ENOENT (No such file or directory)
[pid 30585] connect(12, {sa_family=AF_LOCAL, sun_path="/dnstap/dnstap.sock"}, 110) = -1 ENOENT (No such file or directory)
参考
以下、注釈
./configure@protobuf-c
configure: error: Package requirements (protobuf >= 2.6.0) were not met:
No package 'protobuf' found