🌗

BINDのview機能で実現する、内向き/外向きDNSの構築 (Split-Horizon DNS)

に公開

はじめに

社内にWebサーバーやファイルサーバーを立てた際、「社内のPCからはプライベートIPアドレスで、社外からはグローバルIPアドレスで同じドメイン名にアクセスさせたい」という要件に直面することがあります。

これを解決するスマートな方法が、DNSサーバーが 問い合わせ元に応じて応答内容を変える「スプリットDNS(Split-Horizon DNS)」 です。

この記事では、自身のWikiメモを元に、DNSサーバーの定番ソフトであるBINDのview機能を使って、このスプリットDNSを構築する手順を解説します。

スプリットDNSとは?

スプリットDNSは、DNSサーバーが問い合わせ元のIPアドレスを見て、相手が「内部(LAN)のクライアント」なのか「外部(WAN)のクライアント」なのかを判断し、それぞれに用意した異なるゾーン情報を応答する仕組みです。

  • 内部クライアントからの問い合わせ: server.example.com192.168.1.10 (プライベートIP)
  • 外部クライアントからの問い合わせ: server.example.com203.0.113.10 (グローバルIP)

これにより、内部ユーザーはLAN内で高速に通信でき、外部ユーザーはインターネット経由で正しくアクセスできる、という効率的な名前解決が実現できます。

Step 1: named.confでのview設定

この仕組みの核となるのが、BINDの設定ファイルnamed.conf内のviewディレクティブです。ここで「内部向け」と「外部向け」の設定を完全に分離します。

/var/named/chroot/etc/named.conf
// ... optionsディレクティブなどは省略 ...

#-- 内部向けビュー
view "internal" {
  # このビューにマッチするクライアントを指定 (localnetsは内部ネットワーク)
  match-clients { localnets; };
  match-destinations { localnets; };
  recursion yes; // 内部向けには再帰問い合わせを許可

  # 内部向けのゾーン定義ファイルをインクルード
  include "/etc/named/named.example.com.zone.internal";
};

#-- 外部向けビュー
view "external" {
  # 上記以外、全てのクライアントにマッチ
  match-clients { any; };
  match-destinations { any; };
  recursion no; // 外部向けには再帰問い合わせを許可しない (セキュリティ対策)

  # 外部向けのゾーン定義ファイルをインクルード
  include "/etc/named/named.example.com.zone.external";
};

match-clientsが問い合わせ元のIPアドレスを判定する重要な設定です。localnetsoptionsで定義されたローカルネットワークを指します。

Step 2: ゾーン定義ファイルの作成

次に、viewごとに読み込ませるゾーン定義ファイルを作成します。

内部向けゾーン定義 (named.example.com.zone.internal):

zone "example.com" {
  type master;
  file "example.com.db.internal"; // 内部向けゾーンファイル
};

外部向けゾーン定義 (named.example.com.zone.external):

zone "example.com" {
  type master;
  file "example.com.db.external"; // 外部向けゾーンファイル
};

Step 3: ゾーンファイルの作成

最後に、それぞれの定義ファイルから読み込まれるゾーンファイル(レコード本体)を作成します。ここで応答するIPアドレスが変わります。

内部向けゾーンファイル (example.com.db.internal):

; ... SOAレコードなどは省略 ...
@       IN  A     192.168.1.10    ; example.com のIPアドレス
server  IN  A     192.168.1.10    ; server.example.com
www     IN  A     192.168.1.11    ; [www.example.com](https://www.example.com)

サーバーのIPアドレスとして、プライベートIPアドレスを記述します。

外部向けゾーンファイル (example.com.db.external):

; ... SOAレコードなどは省略 ...
@       IN  A     203.0.113.10    ; example.com のIPアドレス
server  IN  A     203.0.113.10    ; server.example.com
www     IN  A     203.0.113.11    ; [www.example.com](https://www.example.com)

こちらには、グローバルIPアドレスを記述します。

おわりに

BINDのview機能を使うことで、単一のDNSサーバーで内部向けと外部向けの名前解決をスマートに両立させることができます。少し設定は複雑になりますが、ネットワークのセキュリティと効率性を高める上で非常に強力なテクニックです。
特に、社内システムと公開サーバーが混在するような環境では、このスプリットDNSの考え方が大いに役立つはずです。


この記事で紹介した内容以外にも、技術情報をブログで発信しています。
MEANTECH
https://meantech.fontfontfont.com/

Discussion