- PR -

NAT環境における1台のDNSサーバーでのゾーン機能とキャッシュ機能の運用

1
投稿者投稿内容
waio
会議室デビュー日: 2005/08/03
投稿数: 7
投稿日時: 2005-08-03 16:43
はじめての投稿です。waioと申します。
以後、宣しくおねがいします。

現在、自宅にて以下の環境にてDNSサーバーを運用しています。

FW fedora core3+pppoe(ユーザーモードにてBフレッツに接続。)
DNS centos4 + bind-9.3.1(ソースからインストール)

| ppp0(グローバルIP)
| (eth0 IP unnumberd)
|
FW--eth2 クライアントセグメント
|
|
eth1 サーバーセグメント
(すいません。空白が埋められてしまい図をASCIIでうまく書けませんでした。)


ppp0にはIP aliasでppp0:0、ppp0:1といった具合に
グローバルIPを割り振り、そのうちの1つをiptablesのSNAT、DNAT
にてサーバーセグメントにあるDNSサーバーにNATをかけています。

このDNSサーバーは外部に対するゾーンと内部で使用するゾーンを持っており、
また内部からのキャッシュDNSとしても動作しています。
(allow recursionにて内部ネットワークからのみ許可)

しかし現在、外部ゾーンにて不具合があります。

外部のDNSサーバーからこのDNSサーバーの外部ゾーンに対する
問い合わせは問題なく行くのですが、
クライアントセグメントにいるクライアントからこのDNSに問い合わせ
を行なうと、このDNSサーバーが管理する外部ゾーンを引くことができません。

(クライアントのキャッシュサーバー指定をプロバイダ指定のDNSキャッシュサーバー
にすると問題無く引けます。)

tcpdumpにて追ったDNS問い合わせの流れとしましては

1.クライアントが問い合わせ
2.キャッシュでもあるDNSサーバーはppp0に割りふられているDNS用グローバルIPに対し問い合わせ
3.DNSサーバーは自分のeth0のIPに対しても問い合わせ
4.No such name という結果がクライアントに返される。

(キャプチャしたパケットにて気になった点がありました。2のパケットのうち何個かのUDP Checksum
がincorrectになっていました。ethernetとpppのMTU絡みの問題でしょうか?以前pppoeをカーネル
モードで使用して特定のWEBサイト(Windows UPdate)がクライアントセグメントから見えなくなりました。)

現在手詰り状態です。
皆様の御知恵を貸していただけるとありがたいです。

宣しくおねがいします。
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-08-03 17:19
こんにちは。
この話題、最近幾つか出ていた、
「ルータの内部から、ルータに割り振ったサーバ公開(NAT)用グローバルアドレスへ通信できない」
の件に似ているような気がします。この場合、ルータに相当するのは FC3 の FW ですね。

少し設定面で分からない点があるので、質問・コメントだけ。

1. DNSサーバはIPアドレスを幾つ持っていますか?
 プライベートアドレスなので、複数持っても問題ないと思いますが…

2. BINDで、内外のアクセスの区別はどうやってつけていますか?
 アクセス元か、1.によっては、アクセス先でもできますね。

3. クライアントから外部用のドメイン情報を引く時のアクセス先アドレスは?
 FW に設定したグローバルアドレスでしょうか。それともサーバのプライベートアドレスでしょうか。

4. 外部に公開するゾーンを、キャッシュから参照するときは?
 内部用ゾーンと外部用ゾーンの同期を取るのか、自身を参照するのか、自然に任せる(委譲関係を辿る)のか、それとも必要ではないのか。

以上、ご参考まで。

PS. 空白は無視されますが、2バイト文字の空白なら使えますよ。
waio
会議室デビュー日: 2005/08/03
投稿数: 7
投稿日時: 2005-08-03 17:45
angelさん。
ご返答ありがとうございます。

以下質問に対し、回答いたします。

>1. DNSサーバはIPアドレスを幾つ持っていますか?
>プライベートアドレスなので、複数持っても問題ないと思いますが…

eth0に対し1つのみです。

>2. BINDで、内外のアクセスの区別はどうやってつけていますか?
>アクセス元か、1.によっては、アクセス先でもできますね。

以下の様にnamed.confのaclにて行なっています。
acl "localnet" {
192.168.0.0/24;
192.168.1.0/24;
192.168.2.0/24;
192.168.3.0/24;
127.0.0/8;
};


>3. クライアントから外部用のドメイン情報を引く時のアクセス先アドレスは?
> FW に設定したグローバルアドレスでしょうか。それともサーバのプライベートアドレスでしょうか。

1の質問にて回答した、DNSサーバーのeth0に割りふっているプライベートアドレスです。

>4. 外部に公開するゾーンを、キャッシュから参照するときは?
> 内部用ゾーンと外部用ゾーンの同期を取るのか、自身を参照するのか、
>自然に任せる(委譲関係を辿る)の>>か、それとも必要ではないのか。

第1参照サーバーはDNSサーバーのプライベートアドレス
第2参照サーバーはプロバイダー指定のDNSキャッシュサーバー
です。

現状、第1参照サーバーは自分で管理している外部ゾーン(仮にexample.net)について返答してくれないので
第1参照サーバーのタイムアウトを待ち、第2参照サーバーから回答がきます。
尚、回答が来ないのはこのDNSサーバーが管理している外部ゾーン(example.net)のみで
その他(たとえばwww.google.co.jp)などは問題無く引けます。


>PS. 空白は無視されますが、2バイト文字の空白なら使えますよ。

ご教授ありがとうございます。試してみます。
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-08-04 09:46
おはようございます。

おそらく、問題点としては…

1. DNSサーバ上で、BINDのキャッシュ機能(内部向け)が、自身の管理する公開ゾーン(外部向け)を参照するときに、自分(プライベートアドレス)→自分(グローバルアドレス)の通信を必要とする。

2. FWの設定の問題上、内部ネットワーク→公開用グローバルアドレス(DNAT対象)ができない。

という2つの条件が重なっているのでしょう。
考えられる解決方法は2通りでしょうか。

(a) BINDの設定で、内部向けACLの中でも外部向けACLと同じように、自ドメインを type master として登録する。

(b) FWの設定を変更し、2.を解消する。すなわち、内部→公開アドレス の通信に対しては、PREROUTING チェインの DNAT だけでなく、POSTROUTING チェインのSNAT も適用されるように調節する。

ちなみに、2. はどこが問題になるかというと…
・行きパケット
  発信時:  P(DNS) → G(PUB) … (1)
  FWで変換後:P(DNS) → P(DNS) ※DNAT適用
  着信時:  P(DNS) → P(DNS)
・帰りパケット
  発信時:  P(DNS) → P(DNS)
  FWは…通らない
  着信時:  P(DNS) → P(DNS) … (2)

というように、行き帰りの (1) と (2) のパケットで、アドレス情報に矛盾が出てしまうわけなのです。
※DNSサーバのプライベートアドレスをP(DNS)、FWで持っている公開用グローバルアドレスをG(PUB)としています。
waio
会議室デビュー日: 2005/08/03
投稿数: 7
投稿日時: 2005-08-04 14:43
angelさん

ご回答ありがとうございます。
ただいま出先ですので、帰宅次第ご教授いただいた方法を
試してみようと思います。

結果が出しだい報告させていただきます。

本当にありがとうございます。助かります。
waio
会議室デビュー日: 2005/08/03
投稿数: 7
投稿日時: 2005-08-05 19:34
angelさん。
2の方法でうまくいきましたのでご報告いたします。

>FWで変換後:P(DNS) → P(DNS) ※DNAT適用
このPREROUTING DNATの処理の後にPOSTROUTING SNATを
行なうようにしたところ、問題無く外部ゾーンを引けるようになりました。

追加した部分のiptables -L -t nat -n -v の結果を張りつけます。
192.168.0.2がDNSサーバーのプライベートアドレスです。

Chain POSTROUTING
target prot opt in out source destination
SNAT all -- * eth1 192.168.0.2 192.168.0.2 to:DNSサーバーのグローバルアドレス

3ヵ月間悩んでいた問題が解決してスッキリしました。

angelさん。本当にありがとうございました。
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-08-06 16:42
こんにちは。問題が解決されたようで何よりです。

以下、蛇足ながら補足です。

1. iptables の DNAT+SNAT について
 元々このアイディアは、VPNを経由した LAN内へのファイルサーバ接続を行う時に考えつきました。クライアントのネットワーク環境に左右されないためには、VPN中継機があたかもプロキシのように振舞う必要があると考えたのです。
この時は、DNAT変換後のパケット情報から SNATすべきかどうかが判断できない場合を恐れ、mark を用いました。( mangle で mark を付けて、nat で mark条件を判断 )
※ VPN専用機ではなかった関係上、他の条件がなるべく絡まないようにしたかったので…

 VPN環境:クライアント・中継機は、それぞれ 10.0.0.X/24, 10.0.0.254 のアドレスを持つ

 LAN環境:サーバ・中継機は、それぞれ 192.168.0.1, 192.168.0.254 のアドレスを持つ

 想定動作:
  クライアント … あたかも、中継機がファイルサーバに見える( 10.0.0.254へ接続 )
  サーバ … あたかも、中継機からの接続に見える

 中継機:LAN側アダプタ eth0, WAN側アダプタ eth1, VPNアダプタ tap0

 中継機 iptables設定
  mangleテーブル PREROUTINGチェイン
   -i tap0 -j MARK --set-mark 0x1

  natテーブル PREROUTINGチェイン
   --mark 0x1 -j DNAT --to-destination 192.168.0.1

  natテーブル POSTROUTINGチェイン
   --mark 0x1 -j SNAT --to-source 192.168.0.254

…まとめたら長くなってしまったので切ります。

[ メッセージ編集済み 編集者: angel 編集日時 2005-08-06 16:48 ]
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-08-06 23:12
こんばんは。補足の続きです。

2. DNSコンテンツサーバとキャッシュの同居
 1台のサーバでコンテンツサーバ(以下サーバ)とキャッシュを同居させるときのパターンを挙げてみたいと思います。DNSソフトの代表として、BIND と、折角なので djbdns についても触れます。
※ なお、私自身、当然のように好みはあるのですが、ここで善悪や優劣を論ずる訳ではありません。

○ポイント1: 機能の相違
・前提
 DNSの通信としては、主に「スタブリゾルバ→キャッシュ」「キャッシュ→サーバ」の2通りの通信があり、同じプロトコルでありながらその性質はガラリと変わります。…まるで別プロトコルであるかのように。なので、分離した方が素直な訳です。
これを踏まえると、次のパターンがあります。

 A. 機能が分離されたソフトを使う ( djbdns )
 B. 機能が同居したソフトの中で機能分担をする ( BIND )

尤も、プロトコルを共有している以上、1つの IPアドレスでは機能分離ができません。そのため、

 a. IPアドレスを複数割り振る
 a'. aと同じだが、ネットワーク条件により FW等での振り分けも行う
 b. ソフトの機能で、条件別に分担を行う

といったヤリクリが必要となります。
a. はどのソフトでも使える汎用的な方法ですし、プライベートネットワークであれば、IPアドレスを複数割り振っても痛手はありません。
a'. a. の特殊な場合で、1つのグローバルアドレスを共有したい時等にあたるでしょう。今回は省略します。
b. はソフトの対応が必要な分トリッキーです。条件を設定すれば、その影に制約が産まれる事もあるので、その点は注意が必要です。

結局組み合わせとしては以下の 3通りになります。

 A-a: IPアドレスを 複数付与して djbdns を普通に運用
 B-a: IPアドレスを 複数付与して BIND を複数インスタンス稼動
 B-b: IPアドレスは 1つのまま、BIND で acl ( 接続元による区別 ) を設定する
    ※ allow-recursion だけでは不完全だった記憶があります

○ポイント2: キャッシュの中での、自ドメインの ECO贔屓
 自機でサーバを動作させるという事は、上位サーバの委譲情報を調べるまでも無く、自分が権限をもっているドメインがあるという事です。
であれば、委譲関係を辿ってキャッシュを行うところをショートカットする事が可能です。この点についてパターンを挙げます。

 α: 上位サーバの委譲情報に従う
 β: 自ドメイン配下は、常に直接自サーバに問い合わせる
 γ: 自ドメイン配下のデータを、サーバ・キャッシュで共有する

αはそのままなので、説明は省略します。贔屓をしない、ごく一般的な選択です。

βは素直なエコヒイキです。djbdns の dnscache はこの機能を標準サポートします。
※ と言いますか、ルートサーバを指定する機能を、下位のドメインにも応用できるだけなのですけどね。
BIND の場合は、ちょっと意味合いが違いますが“type forward”を自ゾーンに指定し、サーバを参照することで成功した記憶があります。
※“type hint”でできれば素直なのでしょうが、未検証です。できたとしても間接指定になるため、使い難いでしょう。
ただし、ポイント1 の b. でも書いた「制約」には注意が必要です。
例えば今回の waio さんの例に適用しようとした場合、自分→自分 の通信を、外部からの接続とみなす必要があるため、acl を工夫するか、今回生じていた NATの問題に向き合う事になります。

γは djbdns ではそもそもできません。BIND のみでの話となります。
基本的にはキャッシュの設定で、自ドメインを“type master”にするだけです。同じゾーンファイルが共有できるかは不明ですが、最低限、コピーやシンボリック/ハードリンクで対応できるでしょう。
自ドメインに権限はあるけど slave の場合はややこしいことになります。少なくともファイルの共有やコピーは役に立ちません。サーバ→キャッシュのゾーン転送が使えるかどうか…、位でしょうか。


…以上、2つのポイントを元に挙げてみました。最初に waio さんに質問を投げたのは、これらのパターンの判断のため、というのがあった訳です。
ちなみに、最後の α〜γ に関しては、BIND での検証は余りやっていない所なので、どなたか突っ込みを頂けると助かります。

[ メッセージ編集済み 編集者: angel 編集日時 2005-08-06 23:17 ]
1

スキルアップ/キャリアアップ(JOB@IT)