Unbound + NSD で DNS

BIND9 に変わる方法として、Unbound と NSD を利用する方法がある。BIND9 は歴史が長い都合上、 RedHat 系や Ubuntu を含む Debian 系などでは GUI ツールも存在する。しかしその反面、多くの攻撃に晒されて来た経緯があり、運用を不安視する人も存在する。

そこで今回は、Unbound と NSD で DNS を Fedora で構築する方法を紹介しようと思う。

 

NSD のインストール

NSD は DNS コンテンツサーバーや、権威DNSサーバーと呼ばれています。

 

NSD が仮に、「router.hoge.co.jp」を「192.168.0.1」と管理している場合、「router.hoge.co.jp のIPアドレスは?」と尋ねると「192.168.0.1 です」、「192.168.0.1 のドメイン名は?」と尋ねると「router.hoge.co.jp です」と答えます。こういった機能を持つサーバーを権威DNSサーバーと呼びます。

 

しかし、NSD は何でも知っているワケではなく、知っている事だけ答えてくれるアノ委員長のような存在で、知らない事は知らないと言います。

 

もっとも、これだけの機能でもレゾルバと併用すれば、DNS として利用できます。

 

では早速インストールしてみましょう。

 

$ su
# yum install nsd

 

GUI でインストールする場合は、コチラをご覧下さい。(パッケージ名:nsd)

 

※ Fedora22 からは DNF を用いてインストールを行います。詳しくはコチラをご覧下さい。

 

ゾーンファイルの作成

ゾーンとは、区分けとか分類だとか思って下さい。例えば、1階、2階とか、総務部、開発部とか。その中で、pc01 の名前を持つ PC が存在し、「192.168.0.5」の IP アドレスを持っていたとします。すると、ゾーンファイルは次の様になります。

 

※ ゾーンファイルの文法は決まっており、BIND と同じです。詳しい文法はコチラをご覧下さい。

※ 後で移動しますので、ファイル名は何でも構いません。

※ systemd-resolve では、動作が不安定になりますので SOA レコードなどに「1W」などは使用しない方が良い様です。これは、「1W」を秒に変換してオーバーフローを起こしているかと思われます。

 

$ORIGIN hoge.co.jp. ; このゾーン
; アドレス末尾の「.」は省略されていないアドレスを表す。
;
$TTL 1D ; 有効時間 1H なら1時間、1D なら1日
; 基本的な情報の宣言
; @ IN SOA ネームサーバー サーバー管理者のメールアドレス (
; メールアドレスの「@」は「.」にして記述
@ IN SOA ns1.hoge.co.jp. postmaster.mail.hoge.co.jp. (
    2014122501 ; シリアル番号(10桁)、慣例として年月日+2桁で記述
    3H ; リフレシュ時間
    1H ; リトライ時間
    1W ; Expire
    1H ; Minimum
    )
         IN NS ns1.hoge.co.jp.
         IN MX 0 mail.hoge.co.jp.
ns1   IN A 192.168.0.1
mail  IN A 192.168.0.2
pc01 IN A 192.168.0.5

 

このように設定されているとき、「pc01」の正式なアドレスは、ゾーン名との組み合わせで「pc01.hoge.co.jp」となります。

 

ここで少し気を付けて欲しい事として、ドメイン名は後ろのゾーンから前のゾーンに属していると言う意味になります。

 

例えば「pc01.hoge.co.jp」は、「日本:jp」→「会社:co」→「会社名:hoge」に存在する「pc01」となります。

 

ここで仮に、1階を「f1」とし、そこに存在する「pc01」の場合のアドレスは、「pc01.f1.hoge.co.jp」の様に、任意の階層をゾーンで表すことが出来ます。

 

※ アドレスの後に付ける「.」は完全なドメイン(FQDN)を表すものです。つまり「www.google.co.jp」などの様に、インターネットでアクセス出来るアドレスもこれに含まれます。また、ゾーンファイル内の「pc01」などはアドレスの一部ですので、「.」を付加しません。

 

逆引きゾーンゾーンファイルの作成

逆引きゾーンファイルは、ゾーンファイルと考え方は同じですが、「192.168.0.5」の IP アドレスを pc01 に変換するために利用します。では早速見ていきましょう。

※ systemd-resolve では、動作が不安定になりますので SOA レコードなどに「1W」などは使用しない方が良い様です。これは、「1W」を秒に変換してオーバーフローを起こしているかと思われます。

$ORIGIN 0.168.192.in-addr.arpa.
; 192.168.0.xx の逆引きゾーンで、最後の数字を検索されるために
; IP アドレスが逆になり、逆引きゾーンを表す「.in-addr.arpa」を付加する。
$TTL 1D
@ IN SOA ns1.hoge.co.jp. postmaster.mail.hoge.co.jp. (
    2014122502 ; Serial
    3H ; Refresh
    1H ; Retry
    1W ; Expire
    1H ; Minimum
    )
@   IN   NS    ns1.hoge.co.jp.
5    IN   PTR  pc01.hoge.co.jp.

 

基本的には、正引きゾーンファイルと殆ど同じです。ただ、IPゾーン「192.168.0」の中の「5」が知りたいワケですから、アドレスを逆さま「0.168.192」にし、逆転を表す「.in-addr.arpa」を付加します。さらに、逆引き用レコードである PTR を利用します。

 

nsd.conf の編集

nsd.conf の詳細はコチラをご覧下さい。

 

先ずは、「mkdir /var/lib/nsd/zone /var/lib/nsd/db」として、ディレクトリを2つ作成します。

 

次に、先程作成したゾーンファイルを「hoge.co.jp.zone」と「0.168.192.in-addr.arpa.zone」として、「/var/lib/nsd/zone」に保存します。

 

さて、実際に「/etc/nsd/nsd.conf」を編集してみましょう。

 

server:
    # IPv4 のみ使用
    ip4-only: yes
    # 自動で作成される
    database: “/var/lib/nsd/db/nsd.db” # データベースファイル
    zonesdir: “/var/lib/nsd/zone”    # ゾーンファイルのあるディレクトリ
    logfile: “/var/log/nsd.log” # ログファイル
    pidfile: “/run/nsd/nsd.pid” # PID ファイル
    port: 53 # ポート番号
zone:
    name: “hoge.co.jp.
    zonefile: “hoge.co.jp.zone
zone:

    name: “0.168.192.in-addr.arpa.
    zonefile: “0.168.192.in-addr.arpa.zone

 

ここで重要なのは、ゾーン名とゾーンファイルを合わせておく事でしょうか?

 

勿論、ゾーンは正引きと逆引きのセットですが、このセットは1つである必要はありません。

 

また、「pidfile」は「/usr/lib/systemd/system/nsd.service」に記載されている「PIDFile」と同じである必要があります。

※ 「/var/run/」は古い表記扱いとなり、現在では「/run/」を使用します。新しい「/var/run/」の配下に PID ファイルを作成すると、起動しない場合があります。

 

NSD の起動

では早速 NSD を起動してみます。

 

$ # スーパーユーザーになる。
$ su
#
# # システム起動時に、デフォルトで起動するようにする。
# systemctl enable nsd.servive
#
# # NSD を起動する。
# systemctl start nsd.servive

 

本来なら問題ないハズですが、SELinux で警告が出てしまいました。そこで、ポリシー用の TE ファイルを作成してみました。(バージョンアップで解消されるかも知れません)

 

module mypol 1.0;

require {
type var_log_t;
type unreserved_port_t;
type nsd_t;
class tcp_socket name_bind;
class dir { write add_name };
class file { create open setattr };
class udp_socket name_bind;
}

#============= nsd_t ==============

#!!!! This avc is allowed in the current policy
allow nsd_t unreserved_port_t:tcp_socket name_bind;

#!!!! This avc is allowed in the current policy
allow nsd_t unreserved_port_t:udp_socket name_bind;

#!!!! This avc is allowed in the current policy
allow nsd_t var_log_t:dir { write add_name };

#!!!! This avc is allowed in the current policy
allow nsd_t var_log_t:file create;
allow nsd_t var_log_t:file { open setattr };

ファイル名は「mypol.te」とし、ポリシー名は「mypol」、バージョンは「1.0」としてあります。利用する場合は、必要に応じて変更して下さい。

 

$ # スーパーユーザーになる。
$ su
#
# # インストールされているポリシー名やバージョンをチェック
# #
既に存在する場合は、ポリシー名を変更して下さい。
# semodule -l
#
# # バイナリモジュールを作成します。
# checkmodule -M -m -o mypol.mod mypol.te
#
# # ポリシーモジュールパッケージを作成します。
# semodule_package -o mypol.pp -m mypol.mod
#
# # ポリシーモジュールパッケージのインストール。
# semodule -i mypol.pp
#
# # ポリシーモジュールパッケージのアップデート。
# # (バージョンを引き上げた場合のみ
# semodule -u mypol.pp

 

NSD の動作を確認します。

 

$ # 正引きの確認
$ dig @127.0.0.1 pc01.hoge.co.jp
$
$ # 逆引きの確認
$ dig @127.0.0.1 -x 192.168.0.5

 

ANSWER SECTION」が存在する事と、「SERVER: 127.0.0.1#53(127.0.0.1)」がある事を確認して下さい。これは解答と、それを応えたサーバーを確認する行為です。

 

実は NSD だけでも、プライベートな DNS としては十分に動作します。それは、レゾルバと呼ばれる機能が存在するためです。(詳しくは「man resolv.conf」で確認して下さい)

 

レゾルバは問い合わせた結果が見つからない場合、次の DNS に問い合わせを自動で行います。ただしこの設定は、各マシンのネットワーク設定として行う必要があります。( Linux、MacOSX、Windowsのマシンで、ネットワークの設定として DNS を指定しているハズです)

 

Unbound のインストール

Unbound は一体ナニを行うデーモンでしょうか?

 

それは、DNS キャッシュと問い合わせに対し、複数の DNS に問い合わせを行う機能です。つまり今回では NSD に問い合わせを行い、結果が見つかった場合にはキャッシュを行い、見つからなかった場合は他の DNS に対して問い合わせを行い、結果が見つかった場合にはキャッシュを行います。

 

しかも、Unbound は問い合わせを行う場合、サーバーマシンのレゾルバを参照します。例えば、複数の DNS でネットワークを管理している場合などでは名前解決が劇的に早くなる可能性があります。また、ネットワーク内に存在するマシンのネットワーク設定で、指定する DNS の数を減らす事も出来ます。

 

では早速インストールしてみましょう。

 

$ su
# yum install unbound

 

グラフィックでインストールする場合は、コチラをご覧下さい。(パッケージ名:unbound)

 

Unbound の設定

今回の Unbound は、NSD のフロントエンドの役目も果たしますので、DNS のポート番号である 53 は Unbound が使用します。そのため、「/etc/nsd/nsd.conf」で記述されている NSD のポート番号を 10053 に変更します。

 

※ この時、SELINUXの設定として、「10053」ポートを「semanage port -a -t dns_port_t -p udp 10053」と「semanage port -a -t dns_port_t -p tcp 10053」で許可しておきます。

 

次のゾーン指定関連のファイルを作成します。設定関連の詳細はコチラをご覧下さい。

 

# ファイル名 hoge.co.jp.conf
# 正引きゾーン hoge.co.jp. に対して、NSD に問い合わせを行う指定
stub-zone:
    name: “hoge.co.jp.
    stub-addr: 127.0.0.1@10053

 

# ファイル名 0.168.192.in-addr.arpa.conf
# 逆引きゾーン 0.168.192.in-addr.arpa. に対して、NSD に問い合わせを行う指定
stub-zone:
    name: “0.168.192.in-addr.arpa.
    stub-addr: 127.0.0.1@10053

 

これらのファイルを「/etc/unbound/conf.d/」に保存します。

 

「/etc/unbound/conf.d」には、ソーン指定などのファイルを格納します。

今度は、ローカル指定関連のファイルを作成します。

 

    # プライベートアドレスを指定します。
    private-address: 192.168.0.0/16    # プライベートドメインを指定します。サブドメインを許可します。
    private-domain: “hoge.co.jp”    # 逆引きを許可するために「transparent」を指定します。
    local-zone: “0.168.192.in-addr.arpa.” transparent

 

    unblock-lan-zones: yes
    domain-insecure: “0.168.192.in-addr.arpa.”

※ アドレスの逆引きはセキュリティの観点から、「transparent」は使用出来無くなりました。そこで、逆引きのゾーンを「domain-insecure」(セキュアでは無いドメイン)扱いとし、「unblock-lan-zones:yes」で、ローカルでの逆引きを許可して行っています。

 

これらのファイルを「/etc/unbound/local.d/」に保存します。

 

ファイルを「/etc/unbound/local.d/」には、ローカルの設定やアクセス制御(ACL)、サーバーに関する設定を格納します。ここのファイルはサーバーセクション(server:)で読み込まれます。アクセス制御を加える必要がある場合は、同様にファイルを作成して下さい。

 

次に、正しい自己署名証明書を設定するために、unbound-control-setup コマンドを実行します。

 

$ su
# unbound-control-setup

これで設定は完了です。

 

Unbound の起動

Undound を起動します。

 

$ # スーパーユーザーになる。
$ su
#
# # NSD のポート番号を変更したので再起動する
# systemctl restart nsd.servive
#
# # システム起動時に、デフォルトで起動するようにする。
# systemctl enable unbound.servive
#
# # Unbound を起動する。
# systemctl start unbound.servive

 

このあと、問題無く起動した場合は、「dig」コマンドを利用して NSD と同様のテストを行います。

DNSSEC の設定(任意)

DNSSEC はセキュアな DNS 設定です。証明書付きで DNS の成り済ましを防ぐ方法であり、この方法でローカルの DNS に限り防止する事ができます。

● DNSSECトリガのインストール

# dnf install  dnssec-trigger

テストが終了した後に、レゾルバの設定を行います。

ネットワーク設定の「DNS」の項目か、又は、「/etc/resolv.conf」の一番上に「127.0.0.1」を追加します。

NetworkManager に DNS を指定します。

● 「/etc/NetworkManager/NetworkManager.conf」を次の様に変更します。

[main]
dns=unbound

● DNSSECトリガの機動設定と確認

# systemctl start dnssec-triggerd
# systemctl enable dnssec-triggerd
# systemctl status dnssec-triggerd

 

dnssec-triggerd.service – Reconfigure local DNSSEC resolver on connectivity changes
        Loaded: loaded (/usr/lib/systemd/system/dnssec-triggerd.service; enabled; vendor preset: enabled)
          Active: active (running) since Tue 2022-01-18 08:19:22 JST; 6h ago
      Main PID: 2075 (dnssec-triggerd)
            Tasks: 1 (limit: 154562)
        Memory: 1.8M
               CPU: 1.311s
         CGroup: /system.slice/dnssec-triggerd.service
                       └─2075 /usr/sbin/dnssec-triggerd -d

1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ‘26.172.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ‘27.172.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ‘28.172.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ‘29.172.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ‘30.172.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ‘31.172.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp dnssec-trigger-script[2076]: Connection provided zone ’10.in-addr.arpa’ (insecure): 127.0.0.1, 8.8.8.8
1月 18 08:19:22 nagato.magic-object.mydns.jp systemd[1]: Started Reconfigure local DNSSEC resolver on connectivity changes.
1月 18 08:19:23 nagato.magic-object.mydns.jp dnssec-triggerd[2545]: ok
1月 18 08:19:27 nagato.magic-object.mydns.jp dnssec-triggerd[3005]: ok

さらにデスクトップ型では、デフォルトで「systemd-resolve」が DNS キャッシュサーバーとして起動しているので、それらを無効にします。

# systemctl disable systemd-resolve
# systemctl stop systemd-resolve

※「systemd-resolve」は無効にしなくても、開放するポートを「127.0.0.1」、「::1」、及びローカルのIPアドレス「192.168.x.x」にする事で、問題なく動作しました。

変更が終了したら NetworkManager.service の再起動を行います。

# systemctl restart NetworkManager.service

次に、「dig」コマンドで最終テストを行います。

 

$ # 正引きの確認
$ dig pc01.hoge.co.jp
$
$ # 逆引きの確認
$ dig -x 192.168.0.5
$
$ # 外部のアドレスが解決出来るかどうかを確かめる
$ dig www.google.co.jp

 

これで問題が無ければ完了です。

 

systemd-resolve を使用している場合

デスクトップ環境で「systemd-resolve」を使用している場合はコチラをご覧下さい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です