BIND9によるDNSスプリットホライズンの設定:LANとインターネットでIPを使い分ける「分身」テクニック

Network tutorial - IT technology blog
Network tutorial - IT technology blog

現実的な課題:なぜ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のロジックさえマスターすれば、データフローを制御し、ユーザー体験を最適化できます。皆さんの構築が成功することを願っています!

Share: