DNS サーバの設定

【概要】Ubuntu 24.04 LTS環境でのBIND DNSサーバ構築方法。View機能で内部と外部からの名前解決を分離設定する具体的な手順。ゾーンファイルとnamed.confの記述方法。rndcやsystemdを用いた管理操作。chroot環境の構成とUFWによるセキュリティ強化策。

BIND DNS サーバを動かし、順引き、逆引きができるようにする。

関連する外部ページ】: http://www.atmarkit.co.jp/flinux/rensai/bind909/bind909a.html

関連する外部ページ】: http://www.atmarkit.co.jp/flinux/index/indexfiles/index-linux.html

関連する外部ページ】: http://www.asahi-net.or.jp/~aa4t-nngk/bind93.html

設定内容

設定内容は次の通りである。

ディレクトリ構造は次のようになる。

/var/named/chroot
+-- dev
+-- etc
+-- proc
+-- var
+-- tmp
+-- run
| +-- named
+-- named (*) 設定ファイルの置き場
+-- data
+-- slaves

事前に調べておく事項

DNSサーバ構築に際して、事前に以下の事項を確認しておく必要がある。

  1. DNSサーバ兼MXのホスト名

    (以下、ホスト名は「dnsmail」のように記述する)

  2. DNSサーバ兼MXの IP アドレス (以下、「XXX.YYY.ZZZ.160」のように記述する)。
  3. Web サーバのホスト名

    (以下、ホスト名は「www」のように記述する)

  4. Web サーバの IP アドレス (以下、「XXX.YYY.ZZZ.167」のように記述する)。
  5. DNSサーバ兼MXがある「内部」のネットワークアドレス

    (以下、ネットワークアドレスは 「XXX.YYY.ZZZ」のように記述する)

  6. DNS ドメイン名 (NIS ドメイン名とは別物であるため混同しないこと)

    (以下、DNS ドメイン名は「mydomain.hoge.com」と記述する)

  7. 上流の DNS サーバの IP アドレス

    (以下、上流の DNS サーバの IP アドレスは「AAA.BBB.CCC.10」と記述する)

DNS サーバソフトのインストール

Ubuntu 24.04 LTS環境では、以下の手順でBINDをインストールする。

  1. 時刻あわせ (rdate コマンドを使用)
    rdate -s <信頼できるマシンのIPアドレス>
    

    注: `rdate` は推奨されない。NTPクライアントまたは `timedatectl` コマンドを使用するのが一般的である。

  2. インストール
    # Ubuntu 24.04 LTSの場合
    sudo apt update
    sudo apt install bind9 bind9utils
    

    注: Ubuntu 24.04 LTSの標準インストールではchrootは含まれず、設定ファイルは`/etc/bind`、データディレクトリは`/var/cache/bind`などに格納される。`bind-chroot` パッケージはUbuntuには存在しない。本記事は別途,chroot環境構成を終えていることを前提とする。

なお、/etc/named.conf は、/var/named/chroot/etc/named.conf へのシンボリックリンクになっているはずなので確認する(bind-chrootを別途設定した場合の例であり、Ubuntu 24.04 LTSの標準構成とは異なる)。

# 以下の出力例は古い環境や特定の構成のものであることに注意
[root@cent01 ~]# ls -la /var/named/chroot/etc/named.conf
-rw-r--r-- 1 root root 1564 4月 20 18:59 /var/named/chroot/etc/named.conf
[root@cent01 etc]# ls -al /etc/named.conf
lrwxrwxrwx 1 root root 32 4月 20 18:29 /etc/named.conf -> /var/named/chroot/etc/named.conf

仮のゾーンファイルの作成とチェック

ここでは、仮のゾーンファイル public.zone, public.rev, db.zone, dbrev.rev を作成する。次に、named.conf を設定して public.zone, public.rev を使うようにする。その後、実際に DNS サーバを起動して簡単なチェックまでを行う。db.zone, dbrev.rev を使う設定は後回しである。

まず, 下記のゾーンファイルのごく簡単なサンプルを作成する。 ディレクトリパスは特定のchroot環境を前提とする。

  1. /var/named/chroot/var/named/data/public.zone
  2. /var/named/chroot/var/named/data/public.rev
  3. /var/named/chroot/var/named/data/db.zone
  4. /var/named/chroot/var/named/data/dbrev.rev

正引き

/var/named/chroot/var/named/data/public.zone, /var/named/chroot/var/named/data/db.zone は仮に次のように設定する。 ドメイン名の末尾の「.」は必要である。

cd /var/named/chroot/var/named/data
vi public.zone
# 以下のように設定
----------------------------------------------------------------------------
$TTL 86400
@ IN SOA dnsmail.mydomain.hoge.com. root.mydomain.hoge.com.(
2006051601 ; Serial (注: 日付形式YYYYMMDDNN、例: 2024073001)
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS dnsmail.mydomain.hoge.com.
IN MX 10 dnsmail.mydomain.hoge.com.
@ IN A XXX.YYY.ZZZ.160
dnsmail IN A XXX.YYY.ZZZ.160
www IN A XXX.YYY.ZZZ.167
hohoge IN A AAA.BBB.CCC.10
----------------------------------------------------------------------------
cp public.zone db.zone

逆引き

/var/named/chroot/var/named/data/public.rev, /var/named/chroot/var/named/data/dbrev.rev は仮に次のように設定する。

cd /var/named/chroot/var/named/data
vi public.rev
# 以下のように設定
----------------------------------------------------------------------------
$TTL 86400
@ IN SOA dnsmail.mydomain.hoge.com. root.mydomain.hoge.com.(
2006051601 ; Serial (注: 日付形式YYYYMMDDNN、例: 2024073001)
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS mydomain.hoge.com.
160 IN PTR dnsmail.mydomain.hoge.com.
167 IN PTR www.mydomain.hoge.com.
----------------------------------------------------------------------------
cp public.rev dbrev.rev

オーナとパーミッションの設定

chown named:named /var/named/chroot/var/named/data/*
chmod 400 /var/named/chroot/var/named/data/public.zone*
chmod 400 /var/named/chroot/var/named/data/public.rev*
chmod 400 /var/named/chroot/var/named/data/db.zone*
chmod 400 /var/named/chroot/var/named/data/dbrev.rev*

もし chown named:named でエラーが出たときは、ユーザとグループを 次の手順で作成する(Ubuntuなどの主要ディストリビューションでは通常インストール時に作成される)。

Linux の場合

/usr/sbin/groupadd named
/usr/sbin/useradd -d /var/named/chroot/var/named -g named -s /sbin/nologin named

チェック

ネットワーク関係の設定ミス, named 等のインストールのミス, public.zone, public.rev の書き間違いを下記の手順でチェックする。

この手順で、仮の DNS サーバが立ち上がることになる。この仮の DNS サーバは public.zone, public.rev は使うが db.zone, dbrev.rev は使っていないことに留意する。

  1. /etc/resolv.conf のチェック

    cat /etc/resolv.conf で、今設定を行なっているマシンの IP アドレスが、「nameserver」の行に正しく記述されていることを確認する。これはクライアントがどのDNSサーバを使うかを定義するファイルである。

    cat /etc/resolv.conf
    

    注: Ubuntu 24.04 LTSではsystemd-resolvedがデフォルトで動作する場合がある。BINDサーバとして機能させるには、systemd-resolvedの設定確認や無効化が必要になることがある。

  2. /var/named/chroot/etc/named.conf の設定
    vi /var/named/chroot/etc/named.conf
    # 次のような zone 定義を末尾に追加する。
    ----------------------------------------------------------------------------
    // mydomain.hoge.com <-> XXX.YYY.ZZZ
    zone "mydomain.hoge.com" IN {
    type master;
    file "data/public.zone";
    allow-query { any; };
    };
    zone "ZZZ.YYY.XXX.in-addr.arpa" IN {
    type master;
    file "data/public.rev";
    allow-query { any; };
    };
    
  3. チェックツールを使って、named.conf ファイルの内容をチェックする

    エラーが出たら、named.conf を書き直す。

    named-checkconf /var/named/chroot/etc/named.conf
    
  4. チェックツールで, public.zone, public.rev をチェックする

    エラーが出たら、public.zone, public.rev を書き直す。

    # named-checkzone <ゾーン名> <ゾーンファイルパス> の形式で使用する
    # 正引きゾーンのチェックにはゾーン名 (ドメイン名) を指定する
    named-checkzone mydomain.hoge.com /var/named/chroot/var/named/data/public.zone
    # 逆引きゾーンのチェックには逆引きゾーン名 (.in-addr.arpa または .ip6.arpa) を指定する
    named-checkzone ZZZ.YYY.XXX.in-addr.arpa /var/named/chroot/var/named/data/public.rev
    
  5. DNS サーバの起動を試みる

    DNS サーバ起動時にエラーが出たら、関係する設定ファイル (ここでは named.conf, public.zone, public.rev) を見直し、もう1度再起動する。 エラーメッセージは journalctl または /var/log/syslog で確認する。

    # systemd環境 (Ubuntu 24.04 LTS) の場合
    sudo systemctl stop named.service
    pkill named # namedプロセスが残っている場合のために実行
    sudo systemctl start named.service
    
    ログの確認 (どちらか実行)
    
    journalctl -u named.service
    
    または
    
    cat /var/log/syslog | grep named
    
  6. /var/run/named/named.pid のシンボリックリンク作成

    この手順は systemd 環境ではpidファイルの管理方法が異なるため、不要または適切なパスが異なる場合がある。現在の環境で必要か確認すること。

    # systemd環境では通常不要だが、元の記述を維持
    rm -f /var/run/named/named.pid
    ln -s /var/named/chroot/var/run/named/named.pid /var/run/named/named.pid
    
  7. 起動チェック (デバッグモード)

    起動チェックのため、最初はデバッグモードで起動してみる。(起動の前に named の停止を行う).

    # systemd環境 (Ubuntu 24.04 LTS) の場合
    sudo systemctl stop named.service
    pkill named # namedプロセスが残っている場合のために実行
    rm -f /var/named/chroot/var/named/data/named.log # ログファイルを削除してクリア
    
    デバッグモードで起動 (namedのバージョンやOSによりパスが異なる場合がある)
    /usr/sbin/named -u named -t /var/named/chroot -c /etc/named.conf -d 1 # 例
    systemd-run --scope --slice=named --uid=named /usr/sbin/named -t /var/named/chroot -c /etc/named.conf -d 1 # systemd-runを使用する別の例
    ログファイルを確認
    
    cat /var/named/chroot/var/named/data/named.log
    
    「cat /var/named/chroot/var/named/data/named.log」の結果ログが出てくるため、エラーが出ていないことを十分に確認する。

    参考:

    • -u: named の実行ユーザ (通常は named に設定する)
    • -t: chroot 先 (任意のディレクトリで良いが、ここでは /var/named/chroot に設定する)
    • -c: named.conf の場所 (任意のディレクトリで良いが、ここでは /etc/named.conf に設定する)
  8. オーナの設定
    chown -R named:named /var/named/chroot
    

    注: chroot環境のディレクトリ構成や実行ユーザーによっては、他のディレクトリ(例: `/var/run/named`)のパーミッション設定も必要となる場合がある。

  9. DNS サーバの起動を試みる

    下記の手順で、DNS サーバを起動する。起動時にエラーが出たら、関係する設定ファイル (ここでは named.conf, public.zone, public.rev, db.zone, dbrev.rev) を見直し、もう1度再起動する。 エラーメッセージは journalctl または /var/log/syslog で確認する。

    # systemd環境 (Ubuntu 24.04 LTS) の場合
    sudo systemctl stop named.service
    pkill named # namedプロセスが残っている場合のために実行
    sudo systemctl start named.service
    # sudo systemctl enable named.service # 起動時に自動起動する場合に実行
    
    ログの確認 (どちらか実行)
    
    journalctl -u named.service
    
    または
    
    cat /var/log/syslog | grep named
    
  10. ログの確認

    /var/named/chroot/var/named/data に 2つのログファイル named.log, security.log が作成されるため確認する。named.log の中にエラーが無いことを確認する。

    cd /var/named/chroot/var/named/data
    ls -la *.log
    tail named.log
    
  11. rndc との通信ができていることのチェック
    rndc status
    # エラーが無く、「server is up and running」という行が出てくることを確認する
    
  12. /etc/hosts.allow の設定について

    TCP wrapper の設定ファイルである /etc/hosts.allow を確認する。現代のシステムではFirewall (例: UFW) による制御が推奨される場合が多い。

    53/UDP は通常の名前解決に使われ、53/TCP はゾーン転送などに使われる。 53/TCP のアクセスは、XXX.YYY.ZZZ.* のネットワークのみを許すように設定する例を示す。

    # /etc/hosts.allow での例 (推奨されない場合がある)
    named: 127.0.0.1
    named: XXX.YYY.ZZZ.
    

    注: Ubuntu 24.04 LTSでは UFW (`sudo ufw allow 53/udp`, `sudo ufw allow 53/tcp from XXX.YYY.ZZZ.0/24`) の設定が推奨される。

rndc についての補足説明

rndc はBINDのリモート管理ツールである。設定ファイル `/etc/rndc.conf` と `/var/named/chroot/etc/rndc.key` が関係する。bind インストール時に生成される鍵をそのまま使用できる。

chroot 化に関する補足説明

DNS サーバプロセス (named) が chroot 化されている状態について説明する。 これは、named プロセスが chroot によって、ルートディレクトリ「/」が実際には設定されたサブディレクトリになっている状態である。

named プロセスから見たルートディレクトリは /var/named/chroot であり、その配下に本来のルートファイルシステム構造を模倣したディレクトリが配置されている。設定ファイルの実体は、chroot環境内から見たパス(例: `/var/named/etc/named.conf`)にある。

このような設定をする理由はセキュリティである。named が乗っ取られた場合に、プロセスが参照できるファイルシステム範囲をchroot環境内に限定することで、named 関係以外のファイルシステムへの被害を抑制できる。Ubuntu 24.04 LTSでは標準でchrootは有効になっておらず、手動設定が必要である。

クライアント側の設定

DNSクライアントとしての設定についても確認しておく。

  1. /etc/resolv.conf

    DNS がうまく動かないと思った時は、クライアント側の /etc/resolv.conf も確認すること。ここに設定されたnameserverに対して名前解決の問い合わせが行われる。

  2. /etc/nsswitch.conf

    次のように、hosts の行に「dns」を含むこと。これにより、名前解決の際にまずhostsファイルを参照し、次にNIS、そしてDNSを参照する順序が定義される。

    hosts: files nis dns
    
  3. /etc/host.conf について

    order hosts,bind
    

    注: 多くのLinuxシステム、特にUbuntu 24.04 LTSでは `/etc/nsswitch.conf` の設定が名前解決の優先順位を決定するため、この設定は必須ではない場合が多い。

    上記の設定後、

    MX, Web サーバの順引き、逆引きができることを確実に確認する(下記の「演習項目」を参照すること)。

演習項目

ここでは、設定したDNSサーバの動作確認方法について説明する。

nslookup, dig, host の使い方の練習

nslookup

注: `nslookup` コマンドは現在非推奨 (deprecated) である。代わりに `dig` または `host` コマンドの使用が推奨される。

  1. 下記の手順で、ゾーンファイルに記述したホスト名とIPとの対応をテストする。
    # nslookup               <--nslookupを起動
    > server <DNSサーバのIPアドレス>   <--問い合わせるDNSサーバを指定
    
    
    //正引きのテスト方法
    > <ホスト名> <--ゾーンファイルに記述したホスト名
    Server: 
    Address: #<ポート番号>
    
    Name: <ゾーンファイルに記述したホスト名>
    Address: <対応するIPアドレス> <--ゾーンファイルに記述したIPが返れば良い
    
  2. 下記の手順で、逆引きをテストする。
    > <IPアドレス> <--逆引きゾーンファイルに記述したIPに対応するIP
    Server: DNSサーバのIPアドレス
    Address: DNSサーバのIPアドレス#ポート番号
    
    
    .in-addr.arpa name=<対応するホスト名> <--逆引きゾーンファイルに記述
    したホスト名がFQDN形式で返れば良い
    

nslookup は exit で終了する。

dig

注: `dig` コマンドはDNSの問い合わせに広く使われる標準的なツールである。

  1. 下記の手順で、正引きをテストする。
    dig @<DNSサーバのIPアドレス> <調べたいホスト名>
    
  2. 下記の手順で、逆引きをテストする。
    # dig @<DNSサーバのIPアドレス> -x <調べたいIP> ptr
    
  3. チェック項目について述べる。
    ;; ->>HEADER<<-の部分で
     ・status:がNOERROR である。
       status:ではサーバからの応答の状態を表す。
        NOERROR:DNSサーバが正常に応答したことを示す。
        NXDOMAIN:問い合わせたドメインが存在しないことを示す。
        SERVFAIL:DNSサーバが正しく応答しなかったことを示す。
     ・flags:にqr,aaがあるか確認する。内部マシンからdigをした場合raもあるはずである。
       flags:には以下の5つがある。
        qr:クエリに対する回答であることを示す。
        aa:回答が権限のある回答であることを示す。
        tc:回答が長くて切り捨てられたことを示す。
        ra:サーバが再帰可能であることを示す。
        rd:再帰希望のフラグが設定されていることを示す。
     ・ANSWER:が1以上であるか確認する。
       ANSWER:では問い合わせに対する回答の数を示す。
    ;;ANSWER SECTION:がゾーンファイルに設定した通りであるかどうかを確認する。
    

host

注: `host` コマンドも簡単な名前解決の確認に便利である。

# 正引き
host <調べたいホスト名> <DNSサーバのIPアドレス>

逆引き

host <調べたいIPアドレス> 

ゾーンファイル db.zone, dbrev.rev のメンテナンス

ゾーンファイルdb.zone, dbrev.revのメンテナンス手順は以下の通りである (グローバルIPを持つマシンの追加・削除を行う場合)。

  1. ゾーンファイルに変更を加える前に、バックアップを取得しておく。
    # cd /var/named/chroot/var/named/data
    # cp db.zone db.zone.backYYYYMMDD    <--その日の日付 (例: db.zone.back20240730)
    # cp dbrev.rev dbrev.rev.backYYYYMMDD  <--その日の日付 (例: dbrev.rev.back20240730)
    
  2. db.zoneのAレコードを追加・削除する。
    //Aレコードの記述例
    hostname IN A XXX.YYY.ZZZ.200
    
  3. dbrev.revのPTRレコードを追加・削除する。
    //PTRレコードの記述例
    200 IN PTR hostname.mydomain.hoge.com.
    
  4. SOAレコードのシリアル番号を更新する。 シリアル番号は
     YYYYMMDDNN (例: 2024073001)
     "更新した年月日+その日の更新回数"
    
    のように設定する。Serial番号を増やすことで、セカンダリサーバなどがゾーンファイルの更新を検知できるようになる。
  5. ゾーンファイルの変更を反映させるためにnamedをリロードまたは再起動する。
    # namedプロセスにHUPシグナルを送る (古い方法であり、推奨されない場合がある)
    # kill -HUP `cat /var/named/chroot/var/run/named/named.pid`
    
    推奨される方法 (rndc reload または systemctl reload named.service)
    
    rndc reload # ゾーンファイルのみ再読み込み、キャッシュは保持される
    
    または
    
    sudo systemctl reload named.service # namedサービスをリロードする
    
    namedサービスの再起動 (キャッシュもクリアされる)
    sudo systemctl restart named.service
    

    注: `rndc reload` または `systemctl reload named.service` の使用が推奨される。

rndc 関係

rndc はBINDのリモート管理ツールである。

  1. 設定ファイルとゾーンファイルを再読み込みする。ただしキャッシュデータは保持される。
    rndc reload
    # ログファイルを見てエラーが無いことを確認する
    tail /var/named/chroot/var/named/data/named.log
    
  2. キャッシュをファイルにダンプする。出力先はnamed.confのoptions中のdump-fileで定義する。出力先を定義していない場合はワークディレクトリの cache_dump.dbに出力される。
    rndc dumpdb
    # 出力結果を確認
    cat /var/named/chroot/var/named/data/cache_dump.db
    
  3. キャッシュをすべてフラッシュする。
    rndc flush
    # キャッシュをファイルに出力してクリアされたことを確認する
    rndc dumpdb
    cat /var/named/chroot/var/named/data/cache_dump.db
    
  4. サーバの統計情報をファイルにダンプする。出力先はnamed.confのoptions中のstatistics-fileで定義する。出力先を定義していない場合はワークディレクトリのnamed_stats.txtに出力される。
    rndc stats
    # 出力結果を確認
    cat /var/named/chroot/var/named/data/named_stats.txt
    

    出力結果の意味について述べる。

     success   問い合わせに成功したクエリー数である。
     referral   問い合わせに対し参照となったクエリー数である。
     nxrrset   問い合わせに対するレコード型が存在しなかったクエリー数である。
     nxdomain   問い合わせに対するドメイン名やホスト名が存在しなかったクエリー数である。
     recursion  再帰問い合わせを行ったクエリー数である。
     failure   エラーとなったクエリー数である。
    

内部向けのゾーンファイルと、外部向けのゾーンファイルが正しく動いていることを bind のコマンドで確認する

この項目は「後回し」とする。具体的には、内部ネットワークと外部ネットワークの異なるクライアントから、それぞれ期待される名前解決が行われるかを確認する必要がある。


以上の演習が済んだら、仮に設定されたゾーンファイルを本格的なものに書き換える。その後、DNS 管理コマンドについての練習及び DNS サーバの動作確認を再度行う。