Last Update 2009-03-25

DDNS(Dynamic DNS)

DNSのクライアントから動的にDNSサーバーにホスト名とIPアドレスの登録を行うこと。

DNSサーバーがUnixの場合、Windowsの場合。
DNSクライアントがUnixの場合、Windowsの場合。

組み合わせは色々あるが、ここではDNSサーバーがWindows、DNSクライアントがLinuxのケースを考える。
LinuxはRedHat EL5.2で、winbindによりWindowsのADにドメイン参加している(させられている)。

リンク


ダウンロード


dhclient と samba の net ads dns register -P の組み合わせ

dhclientがDHCPでIPアドレスを取得した後に実行される
dhclient-scriptのexit-hookでDDNS更新することを考える。

結論としてはこれが一番良いと思われる。
準備は/etc/dhclient-exit-hooksを作成しておくだけとなる。

/etc/dhclient-exit-hooksの例
case "$reason" in
  BOUND|RENEW|REBIND|REBOOT)
  # modify /etc/hosts
  sed -i "/`hostname`/d" /etc/hosts
  echo "$new_ip_address `hostname`.test.com `hostname`" >> /etc/hosts
  # DDNS update
  net ads dns register -P 2>&1 | logger
  ;;
esac 
dhclient-exit-hooksの詳細はdhclient-scriptのmanを参照。

これで、DHCPクライアントがIPアドレスを取得した後、
このスクリプトがdhclient-scriptから実行され、
/etc/hostsに自分のIPアドレスとFQDNとホスト名を追加し、DDNS更新が行われる。

わざわざ/etc/hostsに追加している理由はこの下で説明。

net ads dns register の問題点

最初、samba の net ads dns register コマンドでDDNS更新できるはず、
とテストしていたがエラーになりできなかった。
エラーメッセージは以下。
No DNS domain configured for client1. Unable to perform DNS Update. DNS update failed!
ちなみに、下で述べているnsupdate-gssで一度DDNS更新しておくと、net ads dns register はエラーとならず正常終了する。

原因を調べていて以下のWEBに辿りついた。
improve/fix net ads dns register.

要は登録しようとしているホストの情報が、
  • a)DNSから引ける。DNSにエントリがないなら手で登録しておく。
  • b)/etc/hostsにエントリがある。
のどちらかでないとnet ads dns registerは動きません、ということのようである。

(参考情報)WindowsのDDNSについて

Windowsの場合、WindowsのDNSサーバーへのDDNS登録は標準の機能として備わっている。
XPの場合、TCP/IP詳細設定のDNSタブの中に「この接続のアドレスをDNSに登録する(R)」というチェックボックスがあり、DHCPでアドレスを取得した後、ホスト名とIPアドレスがDNSサーバーに登録される。

WindowsのDNSサーバー側でAD認証されたクライアントのみにDNS更新を許可する設定を行っている場合、認証方式としてGSS-TSIGが使われている。

このGSS-TSIGが曲者。
Linuxの標準のDDNS更新がGSS-TSIGに対応していない。
このため、以下で検証したdhclientやnsupdateではWindowsのDNSサーバーにDDNS更新がかけられない。

(参考情報)LinuxのDDNSについて

LinuxではいくつかDDNS更新のための手段がある。
但し、以下の手段はいずれもGSS-TSIGに対応していない。

dhclient

DHCPでIPアドレスを取得した後、dhclient-eth0.confを設定しておくと、eth0のI/Fに設定されたIPアドレスのDNSへの登録も行ってくれる。
これが動くならこの方法が一番便利。

以下、dhclient-eth0.confの設定例
send fqdn.fqdn "client1.test.com.";
send fqdn.encoded on;
send fqdn.server-update off;
fqdn.server-updateが上記のようにoffならクライアントからDNSに直接登録しに行く動きとなる。
これがonだとIPアドレスをリースしてくれたDHCPサーバーにDNSサーバーへのDDNS登録を依頼する動きとなる。

残念ながら、このdhclientはGSS-TSIGに対応していない。
よって、WindowsのDNSサーバーにDDNS更新しに行くところでエラーとなる。

nsupdateコマンド

手動でもよいから他に方法はないか?
nsupdateコマンドにより、DNSサーバーに対してDNS更新を要求することができる。
% nsupdate
 > update add client1.test.com. 3600 IN A 192.168.10.1
 > (空行でのリターンで上記コマンドが実行される) 
 
残念ながら、このnsupdateもGSS-TSIGに対応していない。
よって、DNSサーバーがWindowsだとDDNS更新しに行ってエラーとなる。

(参考情報)LinuxからWindows DNS サーバーへのDDNS登録

nsupdate-gss

GSS-TSIGに対応したnsupdateがこのnsupdate-gssで、Perlスクリプトとなっている。
nsupdate-gssをインストールする時に要求されるPerlのモジュールはできるだけEPELなどから最新のものをインストールしたほうがよい。
今回は以下のようにした。
DAGからは以下の3つ。
  • nsupdate-gss-0.0.20050330-1.el5.rf.noarch.rpm
  • perl-GSSAPI-0.26-1.el5.rf.i386.rpm
  • perl-Net-DNS-0.63-1.el5.rf.i386.rpm
RHEL5.2のCDからは以下の3つ。
  • perl-Digest-HMAC
  • perl-Digest-SHA1
  • perl-Net-IP

上で述べたがここでの環境は、次のようになっている。
  • WindowsのADにRHEL5.2のclient1.test.comがドメイン参加している
  • 認証はkrb5+winbindで行っている(samba-3.0.28)

インストール後、以下の手順でDDNS登録を行う。
nsupdate-gssインストールにより、/usr/share/以下にREADMEができるのでそれを参照。
LinuxにはADに登録されているユーザーでログインしておく。
% vi /etc/krb5.conf で、以下を追加。
[libdefaults]
default_tgs_enctypes =  des3-hmac-sha1 des-cbc-crc des-cbc-md5 
default_tkt_enctypes =  des3-hmac-sha1 des-cbc-crc des-cbc-md5 
 
% kinit でチケットを取得。作成されたチケットが klist -e で見て、
'DES cbc mode with CRC-32'
となっていることを確認する。
READMEによると、他のタイプでも動くと思うがテストしてないよ、とのこと。
但し 'HMAC-MD5' は動かないらしい。(他のタイプについてはHMAC-MD5含めて未確認)
 
% nsupdate-gss client1 test.com 192.168.10.1 36000
nslookup client1.test.com でDNSに登録されていることが確認できる。

これでできるのだが、kinitでチケット作成の時にパスワードを入力せねばならず、バッチでの実行はできない。
DHCPでIPアドレスをリースされたら即DDNS更新という動きをバックグラウンドでやってほしいのだが。
これでは、毎回ログインしてからkinitしてnsupdate-gssしてやらないといけない。
最終更新:2009年03月25日 21:33