DNS Configuration and Management

Linux DNS 設定と管理 完全ガイド

目次

  1. はじめに
  2. DNS の基礎概念
  3. DNS 診断コマンド
  4. ローカル名前解決の設定
  5. systemd-resolved
  6. BIND9 詳細解説
  7. dnsmasq
  8. DNS キャッシング
  9. DNS セキュリティ
  10. トラブルシューティング
  11. ベストプラクティス
  12. 比較表
  13. 参考文献

1. はじめに

DNS(Domain Name System)は、インターネットの根幹をなすシステムであり、人間が読めるドメイン名をIPアドレスに変換する分散データベースシステムである。本ガイドでは、Linux における DNS の設定と管理を包括的に解説する。

対象読者

  • Linux システム管理者
  • ネットワークエンジニア
  • SRE / DevOps エンジニア

2. DNS の基礎概念

2.1 DNS の仕組み

DNS は階層的な分散データベースシステムであり、以下の構成要素から成る。

                    . (ルート)
                    │
         ┌──────────┼──────────┐
         │          │          │
       .com       .org       .jp
         │          │          │
    ┌────┼────┐     │     ┌───┼───┐
    │    │    │     │     │       │
 google example  wikipedia co    ac
    │    │                │       │
   www  www            example  todai
                        │
                       www

DNS サーバーの種類

種類説明
ルートネームサーバーDNS 階層の最上位。TLD サーバーの情報を保持a.root-servers.net ~ m.root-servers.net
TLD ネームサーバートップレベルドメインを管理a.gtld-servers.net (.com)
権威ネームサーバー特定のドメインのゾーン情報を保持ns1.example.com
キャッシュ/再帰ネームサーバークライアントの代わりに名前解決を実行8.8.8.8 (Google Public DNS)
フォワーダークエリを別のサーバーに転送ローカル dnsmasq

2.2 DNS レコードタイプ

レコード説明
Aドメイン名を IPv4 アドレスに対応付けwww.example.com. IN A 93.184.216.34
AAAAドメイン名を IPv6 アドレスに対応付けwww.example.com. IN AAAA 2606:2800:220:1:...
CNAMEドメイン名の別名(エイリアス)blog.example.com. IN CNAME www.example.com.
MXメールサーバーを指定(優先度付き)example.com. IN MX 10 mail.example.com.
NSゾーンの権威ネームサーバーを指定example.com. IN NS ns1.example.com.
PTRIP アドレスからドメイン名への逆引き34.216.184.93.in-addr.arpa. IN PTR www.example.com.
SOAゾーンの管理情報(シリアル、リフレッシュ等)後述
TXTテキスト情報(SPF、DKIM、検証等)example.com. IN TXT "v=spf1 mx -all"
SRVサービスのロケーション情報_sip._tcp.example.com. IN SRV 10 60 5060 sip.example.com.
CAA証明書発行認可example.com. IN CAA 0 issue "letsencrypt.org"

SOA レコードの詳細

example.com.  IN  SOA  ns1.example.com. admin.example.com. (
    2026041001  ; シリアル番号 (YYYYMMDDnn)
    3600        ; リフレッシュ間隔 (1時間)
    900         ; リトライ間隔 (15分)
    604800      ; 有効期限 (7日)
    86400       ; ネガティブキャッシュTTL (1日)
)
フィールド説明
MNAMEプライマリネームサーバー
RNAME管理者のメールアドレス(@を.に置換)
SERIALゾーンのバージョン番号
REFRESHセカンダリがプライマリを確認する間隔
RETRYリフレッシュ失敗時のリトライ間隔
EXPIREセカンダリがゾーンデータを無効とするまでの時間
MINIMUMネガティブキャッシュの TTL

SRV レコードの詳細

_service._proto.name. TTL class SRV priority weight port target.

# 例: SIP サービス
_sip._tcp.example.com. 3600 IN SRV 10 60 5060 sipserver1.example.com.
_sip._tcp.example.com. 3600 IN SRV 10 40 5060 sipserver2.example.com.
_sip._tcp.example.com. 3600 IN SRV 20 0  5060 sipbackup.example.com.

2.3 DNS 名前解決の流れ

クライアント → ローカルリゾルバ → キャッシュ確認
                                    │
                                    ├─ キャッシュにあり → 応答を返す
                                    │
                                    └─ キャッシュになし → 再帰問い合わせ開始
                                         │
                                         ├─ ルートサーバーに問い合わせ
                                         │   → TLD サーバーの情報を取得
                                         │
                                         ├─ TLD サーバーに問い合わせ
                                         │   → 権威サーバーの情報を取得
                                         │
                                         └─ 権威サーバーに問い合わせ
                                             → 最終的な回答を取得
                                             → キャッシュに保存
                                             → クライアントに応答

3. DNS 診断コマンド

3.1 dig コマンド

dig(Domain Information Groper)は最も強力な DNS 診断ツールである。

# 基本的な A レコード問い合わせ
$ dig example.com

; <<>> DiG 9.18.18 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.com.                   IN      A

;; ANSWER SECTION:
example.com.            86400   IN      A       93.184.216.34

;; Query time: 25 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Thu Apr 10 10:00:00 UTC 2026
;; MSG SIZE  rcvd: 56

# 特定のレコードタイプを問い合わせ
$ dig example.com MX
$ dig example.com AAAA
$ dig example.com NS
$ dig example.com SOA
$ dig example.com TXT
$ dig _sip._tcp.example.com SRV

# 特定の DNS サーバーを指定
$ dig @8.8.8.8 example.com
$ dig @ns1.example.com example.com

# 逆引き
$ dig -x 93.184.216.34
;; ANSWER SECTION:
34.216.184.93.in-addr.arpa. 86400 IN PTR www.example.com.

# 簡潔な出力
$ dig +short example.com
93.184.216.34

$ dig +short example.com MX
10 mail.example.com.

# トレース(名前解決の過程を表示)
$ dig +trace example.com
.                       86400   IN      NS      a.root-servers.net.
...
com.                    172800  IN      NS      a.gtld-servers.net.
...
example.com.            86400   IN      A       93.184.216.34

# DNSSEC 検証情報を含む
$ dig +dnssec example.com

# ANY レコード(全レコード)
$ dig example.com ANY

# TCP での問い合わせ
$ dig +tcp example.com

# 応答のセクション制御
$ dig +noall +answer example.com    # ANSWER セクションのみ
$ dig +noall +authority example.com  # AUTHORITY セクションのみ

# ゾーン転送の試行(AXFR)
$ dig @ns1.example.com example.com AXFR

# バッチ問い合わせ
$ dig -f queries.txt

3.2 nslookup コマンド

# 基本的な問い合わせ
$ nslookup example.com
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
Name:   example.com
Address: 93.184.216.34

# 特定のサーバーを指定
$ nslookup example.com 8.8.8.8

# レコードタイプの指定
$ nslookup -type=MX example.com
$ nslookup -type=NS example.com
$ nslookup -type=SOA example.com
$ nslookup -type=TXT example.com

# 逆引き
$ nslookup 93.184.216.34

# インタラクティブモード
$ nslookup
> server 8.8.8.8
> set type=MX
> example.com
> exit

3.3 host コマンド

# 基本的な問い合わせ
$ host example.com
example.com has address 93.184.216.34
example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946
example.com mail is handled by 0 .

# 特定のレコードタイプ
$ host -t MX example.com
example.com mail is handled by 10 mail.example.com.

$ host -t NS example.com
example.com name server ns1.example.com.
example.com name server ns2.example.com.

# 逆引き
$ host 93.184.216.34
34.216.184.93.in-addr.arpa domain name pointer www.example.com.

# 詳細出力
$ host -v example.com

# 特定の DNS サーバーを指定
$ host example.com 8.8.8.8

# ゾーン転送の試行
$ host -l example.com ns1.example.com

4. ローカル名前解決の設定

4.1 /etc/hosts

# /etc/hosts の基本形式
# IP_ADDRESS    FQDN              ALIAS
127.0.0.1       localhost
127.0.1.1       myhost.example.com myhost
::1             localhost ip6-localhost ip6-loopback

# サーバーの追加
192.168.1.10    web01.internal.example.com  web01
192.168.1.11    web02.internal.example.com  web02
192.168.1.20    db01.internal.example.com   db01
192.168.1.21    db02.internal.example.com   db02

# 開発環境の例
192.168.1.100   dev.myapp.local
192.168.1.100   api.myapp.local
192.168.1.100   admin.myapp.local

4.2 /etc/resolv.conf

# /etc/resolv.conf の設定
# ドメイン名
domain example.com

# 検索ドメイン(短縮名に自動付加)
search example.com internal.example.com

# ネームサーバー(最大3つ)
nameserver 192.168.1.1
nameserver 8.8.8.8
nameserver 8.8.4.4

# オプション
options timeout:2         # タイムアウト(秒)
options attempts:3        # リトライ回数
options rotate           # サーバーのラウンドロビン
options ndots:2          # 絶対名と見なすドット数の閾値
options edns0            # EDNS0 の有効化
options single-request   # A と AAAA を順次問い合わせ

注意: systemd-resolved や NetworkManager を使用している場合、/etc/resolv.conf は自動管理される。

# resolv.conf の管理状態を確認
$ ls -la /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Apr 10 10:00 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

# 直接編集する場合はリンクを解除
$ sudo rm /etc/resolv.conf
$ sudo vi /etc/resolv.conf

4.3 /etc/nsswitch.conf

# /etc/nsswitch.conf での名前解決順序
hosts:  files dns myhostname

# files: /etc/hosts を参照
# dns: DNS サーバーを参照
# myhostname: システムのホスト名を解決
# mdns4_minimal: mDNS (.local ドメイン)
# resolve: systemd-resolved

5. systemd-resolved

5.1 概要と設定

systemd-resolved は、systemd に統合された名前解決サービスである。

# サービスの状態確認
$ sudo systemctl status systemd-resolved
● systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled)
     Active: active (running)

# 設定ファイル
# /etc/systemd/resolved.conf
$ sudo cat /etc/systemd/resolved.conf
[Resolve]
# DNS サーバー
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 1.0.0.1

# ドメイン
Domains=example.com internal.example.com

# DNSSEC
DNSSEC=allow-downgrade

# DNS over TLS
DNSOverTLS=opportunistic

# キャッシュ
Cache=yes

# マルチキャスト DNS
MulticastDNS=yes

# LLMNR
LLMNR=yes

resolv.conf のモード

# スタブリゾルバモード(推奨)
$ sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# → 127.0.0.53 を参照(systemd-resolved 経由)

# 直接モード
$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
# → 実際の DNS サーバーを直接参照

5.2 resolvectl コマンド

# DNS 設定の確認
$ resolvectl status
Global
       Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=allow-downgrade/unsupported
resolv.conf mode: stub

Link 2 (eth0)
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=allow-downgrade/unsupported
Current DNS Server: 192.168.1.1
       DNS Servers: 192.168.1.1
        DNS Domain: example.com

# DNS の問い合わせ
$ resolvectl query example.com
example.com: 93.184.216.34
             2606:2800:220:1:248:1893:25c8:1946

-- Information acquired via protocol DNS in 25ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no

# 統計情報の確認
$ resolvectl statistics
DNSSEC supported by current servers: no

Transactions
Current Transactions: 0
  Total Transactions: 1234

Cache
  Current Cache Size: 45
          Cache Hits: 890
        Cache Misses: 344

DNSSEC Verdicts
              Secure: 0
            Insecure: 1234
               Bogus: 0
       Indeterminate: 0

# キャッシュのフラッシュ
$ resolvectl flush-caches
$ resolvectl statistics  # キャッシュサイズが0になることを確認

# 特定のインターフェースの DNS 設定
$ resolvectl dns eth0 8.8.8.8 8.8.4.4
$ resolvectl domain eth0 example.com

5.3 DNS over TLS (DoT)

# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 8.8.8.8#dns.google
DNSOverTLS=yes

# サービスの再起動
$ sudo systemctl restart systemd-resolved

# 確認
$ resolvectl status
...
DNSOverTLS setting: yes
...

6. BIND9 詳細解説

6.1 インストールと基本設定

# Debian/Ubuntu
$ sudo apt install bind9 bind9utils bind9-dnsutils

# RHEL/CentOS
$ sudo yum install bind bind-utils

# サービスの管理
$ sudo systemctl enable named  # RHEL/CentOS
$ sudo systemctl enable bind9  # Debian/Ubuntu
$ sudo systemctl start named

ディレクトリ構造

/etc/bind/                      # Debian/Ubuntu
/etc/named/                     # RHEL/CentOS
├── named.conf                  # メイン設定ファイル
├── named.conf.options          # オプション設定
├── named.conf.local            # ローカルゾーン設定
├── named.conf.default-zones    # デフォルトゾーン
├── db.local                    # localhost の正引きゾーン
├── db.127                      # localhost の逆引きゾーン
├── db.root                     # ルートヒントファイル
└── zones/                      # カスタムゾーンファイル
    ├── db.example.com
    └── db.192.168.1

6.2 named.conf の構造

# /etc/bind/named.conf.options
options {
    directory "/var/cache/bind";

    // リスニングアドレスとポート
    listen-on port 53 { 127.0.0.1; 192.168.1.1; };
    listen-on-v6 port 53 { ::1; };

    // クエリを許可するクライアント
    allow-query { localhost; 192.168.1.0/24; 10.0.0.0/8; };

    // 再帰問い合わせを許可するクライアント
    allow-recursion { localhost; 192.168.1.0/24; };

    // 転送先サーバー
    forwarders {
        8.8.8.8;
        8.8.4.4;
    };

    // 転送モード(first: まず転送先に問い合わせ、only: 転送先のみ)
    forward first;

    // ゾーン転送の制限
    allow-transfer { none; };

    // DNSSEC
    dnssec-validation auto;

    // バージョン情報の非表示
    version "not disclosed";

    // 再帰問い合わせ
    recursion yes;

    // レスポンスレート制限
    rate-limit {
        responses-per-second 10;
        window 5;
    };

    // ログ
    querylog yes;
};

# /etc/bind/named.conf.local
// 正引きゾーン
zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { 192.168.1.2; };  // セカンダリサーバー
    also-notify { 192.168.1.2; };
};

// 逆引きゾーン
zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.192.168.1";
    allow-transfer { 192.168.1.2; };
};

// セカンダリゾーン
zone "other.com" {
    type slave;
    file "/var/cache/bind/db.other.com";
    masters { 10.0.0.1; };
};

ACL とログ設定

# ACL の定義
acl "internal" {
    192.168.1.0/24;
    10.0.0.0/8;
    127.0.0.1;
};

acl "secondary-servers" {
    192.168.1.2;
    192.168.1.3;
};

# ログ設定
logging {
    channel default_log {
        file "/var/log/named/default.log" versions 3 size 5m;
        severity info;
        print-time yes;
        print-severity yes;
        print-category yes;
    };

    channel query_log {
        file "/var/log/named/query.log" versions 5 size 10m;
        severity info;
        print-time yes;
    };

    channel security_log {
        file "/var/log/named/security.log" versions 3 size 5m;
        severity warning;
        print-time yes;
    };

    category default { default_log; };
    category queries { query_log; };
    category security { security_log; };
    category xfer-in { default_log; };
    category xfer-out { default_log; };
};

6.3 正引きゾーンの設定

# /etc/bind/zones/db.example.com
$TTL    86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2026041001      ; Serial
                        3600            ; Refresh (1 hour)
                        900             ; Retry (15 minutes)
                        604800          ; Expire (7 days)
                        86400 )         ; Negative Cache TTL (1 day)

; ネームサーバー
@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com.

; ネームサーバーの A レコード
ns1     IN      A       192.168.1.1
ns2     IN      A       192.168.1.2

; メールサーバー
@       IN      MX      10 mail.example.com.
@       IN      MX      20 mail2.example.com.

; Web サーバー
@       IN      A       192.168.1.10
www     IN      A       192.168.1.10
www     IN      AAAA    2001:db8::10

; アプリケーションサーバー
app     IN      A       192.168.1.20
api     IN      CNAME   app.example.com.

; メールサーバー
mail    IN      A       192.168.1.30
mail2   IN      A       192.168.1.31

; データベースサーバー
db01    IN      A       192.168.1.40
db02    IN      A       192.168.1.41

; 監視サーバー
monitor IN      A       192.168.1.50

; SRV レコード
_http._tcp      IN      SRV     10 60 80 www.example.com.
_https._tcp     IN      SRV     10 60 443 www.example.com.

; TXT レコード
@       IN      TXT     "v=spf1 mx ip4:192.168.1.30 -all"

; CAA レコード
@       IN      CAA     0 issue "letsencrypt.org"
@       IN      CAA     0 iodef "mailto:admin@example.com"

; ワイルドカード
*.dev   IN      A       192.168.1.100

ゾーンファイルの検証

# named-checkzone でゾーンファイルを検証
$ named-checkzone example.com /etc/bind/zones/db.example.com
zone example.com/IN: loaded serial 2026041001
OK

# named-checkconf で設定ファイルを検証
$ named-checkconf /etc/bind/named.conf
# エラーがなければ出力なし

# 設定のリロード
$ sudo rndc reload
$ sudo rndc reload example.com  # 特定のゾーンのみ

6.4 逆引きゾーンの設定

# /etc/bind/zones/db.192.168.1
$TTL    86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2026041001      ; Serial
                        3600            ; Refresh
                        900             ; Retry
                        604800          ; Expire
                        86400 )         ; Negative Cache TTL

@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com.

; PTR レコード
1       IN      PTR     ns1.example.com.
2       IN      PTR     ns2.example.com.
10      IN      PTR     www.example.com.
20      IN      PTR     app.example.com.
30      IN      PTR     mail.example.com.
31      IN      PTR     mail2.example.com.
40      IN      PTR     db01.example.com.
41      IN      PTR     db02.example.com.
50      IN      PTR     monitor.example.com.

IPv6 逆引きゾーン

# /etc/bind/named.conf.local に追加
zone "8.b.d.0.1.0.0.2.ip6.arpa" {
    type master;
    file "/etc/bind/zones/db.2001:db8";
};

# /etc/bind/zones/db.2001:db8
$TTL    86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2026041001
                        3600
                        900
                        604800
                        86400 )

@       IN      NS      ns1.example.com.

0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0   IN   PTR   www.example.com.

6.5 ゾーン転送

プライマリサーバーの設定

# named.conf.local(プライマリ)
zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";

    // ゾーン転送を許可するセカンダリサーバー
    allow-transfer {
        192.168.1.2;      // ns2
        192.168.1.3;      // ns3
        key "transfer-key"; // TSIG キーによる認証
    };

    // ゾーン更新時にセカンダリに通知
    also-notify {
        192.168.1.2;
        192.168.1.3;
    };

    // NOTIFY メッセージの送信
    notify yes;
};

セカンダリサーバーの設定

# named.conf.local(セカンダリ)
zone "example.com" {
    type slave;
    file "/var/cache/bind/db.example.com";

    // プライマリサーバー
    masters {
        192.168.1.1;
    };

    // セカンダリからの転送は不許可
    allow-transfer { none; };
};

TSIG(Transaction Signature)による認証

# TSIG キーの生成
$ tsig-keygen transfer-key > /etc/bind/transfer-key.conf
# 出力例:
key "transfer-key" {
    algorithm hmac-sha256;
    secret "abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678==";
};

# named.conf に include
include "/etc/bind/transfer-key.conf";

# プライマリのゾーン設定
zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { key "transfer-key"; };
};

# セカンダリのサーバー設定
server 192.168.1.1 {
    keys { transfer-key; };
};

zone "example.com" {
    type slave;
    masters { 192.168.1.1; };
    file "/var/cache/bind/db.example.com";
};

ゾーン転送の確認

# AXFR(完全ゾーン転送)の確認
$ dig @192.168.1.2 example.com AXFR

# IXFR(増分ゾーン転送)の確認
$ dig @192.168.1.2 example.com IXFR=2026041000

# rndc によるゾーン転送の状態確認
$ sudo rndc zonestatus example.com
name: example.com
type: master
files: /etc/bind/zones/db.example.com
serial: 2026041001
nodes: 15
last loaded: Thu, 10 Apr 2026 10:00:00 GMT

6.6 DNSSEC

DNSSEC の概要

DNSSEC は、DNS 応答にデジタル署名を付与し、応答の改ざんを検出するためのセキュリティ拡張である。

キーの生成と署名

# KSK(Key Signing Key)の生成
$ cd /etc/bind/zones/
$ dnssec-keygen -a ECDSAP256SHA256 -f KSK -n ZONE example.com
Generating key pair...
Kexample.com.+013+12345

# ZSK(Zone Signing Key)の生成
$ dnssec-keygen -a ECDSAP256SHA256 -n ZONE example.com
Generating key pair...
Kexample.com.+013+67890

# ゾーンファイルにキーを追加
$ cat Kexample.com.+013+12345.key >> db.example.com
$ cat Kexample.com.+013+67890.key >> db.example.com

# ゾーンの署名
$ dnssec-signzone -A -3 $(head -c 1000 /dev/urandom | sha1sum | cut -b 1-16) \
    -N INCREMENT -o example.com -t db.example.com
Verifying the zone using the following algorithms: ECDSAP256SHA256.
Zone fully signed:
Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                            ZSKs: 1 active, 0 stand-by, 0 revoked
db.example.com.signed

BIND9 の自動 DNSSEC 管理(dnssec-policy)

# named.conf.options に DNSSEC ポリシーを定義
dnssec-policy "standard" {
    keys {
        ksk key-directory lifetime unlimited algorithm ecdsap256sha256;
        zsk key-directory lifetime 30d algorithm ecdsap256sha256;
    };
    max-zone-ttl 86400;
    zone-propagation-delay 300;
    parent-ds-ttl 3600;
    parent-propagation-delay 7200;
};

# ゾーン設定で使用
zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
    dnssec-policy "standard";
    inline-signing yes;
};

DNSSEC の検証

# DNSSEC 対応の問い合わせ
$ dig +dnssec example.com
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
# ad フラグ = Authenticated Data(DNSSEC 検証済み)

# DS レコードの確認
$ dig example.com DS +short
12345 13 2 ABCDEF1234567890...

# DNSKEY レコードの確認
$ dig example.com DNSKEY +short

# RRSIG レコードの確認
$ dig example.com RRSIG +short

# delv コマンドで詳細な検証
$ delv @8.8.8.8 example.com
; fully validated
example.com.    86400   IN      A       93.184.216.34
example.com.    86400   IN      RRSIG   A 13 2 86400 ...

6.7 ビューとスプリットホライズン DNS

スプリットホライズン DNS は、クエリの送信元に応じて異なる応答を返す機能である。

# /etc/bind/named.conf
acl "internal-networks" {
    192.168.0.0/16;
    10.0.0.0/8;
    127.0.0.1;
};

acl "external-networks" {
    !192.168.0.0/16;
    !10.0.0.0/8;
    !127.0.0.1;
    any;
};

// 内部ビュー
view "internal" {
    match-clients { internal-networks; };
    recursion yes;

    zone "example.com" {
        type master;
        file "/etc/bind/zones/internal/db.example.com";
    };

    zone "1.168.192.in-addr.arpa" {
        type master;
        file "/etc/bind/zones/internal/db.192.168.1";
    };
};

// 外部ビュー
view "external" {
    match-clients { external-networks; };
    recursion no;

    zone "example.com" {
        type master;
        file "/etc/bind/zones/external/db.example.com";
    };
};

内部ゾーンファイル

# /etc/bind/zones/internal/db.example.com
$TTL    86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2026041001 3600 900 604800 86400 )

@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com.

ns1     IN      A       192.168.1.1
ns2     IN      A       192.168.1.2

; 内部 IP アドレスを返す
www     IN      A       192.168.1.10
app     IN      A       192.168.1.20
api     IN      A       192.168.1.20
db01    IN      A       192.168.1.40

; 内部専用のレコード
gitlab  IN      A       192.168.1.60
jenkins IN      A       192.168.1.61
grafana IN      A       192.168.1.62

外部ゾーンファイル

# /etc/bind/zones/external/db.example.com
$TTL    86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2026041001 3600 900 604800 86400 )

@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com.

ns1     IN      A       203.0.113.1
ns2     IN      A       203.0.113.2

; 外部(パブリック)IP アドレスを返す
www     IN      A       203.0.113.10
@       IN      MX      10 mail.example.com.
mail    IN      A       203.0.113.30

; TXT レコード(SPF、DKIM)
@       IN      TXT     "v=spf1 ip4:203.0.113.30 -all"

; 内部サーバー(db, gitlab 等)は外部に公開しない

7. dnsmasq

7.1 概要と用途

dnsmasq は、軽量な DNS フォワーダー・キャッシュサーバーおよび DHCP サーバーである。小規模ネットワークやローカル開発環境に最適である。

# インストール
$ sudo apt install dnsmasq     # Debian/Ubuntu
$ sudo yum install dnsmasq     # RHEL/CentOS

# サービスの管理
$ sudo systemctl enable dnsmasq
$ sudo systemctl start dnsmasq

7.2 DNS キャッシング設定

# /etc/dnsmasq.conf

# リスニングアドレス
listen-address=127.0.0.1,192.168.1.1

# ポート
port=53

# 上流 DNS サーバー
server=8.8.8.8
server=8.8.4.4
server=1.1.1.1

# 特定のドメインに対する上流サーバー
server=/internal.example.com/192.168.1.1
server=/1.168.192.in-addr.arpa/192.168.1.1

# キャッシュサイズ
cache-size=1000

# ネガティブキャッシュの有効化
no-negcache

# /etc/hosts の読み込み
no-hosts                    # /etc/hosts を無視
addn-hosts=/etc/dnsmasq.hosts  # 追加のホストファイル

# ドメイン
domain=example.com
local=/example.com/

# DNSSEC の検証
dnssec
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D

# ロギング
log-queries
log-facility=/var/log/dnsmasq.log

# 特定のレコードの追加
address=/myapp.local/192.168.1.100
address=/double-click.net/0.0.0.0  # 広告ブロック

7.3 DHCP 連携

# /etc/dnsmasq.conf (DHCP設定)

# DHCP レンジ
dhcp-range=192.168.1.100,192.168.1.200,24h

# 固定 IP の割り当て
dhcp-host=00:11:22:33:44:55,web01,192.168.1.10
dhcp-host=00:11:22:33:44:66,db01,192.168.1.40

# デフォルトゲートウェイ
dhcp-option=3,192.168.1.1

# DNS サーバー
dhcp-option=6,192.168.1.1

# ドメイン名
dhcp-option=15,example.com

# DHCP で割り当てたホスト名を DNS に自動登録
dhcp-authoritative

8. DNS キャッシング

8.1 キャッシュの仕組み

DNS キャッシュは、TTL(Time To Live)に基づいて名前解決の結果を一時的に保存する機能である。

8.2 キャッシュの管理

# systemd-resolved のキャッシュ
$ resolvectl statistics       # キャッシュ統計
$ resolvectl flush-caches     # キャッシュフラッシュ

# BIND9 のキャッシュ
$ sudo rndc flush             # 全キャッシュフラッシュ
$ sudo rndc flush example.com # 特定ドメインのキャッシュフラッシュ
$ sudo rndc dumpdb -cache     # キャッシュのダンプ
$ sudo rndc stats             # 統計情報

# dnsmasq のキャッシュ
$ sudo kill -SIGUSR1 $(pidof dnsmasq)  # キャッシュ統計をログ出力
$ sudo systemctl restart dnsmasq        # キャッシュフラッシュ

# nscd のキャッシュ
$ sudo nscd -i hosts          # ホストキャッシュの無効化

8.3 TTL の考慮事項

シナリオ推奨 TTL理由
静的な Web サイト86400 (24h)変更頻度が低い
動的な Web アプリ300-3600 (5m-1h)適度な更新頻度
DNS 移行直前60-300 (1-5m)速やかな切り替えのため
ロードバランサー30-60 (30s-1m)迅速なフェイルオーバー
CDN300 (5m)CDN プロバイダの推奨

9. DNS セキュリティ

9.1 一般的な脅威

脅威説明対策
DNS スプーフィング偽の DNS 応答を注入DNSSEC、DNS over TLS/HTTPS
DNS アンプ攻撃オープンリゾルバを悪用したDDoS再帰問い合わせの制限、RRL
DNS トンネリングDNS を使ったデータ流出DNS トラフィックの監視
ゾーン転送の悪用不正なゾーン転送allow-transfer の制限、TSIG
キャッシュポイズニングキャッシュに偽データを注入DNSSEC、ソースポートランダム化

9.2 セキュリティ設定の実践

# BIND9 のセキュリティ強化設定
options {
    // バージョン情報の非表示
    version "none";

    // 再帰問い合わせの制限
    allow-recursion { internal-networks; };

    // ゾーン転送のデフォルト禁止
    allow-transfer { none; };

    // クエリの制限
    allow-query { internal-networks; };

    // レスポンスレート制限(RRL)
    rate-limit {
        responses-per-second 5;
        window 5;
        slip 2;
        ipv4-prefix-length 24;
        ipv6-prefix-length 56;
    };

    // DNSSEC 検証
    dnssec-validation auto;

    // 最小応答(追加セクションを最小化)
    minimal-responses yes;

    // fetch-glue を無効化
    fetch-glue no;
};

9.3 DNS over HTTPS (DoH) / DNS over TLS (DoT)

# systemd-resolved での DoT 設定
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 8.8.8.8#dns.google
DNSOverTLS=yes

# stubby での DoT 設定(スタンドアロン)
# /etc/stubby/stubby.yml
resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
round_robin_upstreams: 1
upstream_recursive_servers:
  - address_data: 1.1.1.1
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 8.8.8.8
    tls_auth_name: "dns.google"
listen_addresses:
  - 127.0.0.1@53

10. トラブルシューティング

10.1 一般的な問題

名前解決ができない

# 1. ネットワーク接続を確認
$ ping -c 3 8.8.8.8

# 2. resolv.conf を確認
$ cat /etc/resolv.conf

# 3. DNS サーバーへの到達性を確認
$ dig @8.8.8.8 example.com

# 4. nsswitch.conf を確認
$ grep hosts /etc/nsswitch.conf

# 5. systemd-resolved の状態を確認
$ resolvectl status

# 6. ファイアウォールを確認
$ sudo iptables -L -n | grep 53
$ sudo ss -ulnp | grep 53

BIND9 が起動しない

# 設定ファイルの検証
$ sudo named-checkconf

# ゾーンファイルの検証
$ sudo named-checkzone example.com /etc/bind/zones/db.example.com

# ログの確認
$ sudo journalctl -u named -e
$ sudo journalctl -u bind9 -e

# 権限の確認
$ ls -la /etc/bind/zones/
$ ls -la /var/cache/bind/

ゾーン転送が失敗する

# プライマリサーバーでの確認
$ sudo rndc zonestatus example.com

# セカンダリサーバーでの転送テスト
$ dig @192.168.1.1 example.com AXFR

# TSIG キーの確認
$ sudo rndc tsig-list

# ファイアウォールの確認(TCP 53 も必要)
$ sudo iptables -L -n | grep 53

# ログの確認
$ sudo journalctl -u named | grep "transfer"

10.2 デバッグ手法

# dig での詳細デバッグ
$ dig +trace +all example.com

# tcpdump で DNS トラフィックをキャプチャ
$ sudo tcpdump -i any -n port 53
$ sudo tcpdump -i eth0 -n -vv port 53 -w /tmp/dns.pcap

# BIND9 のデバッグレベルを上げる
$ sudo rndc trace 3    # デバッグレベル3
$ sudo rndc notrace    # デバッグを無効化

# querylog の有効化/無効化
$ sudo rndc querylog on
$ sudo rndc querylog off

11. ベストプラクティス

11.1 DNS サーバー運用

  1. 冗長性: 最低2台の権威サーバーを異なるネットワークに配置
  2. 監視: DNS 応答時間、クエリ数、エラー率を監視
  3. ログ管理: クエリログを適切に保存し、定期的にレビュー
  4. 定期的な更新: BIND9 等の DNS ソフトウェアを最新に保つ
  5. DNSSEC: 可能な限り DNSSEC を導入
  6. アクセス制御: 再帰問い合わせとゾーン転送を適切に制限

11.2 ゾーン管理

  1. シリアル番号: YYYYMMDDnn 形式を使用し、必ずインクリメント
  2. TTL の適切な設定: 用途に応じた TTL を設定
  3. バックアップ: ゾーンファイルを定期的にバックアップ
  4. 変更管理: DNS レコードの変更を文書化
  5. テスト: 変更後に named-checkzone と dig で検証

11.3 クライアント設定

  1. 複数の DNS サーバー: 最低2つの DNS サーバーを設定
  2. ローカルキャッシュ: systemd-resolved や dnsmasq でローカルキャッシュを活用
  3. DNS over TLS/HTTPS: 可能な限り暗号化された DNS を使用
  4. resolv.conf の保護: 不要な自動更新を防止

12. 比較表

12.1 DNS サーバーソフトウェア比較

機能BIND9dnsmasqsystemd-resolvedUnbound
権威サーバー対応非対応非対応非対応
再帰リゾルバ対応フォワーダーのみスタブリゾルバ対応
キャッシュ対応対応対応対応
DHCP非対応対応非対応非対応
DNSSEC対応検証のみ検証のみ対応
DoT/DoH限定的非対応DoT 対応DoT/DoH 対応
リソース消費多い少ない中程度中程度
設定の複雑さ高い低い低い中程度
推奨用途エンタープライズ小規模/開発デスクトップセキュリティ重視

12.2 DNS レコードタイプ一覧

レコードRFC用途必須度
A1035IPv4 アドレス必須
AAAA3596IPv6 アドレス推奨
CNAME1035エイリアス一般的
MX1035メールサーバーメール使用時必須
NS1035ネームサーバー必須
PTR1035逆引き推奨
SOA1035ゾーン管理情報必須
TXT1035テキスト情報SPF/DKIM に必要
SRV2782サービスロケーションサービス依存
CAA6844証明書発行認可推奨
DS4034DNSSEC 委任署名者DNSSEC 使用時
DNSKEY4034DNSSEC 公開鍵DNSSEC 使用時
RRSIG4034DNSSEC 署名DNSSEC 使用時
NSEC/NSEC34034/5155DNSSEC 非存在証明DNSSEC 使用時

13. 参考文献

  1. BIND9 公式ドキュメント: https://bind9.readthedocs.io/
  2. dnsmasq マニュアル: https://thekelleys.org.uk/dnsmasq/doc.html
  3. systemd-resolved マニュアル: man systemd-resolved, man resolved.conf
  4. RFC 1035: Domain Names - Implementation and Specification
  5. RFC 4034: Resource Records for the DNS Security Extensions
  6. RFC 7858: DNS over Transport Layer Security (DoT)
  7. RFC 8484: DNS Queries over HTTPS (DoH)
  8. DNSSEC Guide (ISC): https://bind9.readthedocs.io/en/latest/dnssec-guide.html
  9. Arch Linux Wiki - DNS: https://wiki.archlinux.org/title/Domain_name_resolution
  10. CIS Benchmarks: https://www.cisecurity.org/cis-benchmarks

本ドキュメントは 2026年4月時点の情報に基づいて作成されています。