ISPのデフォルトDNS — 使えるが制御できない
私は50人規模のオフィスと小規模なデータセンターのネットワークを管理しています。最初の数年は8.8.8.8と1.1.1.1に任せきりでした。RouterがDHCPでIPを割り当て、クライアントはISPのDNSを使う——「みんなそうしてるんだから問題ない」という感じで。しかし徐々に問題が積み重なってきました:
- 内部ホスト名が名前解決できない — サーバーにSSHするたびに、
server1.office.localの代わりにIPアドレスを入力する必要がある - すべてのDNSクエリがインターネットに出て行き、平均30〜40msかかる。ローカルキャッシュなら1ms以下なのに
- split-DNSができない — 内部と外部で同じIPを返すしかない
- ログがない。ネットワークに問題が発生したとき、どこから調査すればいいか分からない
そこでBind9を導入することにしました。世界中のプロダクションサーバーで20年以上稼働してきた実績があり、現在も活発にメンテナンスされている最も歴史あるDNSソフトウェアです——プロダクション環境で信頼して使うには十分な理由があります。
インストール前に:押さえておくべき基本概念
Bind9にはさまざまな役割があります:authoritative server(ドメインの権威サーバー)、recursive resolver(クライアントに代わって問い合わせる)、またはその両方。この記事ではauthoritative + forwarderモードのみ使用します——オフィスネットワークには十分で、それ以上複雑にする必要はありません。
押さえておくべき基本用語
- Zone:DNS管理の単位。例:
office.localやexample.com - A record:ホスト名をIPv4アドレスに対応付ける。例:
server1.office.local → 192.168.1.10 - PTR record:逆引きDNS——IPアドレスをホスト名に対応付ける。A recordの逆方向
- NS record:ゾーンのネームサーバーを宣言する
- SOA record:ゾーンのメタデータ——serial、refresh、retry、expire
- Forwarder:Bind9が回答できない場合、クエリを別のDNS(例:8.8.8.8)に転送する
今回は192.168.1.0/24のネットワーク向けに、office.localドメインの内部DNSを構築します。全体の流れを最初から最後まで実演するのに十分な環境です。
Bind9のインストールと設定
ステップ1:Bind9のインストール
Ubuntu/Debianの場合:
sudo apt update
sudo apt install -y bind9 bind9utils bind9-doc dnsutils
インストール後、namedサービスが自動起動します。素早く確認:
sudo systemctl status named
ステップ2:named.conf.optionsの設定
ファイル/etc/bind/named.conf.options——フォワーダーとアクセスコントロールを定義する場所:
sudo nano /etc/bind/named.conf.options
acl "trusted" {
192.168.1.0/24; // 内部ネットワーク
localhost;
localnets;
};
options {
directory "/var/cache/bind";
// 信頼できるネットワークからのクエリのみ許可
allow-query { trusted; };
allow-recursion { trusted; };
// フォワーダー — 不明な場合はCloudflareへ転送
forwarders {
1.1.1.1;
8.8.8.8;
};
forward only;
dnssec-validation auto;
listen-on { any; };
listen-on-v6 { any; };
};
forward onlyの行が重要です:Bind9は自分で外部に再帰問い合わせせず、すべてフォワーダーに委ねます。オフィスネットワークではこの方法が高速でシンプルです。Bind9に8.8.8.8に依存せず完全に自己解決させたい場合は、この行を削除してください。
ステップ3:named.conf.localでのゾーン宣言
sudo nano /etc/bind/named.conf.local
// フォワードゾーン
zone "office.local" {
type master;
file "/etc/bind/zones/db.office.local";
};
// 192.168.1.0/24の逆引きゾーン
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.192.168.1";
};
ステップ4:フォワードゾーンファイルの作成
sudo mkdir /etc/bind/zones
sudo nano /etc/bind/zones/db.office.local
;
; office.localのフォワードゾーンファイル
;
$TTL 604800
@ IN SOA ns1.office.local. admin.office.local. (
2026022801 ; シリアル番号 (形式: YYYYMMDDNN)
604800 ; リフレッシュ間隔 (7日)
86400 ; リトライ間隔 (1日)
2419200 ; 有効期限 (28日)
604800 ; ネガティブキャッシュTTL
)
; ネームサーバー
@ IN NS ns1.office.local.
; Aレコード
ns1 IN A 192.168.1.1
gateway IN A 192.168.1.1
server1 IN A 192.168.1.10
server2 IN A 192.168.1.11
nas IN A 192.168.1.20
printer IN A 192.168.1.30
シリアル番号はYYYYMMDDNN形式:今日の日付+その日の連番です。今日は2026年2月28日で、最初の修正なら2026022801となります。ゾーンを修正するたびに必ずシリアルを増やしてください——これを忘れると、スレーブDNSがエラーを出さずに静かにアップデートを無視します。この件で午前中まるごとデバッグに費やしたことがあります。
ステップ5:逆引きゾーンファイルの作成
sudo nano /etc/bind/zones/db.192.168.1
;
; 192.168.1.0/24の逆引きゾーンファイル
;
$TTL 604800
@ IN SOA ns1.office.local. admin.office.local. (
2026022801
604800
86400
2419200
604800
)
@ IN NS ns1.office.local.
; PTRレコード(ホスト部分のみ記載、フルIPは不要)
1 IN PTR ns1.office.local.
10 IN PTR server1.office.local.
11 IN PTR server2.office.local.
20 IN PTR nas.office.local.
30 IN PTR printer.office.local.
ステップ6:再起動前の設定検証
このステップは絶対に省略しないでください。以前、確認せずにnamedを再起動したことがあり、ゾーンファイルのタイポでオフィス全体のDNSが約10分間停止しました:
# named.confを検証する
sudo named-checkconf
# 各ゾーンファイルを検証する
sudo named-checkzone office.local /etc/bind/zones/db.office.local
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/zones/db.192.168.1
OKと表示されたら再起動:
sudo systemctl restart named
sudo systemctl enable named
ステップ7:クライアントからのテスト
192.168.1.0/24のネットワーク内のマシンから、DNSを192.168.1.1に向けてテストします:
# 正引き
dig @192.168.1.1 server1.office.local
nslookup server1.office.local 192.168.1.1
# 逆引き
dig @192.168.1.1 -x 192.168.1.10
# フォワーダーのテスト — 外部ドメインへのクエリ
dig @192.168.1.1 google.com
正引きが成功すると次のように返ってきます:
;; ANSWER SECTION:
server1.office.local. 604800 IN A 192.168.1.10
内部ホスト名のクエリタイムは、一度キャッシュされると通常1ms未満です。8.8.8.8に直接クエリした場合の30〜40msと比べると大きな差があります。
よくあるトラブルシューティング
- SERVFAIL:ゾーンファイルの構文エラー —
named-checkzoneを再実行する - REFUSED:クライアントのIPがACL
trustedに含まれていない —allow-queryを確認する - Timeout:ファイアウォールがポート53のUDP/TCPをブロックしている —
ufw allow 53 - スレーブが新しいゾーンを受け取らない:シリアルが増えていない — 最も多いミスで、エラーも表示されない
# デバッグ時のリアルタイムログ確認
sudo tail -f /var/log/syslog | grep named
まとめ
Bind9のセットアップ全体で約30分かかります。実際の成果:内部ホスト名が解決できるようになり、クエリタイムが30〜40msから1ms未満に短縮され、ネットワーク障害時に使えるまともなログを初めて手に入れました。
次のステップはsplit-DNSです——server1.example.comが内部からのクエリにはプライベートIP、外部からのクエリにはパブリックIPを返すように設定します。これについては次の記事で書く予定です。
10人以上のチームのネットワークを管理しているなら、問題が起きてから対応するのではなく、今すぐ設定することをお勧めします。内部DNSは一度構築すれば永続的に恩恵を受けられます——文字通りの意味で。
