0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DNSとBINDの実践ガイド ― 名前解決の仕組みからAWS Route 53連携まで

0
Posted at

DNSとBINDの実践ガイド ― 名前解決の仕組みからAWS Route 53連携まで

ドメイン名がどのようにIPアドレスへ解決されるのか、BINDのゾーンファイルはどう書くのか、
そしてAWS Route 53やRoute 53 Resolverでハイブリッド環境をどう構成するのか。
dig での確認方法を交えながら、実務で迷いやすいポイントを端的にまとめるリファレンスです。


目次

  1. 名前解決の流れ
  2. リソースレコードの種類
  3. ゾーンファイルの構造(BIND)
  4. named.conf の設定
  5. マスター/スレーブ構成とゾーン転送
  6. dig によるトラブルシュート
  7. AWS Route 53 の基礎
  8. AWSでのハイブリッドDNS構成
  9. ルーティングポリシーとヘルスチェック
  10. TTLと切り替え作業の注意点
  11. トラブルシューティングチェックリスト

1. 名前解決の流れ

DNSは「ドメイン名 → IPアドレス」の変換を、階層化された分散データベースとして実現している。中心となる登場人物は3種類。

役割 説明
スタブリゾルバ OSやアプリに組み込まれた最小限のクライアント。自分では検索せず、フルリゾルバに丸投げする
フルリゾルバ(キャッシュDNS) ISPや 8.8.8.8(Google)、1.1.1.1(Cloudflare)など。スタブから依頼を受け、権威サーバーを再帰的にたどって答えを見つけ、結果をキャッシュする
権威DNSサーバー 特定ゾーンの正式な回答を持つサーバー。BINDやRoute 53が実装するのはこの役割

名前解決の実際の流れ(www.example.com を引く例):

1. スタブ → フルリゾルバ            再帰クエリ(「答えをくれ、なければお前が調べろ」)
2. フルリゾルバ → ルートサーバー     → 「.com は○○に聞け」(反復クエリ)
3. フルリゾルバ → .com TLDサーバー   → 「example.com は○○に聞け」
4. フルリゾルバ → example.com権威    → www.example.com の A レコードが返る
5. フルリゾルバ → スタブ             結果を返し、自分もTTLの間キャッシュ

スタブ⇔フルリゾルバ間は再帰クエリ、フルリゾルバ⇔各階層間は反復クエリという非対称性を押さえておくと dig +trace(後述)の出力が読みやすくなる。


2. リソースレコードの種類

BIND・Route 53 問わず共通で使うレコードタイプ。

タイプ 用途 備考
A ホスト名 → IPv4アドレス 最も基本的なレコード
AAAA ホスト名 → IPv6アドレス
CNAME ホスト名 → 別のホスト名(別名) 同じ名前に他のレコード(MX、TXTなど)を共存させられない。ゾーンの頂点(apex/root、例: example.com 自体)には設定不可
MX メール配送先のホスト名 + 優先度 優先度は数値が小さいほど優先
TXT 任意の文字列 SPF(送信元IP検証)、DKIM公開鍵、DMARCポリシー、ドメイン所有権確認(ACM証明書発行時など)に使う
NS ゾーンの権威サーバーを委任 親ゾーンと子ゾーンの両方に置く(glue record)
SOA ゾーンの管理情報 プライマリサーバー、管理者メール、シリアル番号、再試行間隔などをまとめて保持
PTR IPアドレス → ホスト名(逆引き) in-addr.arpa(IPv4)/ ip6.arpa(IPv6)ゾーンに置く
SRV サービスの場所(ホスト+ポート) _service._proto.name の形式
CAA 証明書発行を許可するCA(認証局)を制限 未設定のCAからは証明書発行がRFC上拒否される

CNAMEの制約とAliasレコード

CNAMEは「他に何のレコードも持たない名前」にしか使えず、ゾーンの頂点(apex、example.com 自体)には置けない(apexはSOA/NSと共存できないため)。この制約を回避するAWS独自拡張が Aliasレコード(7. AWS Route 53 の基礎 で詳述)で、apexに設定でき、DNSクエリ課金も発生しない。


3. ゾーンファイルの構造(BIND)

example.com ゾーンの最小構成例。

$TTL 3600
@   IN  SOA  ns1.example.com. hostmaster.example.com. (
                2026081901 ; serial(更新のたびに増やす)
                3600       ; refresh(セカンダリの再確認間隔)
                600        ; retry(refresh失敗時の再試行間隔)
                1209600    ; expire(この期間更新がなければゾーン失効)
                300 )      ; minimum(negative cache TTL, RFC2308)

    IN  NS   ns1.example.com.
    IN  NS   ns2.example.com.
    IN  MX   10 mail.example.com.

@       IN  A      203.0.113.10
www     IN  A      203.0.113.10
mail    IN  A      203.0.113.20
ns1     IN  A      203.0.113.1
ns2     IN  A      203.0.113.2
blog    IN  CNAME  www.example.com.
        IN  TXT    "v=spf1 ip4:203.0.113.20 -all"

注意点:

  • $TTL はゾーン全体のデフォルトTTL(秒)。レコード個別に上書きも可能
  • @ はゾーン名自身(この例では example.com.)を表す
  • 末尾のドット . はFQDN(完全修飾ドメイン名)の印。忘れると $ORIGIN(ゾーン名)が自動補完される典型ミス(例: www.example.com とドットなしで書くと www.example.com.example.com. になる)
  • シリアル番号は更新のたびに必ず増やす。スレーブはこの値の増減でゾーンの更新有無を判断する。日付ベース(YYYYMMDDnn)が事実上の標準

4. named.conf の設定

BINDの動作全体を制御するのが named.conf(多くのディストリビューションでは /etc/named.conf や /etc/bind/named.conf)。

options {
    directory "/var/named";
    listen-on port 53 { any; };
    allow-query { any; };
    recursion no;              // 権威サーバー専用なら再帰は無効にする
    version "not disclosed";   // バージョン詐称でfingerprinting対策
};

// マスター(プライマリ)ゾーン
zone "example.com" {
    type master;
    file "example.com.zone";
    allow-transfer { 203.0.113.2; };  // スレーブのIPのみゾーン転送を許可
    also-notify { 203.0.113.2; };     // 更新時にスレーブへ即座に通知
};

// 逆引きゾーン
zone "113.0.203.in-addr.arpa" {
    type master;
    file "203.0.113.zone";
};

権威専用サーバーでは recursion no; を必ず設定する。 再帰を許可したまま外部公開すると、DNS増幅攻撃(オープンリゾルバとして踏み台にされる)の踏み台にされるリスクがある。キャッシュ用途と権威サーバー用途は役割を分離するのが基本方針。


5. マスター/スレーブ構成とゾーン転送

可用性のため、権威サーバーは通常マスター1台+スレーブ複数台の構成を取る(レジストラへの登録上も、異なるネットワークにあるNSを最低2つ登録するのが推奨)。

// スレーブ側の named.conf
zone "example.com" {
    type slave;
    file "slaves/example.com.zone";
    masters { 203.0.113.1; };
};
  • AXFR: ゾーン全体を転送する方式(初回同期時)
  • IXFR: シリアル番号の差分だけを転送する方式(更新の都度、帯域を節約)
  • NOTIFY: マスターがゾーン更新をスレーブへ即座に知らせる仕組み。これがないとスレーブは refresh 間隔(SOAレコードで指定した秒数)まで気づかない
  • ゾーン転送は平文だと詐称・盗聴のリスクがあるため、TSIG(Transaction SIGnature) で送信元認証と改ざん検知を行うのが実務上の必須事項
key "transfer-key" {
    algorithm hmac-sha256;
    secret "base64でエンコードされた共有鍵";
};

zone "example.com" {
    type master;
    file "example.com.zone";
    allow-transfer { key transfer-key; };
};

6. dig によるトラブルシュート

dig はDNSデバッグの主力ツール。よく使うパターンをまとめる。

# 基本のAレコード問い合わせ(OSのデフォルトリゾルバを使用)
$ dig www.example.com A

# 特定のDNSサーバーに直接聞く(キャッシュを介さず権威サーバーの回答を確認)
$ dig @ns1.example.com www.example.com A

# 結果だけ簡潔に見る
$ dig +short www.example.com A
203.0.113.10

# ルートから権威サーバーまでの委任チェーンを実際にたどる(委任ミスの調査に必須)
$ dig +trace example.com

# SOAレコードでシリアル番号を確認(マスター/スレーブの同期状況チェック)
$ dig @ns1.example.com example.com SOA +short
$ dig @ns2.example.com example.com SOA +short
# → 2つのシリアル番号が一致していればゾーン転送は正常

# 逆引き(PTRレコード)の確認
$ dig -x 203.0.113.10

# メール配送先の確認
$ dig example.com MX +short

# 再帰なしで問い合わせ、そのサーバーが権威応答を持っているか確認
$ dig +norecurse @ns1.example.com example.com A

dig の出力で確認すべきセクション:

  • ;; ANSWER SECTION — 実際の回答レコード
  • ;; AUTHORITY SECTION — 権威サーバー(NSレコード)の情報。ANSWERが空でここだけ埋まっている場合は「委任はされているがレコードがない」ケース
  • flags: 行の aa(Authoritative Answer)— 権威サーバーからの直接回答かどうか。aa がなければキャッシュ経由の非権威応答

7. AWS Route 53 の基礎

Route 53はAWSのマネージドDNSサービスで、権威DNSサーバー機能(BINDのマスター相当)をフルマネージドで提供する。

ホストゾーン

  • パブリックホストゾーン: インターネットから引けるゾーン。作成すると自動で4つのNSサーバー名が割り当てられる → これをドメインレジストラ側のNS委任設定に登録する
  • プライベートホストゾーン: 指定したVPC内からのみ解決できるゾーン。VPC側で enableDnsSupport と enableDnsHostnames を有効にしておく必要がある
# ホストゾーンの作成
$ aws route53 create-hosted-zone \
    --name example.com \
    --caller-reference "$(date +%s)"

# 割り当てられたNSレコードの確認(これをレジストラに登録する)
$ aws route53 list-resource-record-sets \
    --hosted-zone-id Z1234567890ABC \
    --query "ResourceRecordSets[?Type=='NS']"

Aliasレコード

Route 53独自の拡張で、ELB・CloudFront・S3静的サイトホスティング・API Gateway・別のRoute 53レコードなど、AWSのリソースを指す特別なポインタ。挙動はCNAMEに似るが次の点が異なる。

CNAME Alias
ゾーン頂点(apex)に設定 不可 可能
クエリ課金 発生する 発生しない
ターゲットのIP変化への追従 TTL経過後に反映 常に自動で最新IPを返す
指定できる対象 任意のホスト名 AWSリソースのみ

apexドメイン(example.com そのもの)をELBやCloudFrontに向けたい、という要望はCNAMEの制約で実現できないため、AWS環境ではAliasレコードを使うのが基本になる。

# change-batch用JSON例(apexをALBへAliasで向ける)
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "example.com",
      "Type": "A",
      "AliasTarget": {
        "HostedZoneId": "Z35SXDOTRQ7X7K",
        "DNSName": "my-alb-1234567890.ap-northeast-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
$ aws route53 change-resource-record-sets \
    --hosted-zone-id Z1234567890ABC \
    --change-batch file://change-batch.json

8. AWSでのハイブリッドDNS構成

オンプレミス(またはEC2上に構築した既存のBIND)とAWS環境を併存させる場合、Route 53 Resolver が橋渡し役になる。

構成要素

  • インバウンドエンドポイント: オンプレミス側から、AWSのプライベートホストゾーンを名前解決できるようにする入口。VPC内にENI(Elastic Network Interface)としてIPが払い出される
  • アウトバウンドエンドポイント: VPC内のEC2などから、オンプレミスのBINDが権威を持つゾーンへ問い合わせを転送する出口
  • Resolverルール(FORWARD): 「このドメインへのクエリは、あのIPへ転送する」という条件付きフォワーディングルール。BINDの forward zone 設定に相当する
[オンプレミスBIND] <--VPN/DirectConnect--> [アウトバウンドエンドポイント] --(Resolverルール)--> internal.example.com のクエリのみ転送
[EC2/Lambda等]     <--VPN/DirectConnect--> [インバウンドエンドポイント]  <-- オンプレミス側から Route 53 プライベートホストゾーンを解決
# Resolverルールの作成例(internal.example.com をオンプレBINDへ転送)
$ aws route53resolver create-resolver-rule \
    --name "to-onprem-bind" \
    --rule-type FORWARD \
    --domain-name "internal.example.com" \
    --target-ips Ip=10.0.100.53,Port=53 \
    --resolver-endpoint-id rslvr-out-xxxxxxxx

これはBIND側の named.conf に書く条件付きフォワーダーと発想は同じ。

// BIND側: AWSのプライベートホストゾーンへ転送する場合
zone "aws.internal.example.com" {
    type forward;
    forward only;
    forwarders { 10.0.0.2; };  // Route 53 Resolver のインバウンドエンドポイントIP
};

VPCのDNS設定

VPC作成時、デフォルトでは AmazonProvidedDNS(VPC CIDRの +2 アドレス)が使われる。オンプレミスのBINDや独自DNSサーバーを使わせたい場合は、DHCPオプションセットでVPC内インスタンスへ配布するDNSサーバーを差し替える。

$ aws ec2 create-dhcp-options \
    --dhcp-configurations "Key=domain-name-servers,Values=10.0.100.53,10.0.100.54"
$ aws ec2 associate-dhcp-options \
    --dhcp-options-id dopt-xxxxxxxx --vpc-id vpc-xxxxxxxx

注意: DHCPオプションセットの変更は新規に起動したインスタンス、または既存インスタンスでDHCPリース更新(dhclient の再実行や再起動)が発生したタイミングでしか反映されない。

スプリットホライズン(内部/外部で違う答えを返す)

同じドメイン名でも社内からは内部IP、社外からはパブリックIPを返したい、というケースはプライベートホストゾーンとパブリックホストゾーンに同名のゾーンをそれぞれ作ることで実現できる(VPCに紐付いたプライベートホストゾーンが優先して解決される)。BINDでは view ディレクティブで同様のことができる。

// BINDでのスプリットホライズン
acl "internal" { 10.0.0.0/8; };

view "internal" {
    match-clients { internal; };
    zone "example.com" { type master; file "internal/example.com.zone"; };
};

view "external" {
    match-clients { any; };
    zone "example.com" { type master; file "external/example.com.zone"; };
};

9. ルーティングポリシーとヘルスチェック

BINDの静的なゾーンファイルにはない、Route 53ならではの機能。

ポリシー 用途
シンプル 1レコード名に1つの値(複数値を返す場合はランダムに1つ選ばれるDNSラウンドロビン)
加重(Weighted) 同一名に複数レコードを登録し、重み比率でトラフィックを配分。カナリアリリースやBlue/Greenの段階移行に使う
レイテンシベース クライアントに最もレイテンシが低いリージョンへ振り分ける
フェイルオーバー ヘルスチェックと組み合わせ、プライマリ障害時に自動でセカンダリへ切り替える(アクティブ/スタンバイ構成)
位置情報(Geolocation) クライアントの地理的位置(国・大陸単位)で応答を出し分ける
複数値回答(Multivalue Answer) ヘルスチェック付きの簡易ロードバランシング。最大8個までのランダムな健全レコードを返す

ヘルスチェックはHTTP/HTTPS/TCPでエンドポイントの死活監視を行い、フェイルオーバーや EvaluateTargetHealth オプションと組み合わせて異常なターゲットをDNS応答から自動的に除外する。オンプレミスのBINDだけではこの動的な出し分けは実現できず、外部の監視ツールと連携する自作の仕組みが必要になる点がRoute 53との大きな違い。


10. TTLと切り替え作業の注意点

  • 移行やカットオーバーの前に、対象レコードのTTLを事前に短く(例: 300秒程度)下げておく。切り替え後にすぐ元に戻せるよう、変更後もしばらく短いままにしておくのが安全
  • TTLはあくまでキャッシュした側の目安であり、必ず正確に守られるとは限らない。ブラウザやOS、企業プロキシが独自にキャッシュを長く保持することもあるため、「TTLを下げたから即座に切り替わる」と過信しない
  • CNAMEチェーンを挟むと、チェーン上の各ホップで別々にキャッシュされるため、末端のレコードだけTTLを下げても途中のCNAME側のTTLが長ければ古い経路のまま残ることがある
  • Route 53のAliasレコードはRoute 53内部で毎回ターゲットの最新状態を引くため、AレコードのようにTTLを気にする必要がない(TTL自体が設定項目に出てこない)。これはBINDの通常レコードとの明確な違いであり、ELB/CloudFrontのIP変更に強い理由でもある

11. トラブルシューティングチェックリスト

「変更したのに反映されない」「メールが届かない」系の障害調査で最初に確認すべき手順。

  1. 委任が正しいか: dig +trace ドメイン名 で、レジストラに登録したNSと実際にゾーンを持っているNSが一致しているか確認する
  2. 複数の権威サーバーの一貫性: dig @各NS ドメイン名 SOA +short でシリアル番号を比較し、マスター/スレーブ(またはRoute 53のNS4台)で回答がずれていないか確認する
  3. 外部から見えているか: 自分のPCのローカルキャッシュではなく、dig @8.8.8.8 や dig @1.1.1.1 など外部の複数の公開リゾルバに直接問い合わせて実際の伝播状況を見る
  4. メールが届かない場合: MXレコード(dig ドメイン名 MX)、SPFのTXTレコード、逆引きPTRレコード(多くの受信サーバーは送信元IPの逆引きができないメールを迷惑メール扱いする)を確認する
  5. 証明書発行が失敗する場合: CAAレコード(dig ドメイン名 CAA)が発行元CAをブロックしていないか確認する(ACMなら amazon.com、amazontrust.com などの許可が必要)
  6. VPC内から名前解決できない場合: enableDnsSupport / enableDnsHostnames の有効化、DHCPオプションセットの割り当て、セキュリティグループでUDP/TCP 53番ポートが許可されているかを確認する
  7. BINDのログ: named はデフォルトで syslog に出力する。rndc querylog でクエリログを有効化すると、どんな問い合わせが来ているかリアルタイムで追える
  8. 設定ファイルの構文チェック: 変更を反映する前に必ず named-checkconf / named-checkzone ゾーン名 ゾーンファイル で構文エラーを検出してから rndc reload する

参考資料

  • RFC 1034 / RFC 1035 — DNSの基本仕様
  • RFC 2308 — DNSにおけるネガティブキャッシュ(SOAのminimumフィールド)
  • BIND 9 Administrator Reference Manual(ISC公式ドキュメント)
  • AWS公式ドキュメント: Amazon Route 53 Developer Guide、Route 53 Resolver
  • man named.conf / man dig / man named-checkzone(各OS付属マニュアル)

元記事(Bitz Notebook): DNSとBINDの実践ガイド ― 名前解決の仕組みからAWS Route 53連携まで

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?