■目的 LAN 上のサーバーで動作しているインターネット向け DynamicDNS サーバーを、同一サ ーバーの nsupdate で更新するため。 あるドメイン (例:example.com) を 1つの named で view を使って LAN と WAN で使 用していると、同一サーバー上で nsupdate を実行したときに WAN 側を更新せず LAN 側を更新してしまうため、このような環境下では nsupdate が行えない。 ---[ named.conf ]----------------------------------- acl internal { 192.168.1.0/24; 127.0.0.1; }; view "inside" { match-clients { internal; }; zone "internal.example.com" { type master; file "internal_example_com.zone"; }; }; view "outside" { match-clients { any; }; zone "external.example.com" { type master; file "external_example_com.zone"; allow-update { 192.168.1.0/24; 127.0.0.1; } } }; ---[ ifconfig ]------------------------------------- fxp0: flags=8943 mtu 1500 options=8 inet 192.168.1.10 netmask 0xffffff00 broadcast 192.168.1.255 ether 00:a0:c9:69:f7:87 media: Ethernet autoselect (100baseTX ) status: active ---------------------------------------------------- この時、ローカルサーバー上で localhost、もしくはローカルサーバー IP アドレス (例:192.168.1.10) に対して nsupdate を行うと、nsupdate を許可されている external.example.com 側ではなく、nsupdate が許可されていない internal 側にリク エストを発行してしまう。 このため、WAN 側 DNS の update を行えない。 # ipfw add 2500 count log ip from me to me 53 % nsupdate > server 127.0.0.1 > update add test1.griffonworks.net. 600 IN A 192.168.1.1 > send Sending update to 127.0.0.1#53 ▼ipfw ログ Apr 26 13:43:54 leviathan ipfw: 2500 Count UDP 127.0.0.1:58434 127.0.0.1:53 out via lo0 Apr 26 13:43:54 leviathan ipfw: 2500 Count UDP 127.0.0.1:58434 127.0.0.1:53 in via lo0 Apr 26 13:43:54 leviathan ipfw: 2500 Count UDP 127.0.0.1:58434 127.0.0.1:53 out via lo0 Apr 26 13:43:54 leviathan ipfw: 2500 Count UDP 127.0.0.1:58434 127.0.0.1:53 in via lo0 > server 192.168.1.10 > update add test1.griffonworks.net. 600 IN A 192.168.1.1 > send Sending update to 192.168.1.10#53 ▼ipfw ログ Apr 26 13:45:09 leviathan ipfw: 2500 Count UDP 192.168.1.10:58434 192.168.1.10:53 out via lo0 Apr 26 13:45:09 leviathan ipfw: 2500 Count UDP 192.168.1.10:58434 192.168.1.10:53 in via lo0 Apr 26 13:45:09 leviathan ipfw: 2500 Count UDP 192.168.1.10:58434 192.168.1.10:53 out via lo0 Apr 26 13:45:09 leviathan ipfw: 2500 Count UDP 192.168.1.10:58434 192.168.1.10:53 in via lo0 ※ローカルサーバーアドレス同士で通信を行うと、Source・Destination とも同じ IP アドレスになることに注意。 このため、bind9 の view が使用できないため、named を分離する必要がある。 しかし同一サーバー上で named (TCP-53、UDP-53:以下 "IP-53" と呼称) を同一ポート で複数同時起動することは出来ないため、どちらか片方の named のポート番号を変更す る必要があるが、そうすると今度は変更した側の named に対してリクエストを発行でき ない。 # DNS リクエストは Dest.:IP-53 に対して行われるため。 そこで、変更した側の named に対しては、natd で Destination に対するポート変換を 行って対応する。 今回は WAN 側 DNS を IP-1053 で起動し、WAN 側から Dest.:IP-53 に対するリクエス トは Dest:IP-53 → IP-1053 に変換して named にフォワードする。 # ipfw add 3000 divert 8668 log ip from not 192.168.1.0/24 to 192.168.1.10 53 # ipfw add 3001 divert 8668 log ip from 192.168.1.10 1053 to not 192.168.1.0/24 # natd -v -port 8668 -alias_address 192.168.1.10 -redirect_port udp 192.168.1.10:1053 53 ---[ パケットの流れ ]--------------------------- ( 行き ) WAN:any → named:53 ↓ ipfw: WAN(not 192.168.1.0/24):any → named:53 ↓ natd (divert 8668) : named:53→named:1053 ↓ named:1053 ↓ ( 帰り ) ↓ ipfw: named:1053 → WAN(not 192.168.1.0/24):any ↓ natd (divert 8668) : named:1053 → named:53 ↓ named:53 → WAN:any ------------------------------------------------ WAN 側から見れば named の IP-53 と通信したように見えるが、サーバー内では IP-53 → IP-1053 に変換しているので 1053番で起動している named に対してリクエストが 行われている。 ただし、この状態ではローカルサーバー (192.168.1.10 や 127.0.0.1) から nsupdate を行った場合は ipfw の divert ルールに適用されないので、LAN 用 DNS にリクエス トを送ってしまう。 ipfw で me to me:53 や 127.0.0.1 to 127.0.0.1:53 などとすれば WAN 側 DNS にリ クエストを送信できるが、他の DNS を利用するアプリケーションまでもが影響を受け る (本来は LAN 用 DNS を引きたいのに WAN 用 DNS を引いてしまう) のでこの方法は 利用できない。 そこで、使用しているインターフェイスに対してエイリアスでもう 1つ IP アドレスを 割り当て、そこに対して nsupdate などのリクエストを送信することにする。 注意点としては、目的外のアプリケーションでエイリアスアドレスに対してリクエスト を送らないこと。 送ってしまうと WAN 側の DNS を引いてしまうが、それでも良いのであればかまわな い。 ■条件 ・bind を 2つ起動する → /usr/local/bind9/ → /usr/local/bind9-ext/ ・bind 用に IP アドレスを用意する (同一インターフェイスに対して alias で良い) → ifconfig fxp0 inet 192.168.1.10 netmask 255.255.255.0 → ifconfig fxp0 alias 192.168.1.233 netmask 255.255.255.0 ・natd を使って NAT する ・ipfw で natd に divert する ■設定 1. named を 2セット用意する ビルドした際、バイナリ内にデフォルトディレクトリが固定指定されるため、双方のバ イナリは prefix を変更してビルドし直した方がよい。 % ./configure --prefix=/usr/local/bind9-ext --with-openssl=/usr/local/ssl --disable-ipv6 % make # make install % make distclean % ./configure --prefix=/usr/local/bind9 --with-openssl=/usr/local/ssl --disable-ipv6 % make # make install bind9-ext は WAN 側用、bind9 は LAN 用とする。 ---[ WAN 用 named.conf ]--- key "rndc_key" { algorithm hmac-md5; secret "キー文字列"; }; controls { inet 127.0.0.1 port 1953 allow { 127.0.0.1; } keys { "rndc_key"; }; }; options { directory "/usr/local/bind9-ext/etc"; pid-file "/var/run/bind9-ext.pid"; auth-nxdomain yes; version ""; lame-ttl 0; recursion no; }; zone "." { type hint; file "named.root"; }; zone "localhost" { type master; file "localhost.zone"; }; zone "0.0.127.in-addr.arpa" { type master; file "0_0_127.rev"; }; zone "example.com" { type master; file "example_com-ext.zone"; allow-update { 127.0.0.1; 192.168.1.0/24; }; }; --------------------------- ---[ LAN 用 named.conf ]--- key "rndc_key" { algorithm hmac-md5; secret "キー文字列"; }; controls { inet 127.0.0.1 allow { 127.0.0.1; } keys { "rndc_key"; }; }; options { directory "/usr/local/bind9/etc"; pid-file "/var/run/bind9.pid"; auth-nxdomain yes; version ""; lame-ttl 0; recursion yes; }; zone "." { type hint; file "named.root"; }; zone "localhost" { type master; file "localhost.zone"; }; zone "0.0.127.in-addr.arpa" { type master; file "0_0_127.rev"; }; zone "example.com" { type master; file "example_com-int.zone"; allow-update { 127.0.0.1; 192.168.1.0/24; }; }; --------------------------- ゾーンファイルは次のようにしておく。 ---[ example_com-ext.zone ]---------------- $TTL 300 $ORIGIN example.com. @ IN SOA ns.example.com. postmaster.example.com. ( 2007042600 10M 5M 1W 15M ) NS ns.example.com. ns A ***.***.***.*** ------------------------------------------- ※***.***.***.*** は WAN 側 IP アドレス。 ---[ example_com-int.zone ]---------------- $TTL 86400 $ORIGIN example.com. @ IN SOA ns.example.com. postmaster.example.com. ( 2007042600 3H 30M 1W 15M ) NS ns.example.com. ns A 192.168.1.10 ------------------------------------------- この状態で # /usr/local/bind9/sbin/named # /usr/local/bind9-ext/sbin/named -p 1053 とし、プロセスが 2つ上がっているかを確認する。 % ps ax | grep named 26084 ?? Ss 0:23.13 /usr/local/bind9/sbin/named 92197 ?? Ss 0:00.77 /usr/local/bind9-ext/sbin/named -p 1053 起動したら各 DNS に対して問い合わせを行う。 % nslookup > set all Default server: 127.0.0.1 Address: 127.0.0.1#53 Set options: novc nodebug nod2 search recurse timeout = 0 retry = 3 port = 53 querytype = A class = IN srchlist = example.com > set port=53 ← ポート番号を 53 に設定 > ns.example.com. Server: 127.0.0.1 Address: 127.0.0.1#53 ← ポート番号 53 Name: ns.example.com Address: 192.168.1.10 ← LAN 側 IP アドレス > set port=1053 ← ポート番号を 1053 に設定 > ns.example.com. Server: 127.0.0.1 Address: 127.0.0.1#1053 ← ポート番号 1053 Name: ns.example.com Address: ***.***.***.*** ← WAN 側 IP アドレス >^D 1053番で問い合わせると ext のゾーン情報が帰ってくるはずなのでそれを確認してお く。 また、各々の named でゾーン転送した際の内容が違うことを確認する。 % dig -p 53 @127.0.0.1 example.com. axfr % dig -p 1053 @127.0.0.1 example.com. axfr 2. natd の設定 NAT するのは WAN 側からのリクエストのみなので、それ用に natd のルールを書く。 ---[ /etc/natd.conf ]--- port 8668 pid_file /var/run/natd.pid alias_address 192.168.1.233 log yes # redirect_port [プロトコル] [転送先IPアドレス:転送先ポート番号] [接続受付ポート番号] redirect_port udp 192.168.1.233:1053 53 redirect_port tcp 192.168.1.233:1053 53 ------------------------ 書いたらデバッグモードで起動しておく。 # natd -v -c /etc/natd.conf natd を ipfw の divert 設定を行う前に起動しておかないと、ipfw で divert された パケットが消滅してしまうので注意!! 3. ipfw の設定 「WAN から IP-53 に対するリクエストを NAT する」というルールを記述する。 記述場所は ipfw のルールに沿って適正な場所に挿入する。 # ipfw add 3000 divert 8668 log ip from { not 192.168.1.0/24 or 192.168.1.233 } to 192.168.1.233 dst-port 53 in # ipfw add 3010 divert 8668 log ip from 192.168.1.233 1053 to { not 192.168.1.0/24 or dst-ip 192.168.1.233 } out 3000番 で行きのルールを設定し、3010番 で帰りのパケットを設定する。 行きと帰りのポート番号は NAT される前と後になるので違うことに注意。 また、in と out をしっかりと指定しておかないとローカルインターフェイス同士の通 信で in が in/out の 2重になってしまう。 3000番 のルールでは行きのパケットを natd に渡す設定を行っている。 not 192.168.1.0/24 は 127.0.0.1 も含まれるが、nslookup で server 127.0.0.1 と すると dest が 127.0.0.1 なので 3000番のルールは適用されない。 また、(ローカルサーバーが 192.168.1.10 の時に) server 192.168.1.10 とすると、 ソースアドレスは 192.168.1.10 になるので、これもまた 3000番のルールは適用され ない。 3010番では帰りのパケットを natd に渡す設定を行っている。 ソースアドレスはポート番号が変換された後 (IP-1053) なので注意すること。 なお、or ルールでローカルインターフェイス同士の通信も NAT している。 log は syslog でロギングするオプションだが、有る程度情報が取れたら撤去してしま ってもかまわない。 4. 実投入 WAN 及び LAN からの問い合わせに問題がなければ、natd の -v オプションを外してデ ーモンで起動する。 ■参考 ※xxx.xxx.xxx.xxx は WAN 側にある端末などの IP アドレス。 ※***.***.***.*** は自前鯖のインターネット側 IP アドレス。 % ipfw list 03000 divert 8668 log ip from { not 192.168.1.0/24 or 192.168.1.233 } to 192.168.1.233 dst-port 53 in 03010 divert 8668 log ip from 192.168.1.233 1053 to { not 192.168.1.0/24 or dst-ip 192.168.1.233 } out WAN% dig @***.***.***.*** ns.example.com. % tail -f /var/log/ipfw.log Apr 25 21:05:15 leviathan ipfw: 3000 Divert 8668 UDP xxx.xxx.xxx.xxx:2145 192.168.1.233:53 in via fxp0 Apr 25 21:05:15 leviathan ipfw: 3001 Divert 8668 UDP 192.168.1.233:1053 xxx.xxx.xxx.xxx:2145 out via fxp0 % natd -v -c /etc/natd.conf In {default}[UDP] [UDP] xxx.xxx.xxx.xxx:2145 -> 192.168.1.233:53 aliased to [UDP] xxx.xxx.xxx.xxx:2145 -> 192.168.1.233:1053 Out {default}[UDP] [UDP] 192.168.1.233:1053 -> xxx.xxx.xxx.xxx:2145 aliased to [UDP] 192.168.1.233:53 -> xxx.xxx.xxx.xxx:2145 1つのIPアドレスで処理 もし2つの gateway があるならば、分離用ルールの前に置くこと。 default gateway: 192.168.1.254 (192.168.1.10 へのパケットの戻り用) 2nd gateway : 192.168.1.253 (192.168.1.12 へのパケットの戻り用) ipfw 設定 00530 divert 8668 log ip from { not 192.168.1.0/24 or 192.168.1.233 } to 192.168.1.233 dst-port 53 in 00540 divert 8668 log ip from 192.168.1.233 1053 to { not 192.168.1.0/24 or dst-ip 192.168.1.233 } out 00800 count log ip from 192.168.1.12 to 211.18.200.178 out 02000 fwd 192.168.1.253 ip from 192.168.1.12 to not 192.168.1.0/24 out natd 設定 port 8668 alias_address 192.168.1.12 redirect_port udp 192.168.1.12:1053 53 redirect_port tcp 192.168.1.12:1053 53 ipfw ログ Apr 26 16:44:21 leviathan ipfw: 550 Divert 8668 UDP 211.18.200.178:2427 192.168.1.12:53 in via fxp0 Apr 26 16:44:21 leviathan ipfw: 560 Divert 8668 UDP 192.168.1.12:1053 211.18.200.178:2427 out via fxp0 Apr 26 16:44:21 leviathan ipfw: 800 Count UDP 192.168.1.12:53 211.18.200.178:2427 out via fxp0 natd ログ In {default}[UDP] [UDP] 211.18.200.178:2433 -> 192.168.1.12:53 aliased to [UDP] 211.18.200.178:2433 -> 192.168.1.12:1053 Out {default}[UDP] [UDP] 192.168.1.12:1053 -> 211.18.200.178:2433 aliased to [UDP] 192.168.1.12:53 -> 211.18.200.178:2433 これでローカルサーバー上でローカルサーバーにある WAN 用 DNS の nsupdate を行う ことが可能となる。