DNS¶
DNSに関するRFC¶
RFC1034, RFC1035, RFC1912, RFC2181あたりをざっくりと RFC3484にはこう書かれている.
Rule 8: Use longest matching prefix.
If CommonPrefixLen(SA, D) > CommonPrefixLen(SB, D), then prefer SA.
Similarly, if CommonPrefixLen(SB, D) > CommonPrefixLen(SA, D), then
prefer SB.
つまるところ,複数のIPアドレスリストをDNS answerとしてクライアントに返す場合,これまでは'answerのIPアドレスリストのうち最初のIPアドレスから順に使うクライアントが"多かった"'のだが,RFC3484に準拠した実装が行われているクライアントでは,自分のIPアドレスとのロンゲストマッチをとったIPアドレスリストのうちの最初のものから順に使って行くようである.DNSラウンドロビンなどで複数のIPアドレスリストを返す場合に,DNSサーバが構成したリストの最初の1番目が利用されるわけではなくなるということになる. これを知っておかないと意図した動作と異なるふるまいをしそうなので注意が必要そう.
代表的なdns ソフトウェア¶
- Bind (Internet Systems Consortium)
- 有名.脆弱性がちょっと多い印象.
- Power DNS (PowerDNS)
- Web GUIがあり,レコード登録などの取り扱いがやりやすい.
- Unbound (NLnet Labs)
- DNSキャッシュサーバ.コンテンツサーバにはなれない.
- DNSキャッシュサーバとしては,BINDを完全に置き換えることができる程度の機能は実装されている.
- Knot DNS (CZ.NIC)
- 権威DNS(コンテンツサーバ)専用
- キャッシュサーバ(resolver)として使いたい場合は
Knot DNS resolver
というものもある.- cloudflare(1.1.1.1)で使われているらしい.
Primary DNSはどっち?¶
dig @<server> example.com ns
#... #;; ANSWER SECTION: #example.com. 87468 IN NS ns2.example.com. #example.com. 87468 IN NS ns1.example.com. #...
dig @<server> ns1.example.com soa
# example.com. 180 IN SOA ns1.example.com. hoge.example.com. ...
dig @<server> ns2.example.com soa
# example.com. 180 IN SOA ns1.example.com. hoge.example.com. ...
この場合,SOAがns1なので,ns1をprimaryとしてそうだと見ることができる.(実際にゾーン転送におけるmaster/slaveとしてどう運用されているかはこれではわからない.zone転送元となるmasterは隠されている可能性もある.)
ゾーン転送¶
- IXFRとAXFRがある.AXFRはそのリクエストで該当のゾーン情報すべてを取得するが,IXFRではいわゆる差分アップデートのように動作する.
- IXFRについてはRFC1995を参照
- commands
dig @<server> <domain> axfr
- DNS NOTIFYについてはRFC1996を参照
bindのlogging¶
bind9.11.1でgeoip-use-ecs
optionが使えない (2019-02-25 YudaiHashimoto)¶
- docには載っているのにな....
Feb 23 06:09:32 76efffadff20 bash[27022]: /etc/named.conf:32: unknown option 'geoip-use-ecs'
bind9 build battle¶
bind9.13らへんをいれたかった.
$ wget https://www.openssl.org/source/openssl-1.0.2q.tar.gz $ tar xvzf openssl-1.0.2q.tar.gz $ cd openssl-1.0.2q/ $ perl util/perlpath.pl `which perl` //はいらなかった $ ./config --prefix=/usr --openssldir=/usr/ssl shared $ make $ su $ rpm -q -a | grep openssl | while read line; do rpm -e --nodeps $line; done $ make install $ ldconfig -v $ wget ftp://ftp.isc.org/isc/bind9/9.13.2/bind-9.13.2.tar.gz $ tar xvzf bind-9.13.2.tar.gz $ cd bind-9.13.2/ $ yum provides *sys/capability.h $ yum install libcap-devel $ ./configure --prefix=/usr --sysconfdir=/etc --enable-threads --localstatedir=/var/state --with-libtool --with-openssl=/usr/ $ make $ su $ rpm -q -a | grep '^bind' | while read line; do rpm -e --nodeps $line; done $ ldconfig -v $ groupadd named $ vigr $ chown root:daemon /var/run $ chmod 775 /var/run $ mkdir -p /var/named/pz $ chown -R named:named /var/named $ chmod -R 755 /var/named
9.11 on docker
[jp7fkf@jp7fkf_0 ~]$ sudo docker pull centos:latest latest: Pulling from library/centos a02a4930cb5d: Pull complete Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426 Status: Downloaded newer image for centos:latest [jp7fkf@jp7fkf_0 ~]$ [jp7fkf@jp7fkf_0 ~]$ docker images Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/images/json: dial unix /var/run/docker.sock: connect: permission denied [jp7fkf@jp7fkf_0 ~]$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 1e1148e4cc2c 2 months ago 202MB [jp7fkf@jp7fkf_0 ~]$ sudo docker run -it -d --privileged --name bind911 centos:latest /sbin/init 76efffadff20224247573edb5d5a03834b3be5b9868683542a4fab766c8d55ee [jp7fkf@jp7fkf_0 ~]$ [jp7fkf@jp7fkf_0 ~]$ sudo docker exec -it 76ef /bin/bash
$ yum update $ yum install openssl openssl-devel $ cd /usr/local/src $ yum install wget $ wget --trust-server-name https://www.isc.org/downloads/file/bind-9-11-1/?version=tar-gz $ mv index.html?version=tar-gz bind-9-11-1-p1.tar.gz $ tar xvzf bind-9-11-1-p1.tar.gz $ cd bind-9.11.1/ $ yum install gcc perl $ ./configure --with-libtool --with-openssl --prefix=<install先> $ make $ make install
systemctl であがらない
$ journalctl -xe Feb 23 05:41:50 76efffadff20 named[26825]: isc_stdio_open 'data/named.run' failed: file not found
- 脳死で
yum install bind-chroot
- 脳死で
unboundをdockerにたてる¶
- docker でcentosをたてておく.
yum update
yum install unbound
curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
vi /etc/unbound/unbound.conf
unbound-checkconf
systemctl start unbound
yum install bind-utils
dig @localhost www.google.com
- ハマりどころ
- dnssecがdefaultでonになっているっぽい.
/etc/unbound/unboud.conf
のmodule-configからvalidatorとipsec系のmoduleを消す.- fastlyのunbound.confなんてmodule-config自体commented out されてたな :thinking_face:
module-config: "iterator"
となっていればok
- DNSSECを無効にする方法 – 日本Unboundユーザー会
- Ubuntu 18.04でnameserverが127.0.0.53になってしまう - 発声練習
基本config¶
- このあたり書いておけばとりあえずresolverとしては動きそう.細かいことはgoogleって人がよく知っているので聞いてみるといい.
- interface
- do-ipv4
- do-ipv6
- do-udp
- do-tcp
- access-control
- root-hints
- forward-zose
- name
- forward-addr
ログを取る¶
server:
logfile: "/var/unbound/var/log/unbound.log"
use-syslog: no
- 単にこうするだけだとapparmorに怒られる
# /var/log/syslog
Mar 11 20:53:58 dns01 kernel: [ 1575.963648] audit: type=1400 audit(1583960038.020:22): apparmor="DENIED" operation="mkno
d" profile="/usr/sbin/unbound" name="/var/log/unbound/unbound.log" pid=1761 comm="unbound" requested_mask="c" denied_mask
="c" fsuid=111 ouid=111
# apparmorにpolicyを書く
$ vim /etc/apparmor.d/local/usr.sbin.unbound
/var/log/unbound/unbound.log rw, #これを書いておく.
#よみなおして
$ apparmor_parser -r /etc/apparmor.d/usr.sbin.unbound
# unbound restart
$ sudo systemctl restart unbound
# にしても新規でunbound.logは作成できないので.
$ sudo touch /var/log/unbound/unbound.log
$ sudo chown /var/log/unbound/unbound.log
は実施する必要がある.下記logrotateでは`create 0640 unbound unbound`しているので自動で作成されるはず.
- logrotateのexampleこんな感じかな
- デフォルトだと
/run/unbound.pid
としてpidファイルができる.
- デフォルトだと
/var/log/unbound/unbound.log {
weekly
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 unbound unbound
sharedscripts
postrotate
[ -e /run/unbound.pid ] && invoke-rc.d unbound force-reload >/dev/null || true
endscript
}
localにかいとくとき.¶
local-zone: "***.hoge.local." static
local-data: "IN NS ns1.hoge.local."
local-data: "IN NS ns2.hoge.local."
local-data: "ns1.hoge.local. IN A 10.0.0.1"
local-data: "ns2.hoge.local. IN A 10.0.0.2"
vimにペーストするときにインデントされるのを防止¶
- ペーストモード
:set paste
を打ってから入力
- alコマンド
:al
して貼り付け
unbound¶
unbound install battle on ubuntu18.04¶
- 2019/07現在下記のパッケージがある.(1.6.7)
jp7fkf@lab1:~$ sudo apt list -a | grep unbound
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
libghc-unbounded-delays-dev/bionic 0.1.1.0-1 amd64
libghc-unbounded-delays-doc/bionic 0.1.1.0-1 all
libghc-unbounded-delays-prof/bionic 0.1.1.0-1 amd64
libunbound-dev/bionic-updates 1.6.7-1ubuntu2.2 amd64
libunbound-dev/bionic-security 1.6.7-1ubuntu2.1 amd64
libunbound-dev/bionic 1.6.7-1ubuntu2 amd64
libunbound2/bionic-updates 1.6.7-1ubuntu2.2 amd64
libunbound2/bionic-security 1.6.7-1ubuntu2.1 amd64
libunbound2/bionic 1.6.7-1ubuntu2 amd64
python-unbound/bionic-updates 1.6.7-1ubuntu2.2 amd64
python-unbound/bionic-security 1.6.7-1ubuntu2.1 amd64
python-unbound/bionic 1.6.7-1ubuntu2 amd64
python3-unbound/bionic-updates 1.6.7-1ubuntu2.2 amd64
python3-unbound/bionic-security 1.6.7-1ubuntu2.1 amd64
python3-unbound/bionic 1.6.7-1ubuntu2 amd64
unbound/bionic-updates 1.6.7-1ubuntu2.2 amd64
unbound/bionic-security 1.6.7-1ubuntu2.1 amd64
unbound/bionic 1.6.7-1ubuntu2 amd64
unbound-anchor/bionic-updates 1.6.7-1ubuntu2.2 amd64
unbound-anchor/bionic-security 1.6.7-1ubuntu2.1 amd64
unbound-anchor/bionic 1.6.7-1ubuntu2 amd64
unbound-host/bionic-updates 1.6.7-1ubuntu2.2 amd64
unbound-host/bionic-security 1.6.7-1ubuntu2.1 amd64
unbound-host/bionic 1.6.7-1ubuntu2 amd64
Unbound DNS monitoring¶
[NLnet Labs Documentation
Unbound - Howto Statistics](https://nlnetlabs.nl/documentation/unbound/howto-statistics/)
GitHub - jeftedelima/Unbound-DNS: Template Unbound Server - Zabbix
unbound config examples¶
optimization¶
dnsperf¶
SOAのシリアル番号を小さくする方法¶
If you make a mistake and increment the serial number too high, and
you want to reset the serial number to a lower value, use the
following procedure:
Take the `incorrect' serial number and add 2147483647 to it. If
the number exceeds 4294967296, subtract 4294967296. Load the
resulting number. Then wait 2 refresh periods to allow the zone
to propagate to all servers.
Repeat above until the resulting serial number is less than the
target serial number.
Up the serial number to the target serial number.
- 現在のシリアル番号に2147483647を足した値を新しいシリアル番号とするが,その結果が4294967296よりも大きくなる場合には、4294967296を引いた値を新しいシリアル番号とする.
References¶
- DNSの仕組み完全解説
- Knot DNSを使ってみた - DNS Summer Days 2014(mikit-san)
- DNS温泉番外編(2016)
- Web-based DNS Randomness Test
dig +short porttest.dns-oarc.net TXT
- Unboundのunwanted-reply-thresholdオプション
- https://jprs.jp/tech/security/2014-04-30-poisoning-countermeasure-resolver-1.pdf
- https://www.janog.gr.jp/meeting/janog31.5/doc/janog31.5_dns-open-resolver-maz.pdf
特定のzoneの問い合わせ先を指定したい場合(stub zone)¶
unbound¶
stub-zone:
name:"example.com"
stub-addr:192.168.0.11
stub-addr:192.168.0.12
stub-zone:
name: "0.168.192.in-addr.arpa"
stub-addr:192.168.0.11
stub-addr:192.168.0.12
powerdns recursor¶
- forward-zonesあたりを使うことになる.
forward-zones=example.com=192.168.0.11;192.168.0.12,0.168.192.in-addr.arpa=192.168.0.11;192.168.0.12
knot resolver¶
# define list of internal-only domains
internalDomains = policy.todnames({'example.com', '0.168.192.in-addr.arpa'})
# forward all queries belonging to domains in the list above
policy.add(policy.suffix(policy.FLAGS({'NO_CACHE'}), internalDomains))
policy.add(policy.suffix(policy.STUB({'192.168.0.11', '192.168.0.12'}), internalDomains))