5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【学習メモ】unboundをインストールして最適化と言われる内容を適用する

Posted at

はじめに

LAN内にキャッシュDNSサーバーを作るのにかんたん・はやい・あんぜんなunboundを選択しました。
unboundをdnfでインストールして最適化しようとしたところ、libeventを使わないとスレッドの制限がある…というのを見たのでソースインストールしてみました。

参考資料
Unboundの最適化(unbound.jp)
最適化の方法(unbound.jp)

環境

CentOS Linux release 8.0.1905 (Core)
unbound 1.9.4

# cd /usr/local/src
# mkdir unbound
# cd !:1
# wget https://github.com/NLnetLabs/unbound/archive/release-1.9.6.tar.gz
# tar xf release-1.9.6.tar.gz
# chown -R root. unbound-release-1.9.6
# cd !:3

展開した中身の確認

LICENSE         aclocal.m4        compat        configure.ac  dnstap       ipset        pythonmod  systemd.m4  winrc
Makefile.in     acx_nlnetlabs.m4  config.guess  contrib       doc          iterator     respip     testcode
README          acx_python.m4     config.h.in   daemon        edns-subnet  libunbound   services   testdata
README.md       ax_pthread.m4     config.sub    dns64         install-sh   ltmain.sh    sldns      util
ac_pkg_swig.m4  cachedb           configure     dnscrypt      ipsecmod     makedist.sh  smallapp   validator

コンフィグの確認

configureオプションを見ていきます。
prefixなど設定するものと、パフォーマンスに影響しそうなものをピックアップしていきます。

--prefix=PREFIX

インストール先。

--enable-systemd

systemdで監理できるようになります。

--disable-sha1

Disable SHA1 RRSIG support,
does not disable nsec3 support 

DNSSECのRRset(各FQDN)に使われる署名のアルゴリズムで、SHA1を使わないようにする(その場合はDNSSECの連鎖が止まる?)もの。
sha1をセキュリティ強度が下がっているということなので、無効にしたほうが良さそうです。
不在証明で使われるnsec3のリソースレコードのハッシュで使われるSHA1は無効にしないもののようです。
RRSIGリソースレコード(jprs.jp)
DNESSECの基礎概要(nic.ad.jp)
が、SHA1も多いよう(2017年末現在)なので、無効化するのはやめておいたほうが良さそうです。
世界と日本のDNSSEC(www.slideshare.net/IIJ_PR)

--enable-subnet

EDNSを有効にする設定のようです。
EDNS Client Subnetとは(nic.ad.jp)

--disable-gost

GOST署名なるものあるようですが、ほとんど記事がなくなんのことだかわかりません。
GOSTにも 94と2012があるようです。
Use of GOST Signature Algorithms in DNSKEY and RRSIG Resource Records for DNSSEC(tools.ietf.org)
GOST (hash function)(en.wikipedia.org)

古いOpenSSLを使うようなときに設定するもののようです。
Unboundの紹介(unbound.jp)

--disable-ed448

そうなるとSHA3のED448もOPENSSLに対応していないので無効化する必要があるかもしれません。

# openssl version
OpenSSL 1.1.1 FIPS  11 Sep 2018

# openssl genpkey -algorithm ed448
-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOboQuO93oGq4RioFUosg3GUWNGQOZW2u7t1Jm7G0CSDp
swrd/ZXXLwGV190JYfPv+fpffkgMG3mP6g==
-----END PRIVATE KEY-----

組み込みのOpenSSLでも使えました。無効化する必要はありません。

--enable-fully-static

enable to compile fully static
静的にコンパイルしてくれます。
実行速度は速くなりそうです。

--enable-cachedb

キャッシュスdbモジュールを外部のキャッシュストレージを使って有効にする。
[Unbound][redis][自分用メモ] Unboundでbackendにredisを利用できることを今さらながら知った(blog.komeho.info)
のちのwith-libhiredisをつかえるようです

--with-libevent=pathname

本命です。

--with-libexpat=path

Unboundの紹介では、1.4.7移行で必要になるとあります。

--with-libhiredis=path

hiredisを追加します。

ライブラリのインストール

libevent

dnf install -y libevent libevent-devel

libexpat

dnf install -y expat expat-devel

libhiredis

epelにあるようなので、epelリポジトリを追加します。

https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/e/
最新は epel-release-8-7.el8.noarch.rpm でした。

cd /usr/local/src
dnf install -y https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/e/epel-release-8-7.el8.noarch.rpm 
dnf install -y hiredis hiredis-devel

Configureまとめ

./configure \
--prefix=/usr/local/unbound-1.9.4 \
--enable-systemd \
--enable-fully-static \
--enable-cachedb \
--with-libexpat \
--with-libhiredis

configureを実行します。

configure: error: systemd enabled but libsystemd not found

systemd-develを入れてみます。

dnf install -y systemd-devel
checking for SSL... configure: error: Cannot find the SSL libraries in /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr

Opensslのライブラリがないそうです。

入れます。

dnf install make gcc perl git expat-devel pcre-devel zlib-devel lksctp-tools lksctp-tools-devel kernel-modules-extra -y
cd /usr/local/src ; wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar xf openssl-1.1.1d.tar.gz
chown -R root. openssl-1.1.1d ; cd openssl-1.1.1d
./config --prefix=/usr/local/openssl-1.1.1d --openssldir=/usr/local/openssl-1.1.1d/shared enable-md2 enable-rc5 sctp zlib -fPIC
make -j3 && make install
cd /usr/local ; ln -s openssl-1.1.1d openssl
echo -e "/usr/local/openssl/lib" > /etc/ld.so.conf.d/openssl-1.1.1d.conf
echo -e 'OPENSSL_111D_PATH=/usr/local/openssl/bin\nPATH=$OPENSSL_111D_PATH:$PATH\nexport PATH' > /etc/profile.d/openssl-1.1.1d.sh
source /etc/profile.d/openssl-1.1.1d.sh ; ldconfig

opensslのパスを追加して、unboundのconfigureを通します。

./configure \
--prefix=/usr/local/unbound-1.9.4 \
--enable-systemd \
--enable-fully-static \
--enable-cachedb \
--with-ssl=/usr/local/openssl \
--with-libexpat \
--with-libhiredis
checking for libexpat... configure: error: Could not find libexpat, expat.h

libexpatが見つからないと怒られました。

しかしインストール済みです。

Package expat-2.2.5-3.el8.x86_64 is already installed.
Package expat-devel-2.2.5-3.el8.x86_64 is already installed.

# ls -la /usr/include/expat*
-rw-r--r-- 1 root root 43512  5月 11  2019 /usr/include/expat.h
-rw-r--r-- 1 root root  3517  5月 11  2019 /usr/include/expat_config.h
-rw-r--r-- 1 root root  5532  5月 11  2019 /usr/include/expat_external.h

.configureを見てみます。

19377 # check for libexpat
19378
19379 # Check whether --with-libexpat was given.
19380 if test "${with_libexpat+set}" = set; then :
19381   withval=$with_libexpat;

pathの指定ありなしで挙動が変わるようです。

19382 else
19383    withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
19384 fi

指定がないと、上記のディレクトリが検索対象になりそうな感じです。

19386 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libexpat" >&5
19387 $as_echo_n "checking for libexpat... " >&6; }
19388 found_libexpat="no"
19389 for dir in $withval ; do
19390             if test -f "$dir/include/expat.h"; then
19391                 found_libexpat="yes"
19392                                 if test "$dir" != "/usr"; then
19393                     CPPFLAGS="$CPPFLAGS -I$dir/include"
19394                     LDFLAGS="$LDFLAGS -L$dir/lib"
19395                 fi
19396                 { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
19397 $as_echo "found in $dir" >&6; }
19398                 break;
19399             fi
19400 done

--with-libexpat で configureすると、 1回目の$dirには yesが入っていました。
yes/include/expat.hは見つからないわけです。

libexpatのpathに/usrを指定してみます。
$dirに無事 /usr が入りました。
チェックも通りました。

checking for expat.h... yes

hiredisも問題ないようです。

checking for libhiredis... found in /usr
checking for hiredis/hiredis.h... yes

通ったconfigureオプション

./configure \
--prefix=/usr/local/unbound-1.9.4 \
--enable-systemd \
--enable-fully-static \
--enable-cachedb \
--with-ssl=/usr/local/openssl \
--with-libexpat=/usr \
--with-libhiredis
libtool: warning: complete static linking is impossible in this configuration
libtool: link: gcc -I. -I/usr/local/openssl/include -DSRCDIR=. -g -O2 -flto -pthread -o unbound-host .libs/unbound-host.o .libs/keyraw.o .libs/sbuffer.o .libs/wire2str.o .libs/parse.o .libs/parseutil.o .libs/rrdef.o .libs/str2wire.o .libs/strlcat.o .libs/strlcpy.o  -L/usr/local/openssl/lib -L. -L.libs /usr/local/src/unbound/unbound-release-1.9.6/.libs/libunbound.a -lssl -lsystemd -lcrypto -lhiredis -pthread  -Wl,-rpath -Wl,/usr/local/openssl/lib
/usr/bin/ld: Dwarf Error: Could not find abbrev number 4628.
/tmp/ccoIVbCd.ltrans0.ltrans.o: In function `check_ub_res.part.0':
<artificial>:(.text+0x42f5): undefined reference to `ub_strerror'
/tmp/ccoIVbCd.ltrans0.ltrans.o: In function `dnslook':
<artificial>:(.text+0x4524): undefined reference to `ub_resolve'
<artificial>:(.text+0x4973): undefined reference to `ub_resolve_free'
<artificial>:(.text+0x4aa3): undefined reference to `ub_strerror'
/tmp/ccoIVbCd.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x20): undefined reference to `ub_ctx_create'
<artificial>:(.text.startup+0x42): undefined reference to `ub_ctx_set_option'
<artificial>:(.text.startup+0x9e): undefined reference to `ub_ctx_add_ta'
<artificial>:(.text.startup+0xdb): undefined reference to `ub_ctx_resolvconf'
<artificial>:(.text.startup+0xfe): undefined reference to `ub_ctx_add_ta_file'
<artificial>:(.text.startup+0x15e): undefined reference to `ub_ctx_trustedkeys'
<artificial>:(.text.startup+0x17b): undefined reference to `ub_ctx_add_ta_file'
<artificial>:(.text.startup+0x19e): undefined reference to `ub_ctx_config'
<artificial>:(.text.startup+0x1c2): undefined reference to `ub_ctx_set_option'
<artificial>:(.text.startup+0x1f2): undefined reference to `ub_ctx_set_option'
<artificial>:(.text.startup+0x21c): undefined reference to `ub_ctx_debuglevel'
<artificial>:(.text.startup+0x238): undefined reference to `ub_ctx_get_option'
<artificial>:(.text.startup+0x26a): undefined reference to `ub_ctx_set_option'
<artificial>:(.text.startup+0x4e8): undefined reference to `ub_ctx_delete'
collect2: error: ld returned 1 exit status
make: *** [Makefile:339: unbound-host] エラー 1

おや…

undefined reference to `ub_resolve' で検索するとそれっぽいのが出てきました。
Unbound configuration --enable-static-exe breaks linker #3(github.com)
--disable-flto をconfigureで入れろとのことです。

./configure \
--prefix=/usr/local/unbound-1.9.4 \
--disable-flto \
--enable-systemd \
--enable-fully-static \
--enable-cachedb \
--with-ssl=/usr/local/openssl \
--with-libexpat=/usr \
--with-libhiredis

通りました。

make test
(略)
./testdata/version_bind.rpl OK
./testdata/version_bind_hide.rpl OK
./testdata/views.rpl OK
test OK

通っています。

# make install
(略)
# echo $?
0

インストールされました。

起動スクリプトをdnfで入れたものをコピーします。

元のスクリプト
cat /usr/lib/systemd/system/unbound-anchor.service
[Unit]
Description=Unbound recursive Domain Name Server
After=network.target
After=unbound-keygen.service
Wants=unbound-keygen.service
Wants=unbound-anchor.timer
Before=nss-lookup.target
Wants=nss-lookup.target

[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/unbound
ExecStartPre=/usr/sbin/unbound-checkconf
ExecStartPre=-/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem -f /etc/resolv.conf -R
ExecStart=/usr/sbin/unbound -d $UNBOUND_OPTIONS
ExecReload=/usr/sbin/unbound-control reload

[Install]
WantedBy=multi-user.target

修正したもの

[Unit]
Description=Unbound recursive Domain Name Server
After=network.target
#After=unbound-keygen.service
#Wants=unbound-keygen.service
#Wants=unbound-anchor.timer
Before=nss-lookup.target
Wants=nss-lookup.target

[Service]
Type=simple
#EnvironmentFile=-/etc/sysconfig/unbound
ExecStartPre=/usr/local/unbound-1.9.4/sbin/unbound-checkconf
#ExecStartPre=-/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem -f /etc/resolv.conf -R
ExecStart=/usr/local/unbound-1.9.4/sbin/unbound -d $UNBOUND_OPTIONS
ExecReload=/usr/local/unbound-1.9.4/sbin/unbound-control reload

[Install]
WantedBy=multi-user.target

confファイルはほとんど設定されていないので、ローカルから引けるようにします。

access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
do-not-query-localhost: no

スタートします。

# systemctl start unbound
# systemctl status unbound
● unbound.service - Unbound recursive Domain Name Server
   Loaded: loaded (/usr/lib/systemd/system/unbound.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2019-12-20 13:29:59 JST; 18s ago
  Process: 13455 ExecStartPre=/usr/local/unbound-1.9.4/sbin/unbound-checkconf (code=exited, status=0/SUCCESS)
 Main PID: 13458 (unbound)
    Tasks: 1 (limit: 26213)
   Memory: 3.5M
   CGroup: /system.slice/unbound.service
           └─13458 /usr/local/unbound-1.9.4/sbin/unbound -d

12月 20 13:29:59 unbound systemd[1]: Starting Unbound recursive Domain Name Server...
12月 20 13:29:59 unbound unbound-checkconf[13455]: unbound-checkconf: no errors in /usr/local/unbound-1.9.4/etc/unbound/unbound>
12月 20 13:29:59 unbound systemd[1]: Started Unbound recursive Domain Name Server.
12月 20 13:29:59 unbound unbound[13458]: [13458:0] notice: init module 0: validator
12月 20 13:29:59 unbound unbound[13458]: [13458:0] notice: init module 1: iterator
12月 20 13:29:59 unbound unbound[13458]: [13458:0] info: start of service (unbound 1.9.6).
# dig google.com @localhost

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-17.P2.el8_0.1 <<>> google.com @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48229
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             300     IN      A       216.58.197.174

;; Query time: 86 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 金 12月 20 13:31:24 JST 2019
;; MSG SIZE  rcvd: 55

引けました。
最適化の設定を入れてみます。

# some optimisation options.
server:
        # use all CPUs
        num-threads: 4 
	
        # power of 2 close to num-threads  
        msg-cache-slabs: 4
        rrset-cache-slabs: 4
        infra-cache-slabs: 4
        key-cache-slabs: 4

        # more cache memory, rrset=msg*2
        rrset-cache-size: 100m
        msg-cache-size: 50m

        # more outgoing connections
        # depends on number of cores: 1024/cores - 50 
        outgoing-range: 950

        # Larger socket buffer.  OS may need config.
        so-rcvbuf: 4m

こちらも問題なく動くようです。
負荷テストをしてみます。

参考
フリーのDNSストレスツール の紹介(dnsops.jp)

# wget ftp://ftp.isc.org/isc/bind9/9.9.3-P1/bind-9.9.3-P1.tar.gz
# tar xf bind-9.9.3-P1.tar.gz
# cp bind-9.9.3-P1/lib/isc/include/isc/hmacsha.h /usr/include/isc
dnf install bind-devel openssl-devel libcap-devel libxml2-devel  -y 
cd /usr/local/src
wget https://www.dns-oarc.net/files/dnsperf/dnsperf-2.3.2.tar.gz
tar xf dnsperf-2.3.2.tar.gz
chown -R root. dnsperf-2.3.2
cd !:3
./configure --prefix=/usr/local/dnsperf-2.3.2
(略)
configure: error: BIND 9 libraries must be installed

注)↑は修正済みのコマンドです
さくっといかないものです。
bindのdevelをインストールします。

dnf install bind-devel -y

参考資料
DNSに負荷をかけるテスト(kinneko.hatenadiary.org)

またひっかかります。

configure: error: Package requirements (libssl) were not met:

Package 'libssl', required by 'virtual:world', not found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables libssl_CFLAGS
and libssl_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

いろいろ調べましたが、こういう設定が必要なようです。
libssl detection fails late on macos sierra #246(github.com)

./configure libssl_LIBS=-I/usr/local/openssl/lib libssl_CFLAGS=-I/usr/local/openssl/include/openssl --prefix=/usr/local/dnsperf-2.3.2
Making all in src
make[1]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' に入ります
make  all-recursive
make[2]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' に入ります
make[3]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' に入ります
depbase=`echo datafile.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -DHAVE_CONFIG_H -I.    -I. -I.. -pthread -I/usr/local/openssl/include/openssl -g -O2 -I/usr/include/bind9 -D_REENTRANT -I/builddir/build/BUILD/bind-9.11.4-P2/build/unit/atf/include -DDIG_SIGCHASE -D_GNU_SOURCE -MT datafile.o -MD -MP -MF $depbase.Tpo -c -o datafile.o datafile.c &&\
mv -f $depbase.Tpo $depbase.Po
In file included from os.h:20,                                                                                                      
                 from datafile.c:34:                                                                                                
net.h:25:10: 致命的エラー: openssl/ssl.h: そのようなファイルやディレクトリはありません                                              
 #include <openssl/ssl.h>                                                                                                           
          ^~~~~~~~~~~~~~~                                                                                                           
コンパイルを停止しました。
make[3]: *** [Makefile:588: datafile.o] エラー 1
make[3]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' から出ます
make[2]: *** [Makefile:665: all-recursive] エラー 1
make[2]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' から出ます
make[1]: *** [Makefile:431: all] エラー 2
make[1]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' から出ます
make: *** [Makefile:465: all-recursive] エラー 1

検索していくと ubuntuならlibssl-devを入れろ!というものばかりでしたが、
openssl-develを入れたらすんなり通りました。

/usr/bin/ld: cannot find -lcap
/usr/bin/ld: cannot find -lxml2
/usr/bin/ld: cannot find -llzma
collect2: error: ld returned 1 exit status
make[3]: *** [Makefile:531: dnsperf] エラー 1
make[3]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' から出ます
make[2]: *** [Makefile:665: all-recursive] エラー 1
make[2]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' から出ます
make[1]: *** [Makefile:431: all] エラー 2
make[1]: ディレクトリ '/usr/local/src/dnsperf-2.3.2/src' から出ます
make: *** [Makefile:465: all-recursive] エラー 1

必要なものをインストールします。

dnf install libcap-devel libxml2-devel 

無事、コンパイルが通りインストールができました。

テストしてみます。

cd /usr/local/dnsperf-2.3.2/bin
wget ftp://ftp.nominum.com/pub/nominum/dnsperf/data/queryfile-example-current.gz
gzip -d queryfile-example-current.gz
./resperf -s localhost -d queryfile-example-current
Statistics:

  Queries sent:         102765
  Queries completed:    40394
  Queries lost:         62371
  Response codes:       NOERROR 27710 (68.60%), SERVFAIL 33 (0.08%), NXDOMAIN 12651 (31.32%)
  Run time (s):         56.104757
  Maximum throughput:   6306.000000 qps
  Lost at that point:   64.81%

ソースインストールてチューニングしたほうが、DNFでそのまま入れたunboundより4、5倍以上Maximum Throughputが出ていました。

おまけ

dnfでインストールしたプログラムも、libeventを読み込んでいるようです。

# which unbound
/usr/sbin/unbound

# ldd /usr/sbin/unbound
        linux-vdso.so.1 (0x00007ffd210dd000)
        libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007f77aa103000)
        libevent-2.1.so.6 => /lib64/libevent-2.1.so.6 (0x00007f77a9eaa000)
        libpython3.6m.so.1.0 => /lib64/libpython3.6m.so.1.0 (0x00007f77a9952000)
        libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007f77a947a000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f77a925a000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f77a8e96000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f77a8c7f000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f77a8a7b000)
        libutil.so.1 => /lib64/libutil.so.1 (0x00007f77a8877000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f77a84f5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f77aa6d7000)

が、/usr/sbin/unboundをエディタで見ると

too many file descriptors requested. 
The builtinmini-event cannot handle more than 1024. 
Config for less fds or compile with libevent

こんな記述がありました。やはりソースで入れないと有効にならなさそうです。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?