这原本是Leo 兄的来信指教﹐因为实在太有参考价值了﹐于是公诸同好。

所有对dynamic dns 技术有兴趣的朋友﹐都应该看的。

--

----- Original Message -----

From: LeoLiou

To: netman

Sent: Monday, February 11, 2002 6:59 AM

Subject: about dns

Hi, kenny:

       我是Leo,好久不见啰~~ 在此跟您拜个年,新年快乐喔~ :-)

       放假回来翻了您的DNS 教学,嗯,太棒啰,补充了许多许多的新东西,

       昨天我回了一篇有关"动态IP 架站" 的讨论文章,里面是提到动态更新

       DNS 的,自行架设Dynamic DNS 与client 端的script 更新,不过我在

       DNS 中,不是使用allow-update,而是使用update-policy,update-policy

       比起allow-update 更有弹性,比方,可以限定什么key 可以做什么事。

       举例来说,我的named.conf 长得像是这样..

       // --------------- 宣告Key 的部分---------------

       // P.S: 底下的 leo, mail key 是不正确的

       key "leo" {

               algorithm hmac-md5;

               secret "hB/XM2eFTyxA5r/scautOZ==";

       };

       key "mail" {

               algorithm hmac-md5;

               secret "ht5TkKKFP5l8u9ZTcDbStw==";

       };

       // --------------- 宣告ZONE 的部分---------------

       zone "sayya.org" {

           type master;

           file "named.sayya";

           notify yes;

           also-notify {

                 140.128.78.250;

                 211.23.99.147;

                 61.218.164.83;

           };

           allow-transfer {

                 140.128.78.250;

                 211.23.99.147;

                 61.218.164.83;

           };

           allow-query {

                 0.0.0.0/0;

           };

           update-policy {

                 // 使用mail HOST 的key,仅有权限变更mail.sayya.org 与rsync.sayya.org 的A record

                   grant mail name mail.sayya.org. A;

                 grant mail name rsync.sayya.org. A;

                 // 使用leo USER 的key,可以完全控制sayya.org,比方新增一subdomain,指定DNS

                 // 或是增加一 A, CNAME,TXT.. record 等等

                 grant leo subdomain sayya.org. ANY;

           };

       };

       大概就是这个样子,另外附上之前回覆的那篇..

--------

作者: leoliou (暖冬) 看板: Linux

标题: Re: 动态 IP 架站 @_@

时间: Sun Feb 10 14:49:30 2002

※ 引述《skchen.bbs@bbs.nsysu.edu.tw (ㄚ凯)》之铭言:

> 小弟在之前就有提过相关的问题

> 大家用的动态IP对映的系统都不一样

> 我是用 DynDNS 的系统

> 也不知道为什么跑了一段时间就会产生一大堆僵尸程序@_@

> 更神的是找不到程序在哪里(还是我比较逊脚????) @_@

> 这好像是DynDNS 给的ddClient 程式有BUG 吧

> 我利用了perl 和bash shell script 写了一些小程式

> 可以用来侦测PPP 介面是否存在

> 如果不存在就连线 ^o^

 嗯,看到这封信感觉是真的有讨论的气氛,超喜欢这种感觉~ :)

 记得以前还用ADSL 拨接制的时候,是使用rp-pppoe 连线的,会在断线后自动

 重新连线,这个可以解决断线的问题。

 再来是重点了,Dynamic IP 怎么办呢?我目前的环境是双向 Cable,IP 也是由

 DHCP Server 取得 Dynamic IP 的。当然,如果您去申请dns2go 类似的程式,

 是可以解决您动态IP 的问题,但是缺点是您不可以使用自己的网址,一定要是

 某一些已经律定好的网址,或者是有可能要求您把Primary DNS 指向该公司代

 管,另外,就是您可能还要在Server 中执行该公司所提供的动态IP 更新程式..

 无论如何,就会让我联想到系统安全性的问题.. 对我来说,非常不方便。

 于是,我找了一台固定IP 的Server,架上了Bind,这台就是我自己网域的

 Primary DNS,也就是Dynamic DNS,如何设定,晚点提到。而这台 DNS 的

 固定IP 假设为61.22.33.20,Domain 为example.com,注册名称为

 ns.example.com :)

 再来,比方我的mail server 架在家里,就是我现在双向Cable 的线路上,

 这台mail server 的Domain name 假设为: mail.example.com

 我只要定时向我的Primary DNS 更新我的mail server 的IP 就可以啰,

 Primary DNS 怎么判断允许哪些电脑做更新呢?有两种方式,第一种方式为

 在Primary DNS 中设定allow-update,设定某些固定IP 可以向Primary

 DNS 更新资料,但是比较没有弹性。另外一种就是待会要介绍的

 update-policy。

 allow-update 可以允许特定的IP 或key 来做动态更新,预设是不允许任何

               IP 更新。

 update-policy 在BIND 9 才提供,不用指定某特定的IP 才可以做动态更新,

               而是要凭 key 来决定更新权限。 Primary DNS 有这个 key,

               mail server 往后只要凭这个key 就可以动态更新IP 了。

               当然了,mail server 与Primary DNS 的key 得一样才行。

 key 就是用dnssec-keygen 工具产生出来的签证,现在于Primary DNS

 上,产生 key,并发给 mail server。

 首先,感生 mail server 用的 key:

   # dnssec-keygen -a HMAC-MD5 -b 128 -n HOST mail

   Kmail.+157+44587

   #

 查看一下,结果会产生了档名类似Kmail.+157+44587.key 与

 Kmail.+157+44587.private 两个档案。

 其中Kmail.+157+44587.key 档案内容长得类似这样:

   # less Kmail.+157+44587.key

   mail. IN KEY 512 3 157 BJ7y6dzxchy3u0B4hRLksQ==

   #

 档案内容BJ7y6dzxchy3u0B4hRLksQ== 这是编码过的,就是所谓的key。

 首先,您得将这两个key 复制到mail server 上面,建议使用sftp 传输,

 避免被窃。

 现在,开始 Primary DNS 上的设定了。

 ----- /etc/named.conf ----------

 key "mail" {

         algorithm hmac-md5;

         secret "BJ7y6dzxchy3u0B4hRLksQ==";

 };

 zone "example.com" {

         type master;

         file "named.example";

         update-policy {

           grant mail name mail.example.com. A;

           // mail key 仅允许更新mail.example.com 的A record.

         };

 };

 ----- End of File ----------

 Primary DNS 上面的设定完成后,请记得重跑bind。

 接下来,在mail server 方面,要如何更新呢?

 当然,最重要的,首先要取得mail server 的key。刚刚已经有提到,

 在Primary DNS 产生后,用ftp 传输到mail server 来。

 使用nsupdate 工具向Primary DNS 做更新动作:

   $ nsupdate -k Kmail.+157+44587.key

   > server ns.example.com // 指定Primary DNS

   > update delete mail.example.com A // 先删除旧资料

   > update add mail.example.com 0 A 210.64.233.10 // 再新增资料

   > send // 送出到Primary DNS

   $ // Ctrl-C or Ctrl-D 离开

 验证一下,是不是更新成功:

   $ host mail.example.com ns.example.com

   mail.example.com has address 210.64.233.10

   $

 恭喜您更新成功了,如果您没有成功,请到Primary DNS 上看messages 纪录档。

 注意, key 档案的权限,应该只有owner 可以读写,应为-rw------- 请注意。

 执行nsupdate 的user,应为key 的owner,否则会发生Permission denied

 的情形。

 如果您要让您的电脑自动更新,这里有我自己写的script 供参考:

 建立一个 tmp.txt 内容如下:

 ----- tmp.txt ----------

 server ns.example.com

 update delete mail.example.com A

 update add mail.example.com 0 A SERVER_NEW_IP

 send

 ----- End of File ----------

 建立更新的 script: newip.sh

 ----- newip.sh ----------

 #!/bin/sh

 #

 # Written by LeoLiou.

 #

 # config the update dir.

 exe_path=/root/nsupdate

 new_IP=`/sbin/ifconfig eth0 | grep 'inet addr' | cut -d: -f 2 \

 | cut -d' ' -f1`

 /bin/cat $exe_path/tmp.txt | sed s/SERVER_NEW_IP/$new_IP/g \

 > $exe_path/update.txt

 # update now IP to name server.

 /usr/bin/nsupdate -k $exe_path/Kmail.+157+44587.key -v $exe_path/update.txt

 ----- End of File ----------

 请将您的key, tmp.txt, newip.sh 放置于同一目录,并给予newip.sh 执行权限。

 请执行一次newip.sh 确定没有问题之后,再利用crontab 执行newip.sh 即可。

 0 * * * * /root/nsupdate/newip.sh

 这样就完成整个动态 IP 更新机制了。

 关于update-policy,请看BIND 9 Administrator Reference Manual:

 http://www.isc.org/products/BIND/bind9.html

 dnssec-keygen 与nsupdate 的使用方法,相信man page 写得已经很清楚了。

 :-)

--

 Leo Liou (leo@i18n.linux.org.tw)

 Join i18n project: http://i18n.linux.org.tw/

* ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~

---------------

补充 by netman on October 30, 2002﹕

---------------

我略为修改了Leo兄的script ﹐并置于/root/nsupdate 目录下面。

我这里将界面改为ppp0 ﹐同时也减少不必要的传送动作。

(注﹕原本的tmp.txt 我也改名为nsupdate.scr 了﹐请留意。)

内容如下﹕

#!/bin/bash

#

# Written by LeoLiou.

# Modified by netman on 2002/09/26

#

# set variables

if echo $0 | grep '^/' ; then

   w_dir=${0%/*}

else

   w_dir=$PWD/${0%/*}

fi

KEY_FILE=$w_dir/Kmail.+157+44587.key

UPDATE_SCR=$w_dir/nsupdate.scr

UPDATE_DATA=$w_dir/nsupdate.data

HOST_NAME=mail.example.com

NS_SERVER=ns.example.com

IF="ppp0"

# ensure key files

for file in $KEY_FILE ${KEY_FILE%key}private

do

   if [ ! -r $file ]; then

       echo "$(basename $0): ERROR: $file is not readable."

       exit 1

   fi

done

# prepare initial script

test -f $UPDATE_SCR || {

   cat >| $UPDATE_SCR <<-ENDSCR

           server NS_SERVER

           update delete HOST_NAME A

           update add HOST_NAME 0 A NEW_IP

           send

ENDSCR # <----- 请将ENDSCR 前面的空白换成tab !

   test "$?" = "0" || {

       echo "$(basename $0): ERROR: could not create $UPDATE_SCR."

       exit 2

   }

}

# ensure the server is connectable

host $NS_SERVER $NS_SERVER | grep "$NS_SERVER" &>/dev/null || {

   echo "$(basename $0): ERROR: could not contact nameserver $NS_SERVER."

   exit 3

}

# get current ip

NEW_IP=$(ifconfig | grep "$IF " -A 1 \

   | awk '/inet/ {print $2}' | sed -e 's/.*://')

# do a test then update

host $HOST_NAME $NS_SERVER | grep "$NEW_IP" &>/dev/null || {

   /bin/cat $UPDATE_SCR | sed s/NEW_IP/$NEW_IP/ \

       | sed s/NS_SERVER/$NS_SERVER/ \

       | sed s/HOST_NAME/$HOST_NAME/ \

       >| $UPDATE_DATA

   /usr/bin/nsupdate -k $KEY_FILE -v $UPDATE_DATA || rm -rf $UPDATE_DATA

}

#-- end of script --#

上面的 script 可于这里下载:

http://study-area.ks.edu.tw/linux/src/newip.sh.tgz

目前这个script 只能在linux client 上执行﹐

但我想﹐透过简单的cgi 功能﹐那么任何的windows client 也能轻松的进行更新﹐

不过﹐这部份就需要其他朋友帮忙设定了。

假如您已经成功完成了﹐欢迎通知leo 或netman ﹐以便和大家作更进一步的分享。

谢谢﹗