現実的な課題:なぜDNSスプリットホライズンが必要なのか?
オフィス内にいながら、社内のメールサーバーやERPへのアクセスが非常に遅く感じたことはありませんか?システム運用を開始して6ヶ月経った頃、私は初歩的なミスに気づきました。サーバーはLAN内(IP 192.168.1.50)にあるのに、DNSがパブリックIP(1.2.3.4)のみを指していたのです。
この状態では、PCからのパケットは一度ファイアウォールまで行き、Hairpin NAT処理を経てからサーバーに戻ってきます。このプロセスにより、レイテンシ(latency)が1ms未満から20〜30msまで増加します。さらに、ファイアウォールが高負荷になると、社内ネットワークが正常でも接続が不安定になってしまいます。
その解決策がDNSスプリットホライズン(またはSplit-Brain)です。簡単に言うと、サーバーが「誰が問い合わせてきたか」によって答えを変える仕組みです。LAN内のマシンであれば内部IPを、インターネットからのアクセスであればパブリックIPを返します。これらはすべて自動的に行われます。
コア概念:BIND9におけるACLとView
Linuxでこれを実装するには、次の2つの機能を使いこなす必要があります:
- ACL (Access Control List): IPグループを分類するために使用します。例えば、「VIP」グループはLANネットワーク、それ以外は「Guest」といった具合です。
- View: これが処理の要です。クライアントが属するACLに応じて、BIND9が異なるゾーンファイルを表示できるようにします。
ヒント:ACLに設定する複雑なIP範囲(サブネット)を計算する場合、私はよく IP Subnet Calculator を使用します。これにより、CIDRの入力ミスによる意図しないアクセス制限を防ぐことができます。
DNSスプリットホライズンの設定実習
今回はUbuntu Serverで実施します。CentOSやDebianを使用している場合もロジックは同じですが、設定ファイルのパスに注意してください。
ステップ 1: BIND9のインストール
sudo apt update && sudo apt install bind9 bind9utils bind9-doc -y
ステップ 2: 社内ネットワーク用のACL定義
named.conf.options ファイルを開き、信頼できるIP範囲を宣言します:
sudo nano /etc/bind/named.conf.options
ファイルの先頭に以下のコードを追加します:
acl "trusted" {
127.0.0.0/8;
192.168.1.0/24; # あなたのオフィスのIP範囲
};
ステップ 3: Viewの設定(最も重要なステップ)
通常、ゾーンは直接宣言しますが、スプリットホライズンではすべてのゾーンを view ブロックで囲む必要があります。
重要な注意点: viewを使用する場合、BIND9では100%すべてのゾーン(localhost などのデフォルトゾーンを含む)がいずれかのview内に存在しなければなりません。漏れがあると、サービスがエラーを吐いて起動しません。
/etc/bind/named.conf.local ファイルを編集します:
# LAN内ユーザー向けのビュー
view "internal" {
match-clients { "trusted"; };
recursion yes;
include "/etc/bind/named.conf.default-zones";
zone "itfromzero.com" {
type master;
file "/etc/bind/db.itfromzero.com.internal";
};
};
# インターネット外部ユーザー向けのビュー
view "external" {
match-clients { any; };
recursion no; # DNSアンプ攻撃に悪用されるのを防ぐために無効化
zone "itfromzero.com" {
type master;
file "/etc/bind/db.itfromzero.com.external";
};
};
ステップ 4: 各View用のデータ作成
同一ドメインに対して、2つの別々のデータベースファイルが必要です。
1. 内部ゾーンファイル(LAN IP 192.168.1.50を指す):
sudo cp /etc/bind/db.local /etc/bind/db.itfromzero.com.internal
sudo nano /etc/bind/db.itfromzero.com.internal
ERPのAレコードが内部IPを指すように設定します。
2. 外部ゾーンファイル(パブリックIP 1.2.3.4を指す):
sudo cp /etc/bind/db.local /etc/bind/db.itfromzero.com.external
sudo nano /etc/bind/db.itfromzero.com.external
ここでは、外部からファイアウォール経由でアクセスできるように、AレコードをパブリックIPに設定します。
ステップ 5: 検証と運用
すぐにサービスを再起動せず、まずは構文チェックを行ってシステムの停止を防ぎましょう:
sudo named-checkconf
sudo systemctl restart bind9
動作確認:本当に効果があるか?
dig コマンドを使用して結果を確認します。LAN内のPCから次のように入力します:
dig erp.itfromzero.com
結果が 192.168.1.50 であれば成功です。外部からのテストをするには、スマホのテザリングなどでPCを接続し、再度同じコマンドを実行してみてください。その際、結果はパブリックIP 1.2.3.4 になるはずです。
運用上の「痛い失敗」から学んだ経験
スプリットホライズンを導入すると、アプリケーションのレスポンス速度は驚くほど速くなります。しかし、落とし穴もあります。新しいサブドメインを追加する際、両方のゾーンファイルを更新しなければなりません。
以前、内部ファイルにだけ取引先用のレコードを追加し、外部ファイルを忘れてしまったことがありました。オフィスでのテストは完璧でしたが、お客様から「サイトにアクセスできない」とクレームの電話がかかってきてしまいました。設定変更時は必ず両方のビューをクロスチェックするようにしましょう。
最後に、外部ビューで recursion yes を決して許可しないでください。さもないと、あなたのサーバーが他者へのDDoS攻撃(DNSアンプ攻撃)の踏み台として悪用されることになります。
まとめ
DNSスプリットホライズンは、オンプレミスサーバーを持つ企業ネットワークにとって非常に実用的な技術です。ACLとViewのロジックさえマスターすれば、データフローを制御し、ユーザー体験を最適化できます。皆さんの構築が成功することを願っています!

