🔳

ローカルにDNSサーバを構築(BIND, Unbound)

2023/04/29に公開

はじめに

本記事はローカル環境でDNSサーバを構築したときの手順です。
"構築すること"が目的となっているため細かな設定はしません。

対象者

初めてDNSサーバ(BIND, Unbound)を構築する方を対象としています。

学習環境

権威DNSサーバとキャッシュサーバを分離していて、クライアントマシンが2台いる構成です。

  • 権威DNSサーバ
    ホスト名 : dnscontents
    IPアドレス : 192.168.0.200 /24
    ドメイン名 : learning.local
    OS : CentOS 7.9.2009
    DNSソフトウェア : BIND

  • キャッシュサーバ
    ホスト名 : dnscache
    IPアドレス : 192.168.0.100 /24
    ドメイン名 : learning.local
    OS : CentOS 7.9.2009
    DNSソフトウェア : Unbound

  • クライアントマシン1
    ホスト名 : dnsclient1
    IPアドレス : 192.168.0.1 /24
    ドメイン名 : learning.local
    OS : CentOS 7.9.2009

  • クライアントマシン2
    ホスト名 : dnsclient2
    IPアドレス : 192.168.0.2 /24
    ドメイン名 : learning.local
    OS : CentOS 7.9.2009

ゴール

  • キャッシュサーバがクライアントマシンからの名前解決の要求に成功する。
    (キャッシュサーバがゾーン(leaning.local)のキャッシュを保持していない時、
    権威サーバに対して非再起問い合わせをする。)

  • 権威サーバはキャッシュサーバからしかクエリを受け付けない。

権威DNSサーバ(BIND)構築手順

BINDをインストール
sudo yum -y install bind

BINDを起動
sudo systemctl start bind

named.confを編集

options {
	// listen-on port 53 { 127.0.0.1; };
	listen-on port 53 { 192.168.0.200; };
	// listen-on-v6 port 53 { ::1; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
	statistics-file "/var/named/data/named_stats.txt";
	memstatistics-file "/var/named/data/named_mem_stats.txt";
	recursing-file  "/var/named/data/named.recursing";
	secroots-file   "/var/named/data/named.secroots";
	recursion no;
	allow-query     { 192.168.0.100; };
	allow-recursion { none; };
	allow-query-cache { none; };

	dnssec-enable yes;
	dnssec-validation yes;

	/* Path to ISC DLV key */
	bindkeys-file "/etc/named.root.key";

	managed-keys-directory "/var/named/dynamic";

	pid-file "/run/named/named.pid";
	session-keyfile "/run/named/session.key";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "learning.local" IN {
	type master;
	file "learning.local";
	allow-update { none; };
};

zone "0.168.192.in-addr.arpa" IN {
	type master;
	file "learning.local.rev";
	allow-update { none; };
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

learning.localの正引きzoneファイルを作成

$TTL 1D
@       IN SOA  dnscontents.learning.local. root.learning.local. (
                2023042501  ; serial
                1D          ; refresh
                1H          ; retry
                1W          ; expire
                3H          ; minimum
                )
        IN NS   dnscontents.learning.local.
	IN NS	dnscache.learning.local.

dnscontents IN A    192.168.0.200
dnscache    IN A    192.168.0.100
dnsclient1  IN A    192.168.0.1
dnsclient2  IN A    192.168.0.2

learning.localの逆引きzoneファイルを作成

$TTL 1D
@       IN SOA  dnscontents.learning.local. root.learning.local. (
                2023042501  ; serial
                1D          ; refresh
                1H          ; retry
                1W          ; expire
                3H          ; minimum
                )
        IN NS   dnscontents.learning.local.

200     IN PTR  dnscontents.learning.local.
100     IN PTR  dnscache.learning.local.
1       IN PTR  dnsclient1.learning.local.
2       IN PTR  dnsclient2.learning.local.

bindを再起動
sudo systemctl restart bind

キャッシュサーバ(Unbound)構築手順

Unboundをインストール
sudo yum -y install unbound

Unboundを起動
sudo systemctl start bind

unbound.confを編集

server:
interface: 192.168.0.100
access-control: 192.168.0.0/24 allow
hide-version: yes
/ 権威サーバの設定
stub-zone:
name: "learning.local"
stub-addr: 192.168.0.200

unbound.confの構文が正しいかチェック
unbound-checkconf /etc/unbound/unbound.conf

Unboundを再起動する
sudo systemctl restart unbound

ゴールの条件を満たしているか確認

  • クライアントマシン(dnsclient1)からキャッシュサーバ(dnscache)に名前解決を要求
# nslookup dnsclient1.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnsclient1.learning.local
Address: 192.168.0.1

# nslookup dnsclient2.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnsclient2.learning.local
Address: 192.168.0.2

# nslookup dnscache.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnscache.learning.local
Address: 192.168.0.100

# nslookup dnscontents.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnscontents.learning.local
Address: 192.168.0.200
  • クライアントマシン(dnsclient1)から権威サーバ(dnscontents)に名前解決を要求
# nslookup dnsclient1.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnsclient1.learning.local: REFUSED

# nslookup dnsclient2.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnsclient2.learning.local: REFUSED

# nslookup dnscache.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnscache.learning.local: REFUSED

# nslookup dnscontents.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnscontents.learning.local: REFUSED
  • クライアントマシン(dnsclient2)からキャッシュサーバ(dnscache)に名前解決を要求
# nslookup dnsclient1.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnsclient1.learning.local
Address: 192.168.0.1

# nslookup dnsclient2.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnsclient2.learning.local
Address: 192.168.0.2

# nslookup dnscache.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnscache.learning.local
Address: 192.168.0.100

# nslookup dnscontents.learning.local 192.168.0.100
Server:		192.168.0.100
Address:	192.168.0.100#53

Non-authoritative answer:
Name:	dnscontents.learning.local
Address: 192.168.0.200
  • クライアントマシン(dnsclient2)から権威サーバ(dnscontents)に名前解決を要求
# nslookup dnsclient1.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnsclient1.learning.local: REFUSED

# nslookup dnsclient2.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnsclient2.learning.local: REFUSED

# nslookup dnscache.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnscache.learning.local: REFUSED

# nslookup dnscontents.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

** server can't find dnscontents.learning.local: REFUSED
  • キャッシュサーバ(dnscache)から権威サーバ(dnscontents)に名前解決を要求
# nslookup dnsclient1.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

Name:	dnsclient1.learning.local
Address: 192.168.0.1

# nslookup dnsclient2.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

Name:	dnsclient2.learning.local
Address: 192.168.0.2

# nslookup dnscache.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

Name:	dnscache.learning.local
Address: 192.168.0.100

# nslookup dnscontents.learning.local 192.168.0.200
Server:		192.168.0.200
Address:	192.168.0.200#53

Name:	dnscontents.learning.local
Address: 192.168.0.200

さいごに

今回初めての記事投稿となり、書くべき内容が不足しているかもしれませんが、
私と同様に初めてDNSサーバ(BIND, Unbound)を構築する方々にとって少しでもお役に立てれば幸いです。

Discussion