动态DNS搭建
文章目录
动态DNS理念
如果我们本身是以拨接制的 ADSL 连上 Internet 时,我们的 IP 通常是 ISP 随机提供的,因此每次上网的 IP 都不固定,所以, 我们没有办法以常规的 DNS 设定来给予这种连上 Internet 的方法一个适当的主机名,这时就可以使用动态 DNS(Dynamic DNS, DDNS) 服务。
如果我们想要利用这种没有固定 IP 的联机方法架设网站时,就得要有特殊的管道了, 其中之一的方法就是利用 Internet 上面已经提供的免费动态 IP 对应主机名的服务!
提供这样的服务利用的原理基本上, DNS 主机提供 Internet 相关的 zone 的主机名与 IP 的对应数据,,DDNS 主机 就提供一个机制,让客户端可以通过这个机制来修改他们在 DDNS 主机上面的 zone file 内的资料。
我们的 BIND 9 就有提供类似的机制!那就是利用 update-policy 这个选项,配合认证用的 key 来进行数据文件的更新。
简单的说:
1) 我们的 DDNS 主机先提供 Client 一把 Key (就是认证用的数据, 你可以将他想成是账号与密码的概念)。
2) Client 端利用这把 Key ,并配合 BIND 9 的 nsupdate 指令, 就可以连上 DDNS 主机,并且修改主机上面的 Zone file 内的对应表。
DDNS Server 端的设定:
假设我有一个朋友,他使用的 Linux 主机的 IP 是会随时变动的,但是他想要架设 Web 网站, 所以他向我申请了一个域名,那就是 web.getlinux.cn ,此时我必需要给他一把密钥, 并且设定我的 named.conf 让 getlinux.cn 这个 zone 能够接受来自客户端的数据更新!首先来建立这把密钥!
dnssec-keygen -a [算法] -b [密码长度] -n [类型] 名称
选项与参数:
-a :后面接的 [type] 为加密方式,主要有 RSAMD5, RSA, DSA, DH 与 HMAC-MD5 等。建议你可以使用常见的 HMAC-MD5 来加密密码;
-b :密码长度;
-n :客户端能够更新的类型,主要有底下两种,建议给 HOST 即可:
ZONE:客户端可以更新任何标志及整个 ZONE;
HOST:客户端仅可以针对他的主机名来更新。
1 2 3 4 5 6 7 8 9 10 |
[root@zhangsir ~]#cd /etc/named/ [root@zhangsir /etc/named]#dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST web #时间可能有点长,不是死了,等会就好。 Kweb.+165+06689 [root@zhangsir /etc/named]#ls -l total 8 # 后缀 .key 是公钥,后缀 .private 则是私钥文件! -rw-r--r--. 1 root root 112 12月 22 00:12 Kweb.+165+06689.key -rw-------. 1 root root 232 12月 22 00:12 Kweb.+165+06689.private [root@zhangsir /etc/named]#cat Kweb.+010+43850.key #查看一下公钥文件。 web. IN KEY 512 3 165 4VderqtyJncVLGUrLpW38TL0aI/u+y7ZH/Q5/2jpSoUC8/X0x1003Ys8 c5Osa4HB/xCOY+51MwVQtHw4xnl2fA== #主要就是记下此行最左边这个公钥的密码长度信息,等会要用。 |
接下来需要:将公钥的密码复制到 /etc/named.conf 当中,将私钥传给 web.getlinux.cn 那部主机上!好了,那就开始来修改 named.conf 内的相关设定吧!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
[root@zhangsir ~]#vim /etc/named.conf options { directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { any; }; recursion yes; allow-transfer { none; }; // 不许别人进行 zone 转移 }; key "web" { //添加密匙信息 algorithm hmac-sha512; secret "4VderqtyJncVLGUrLpW38TL0aI/u+y7ZH/Q5/2jpSoUC8/X0x1003Ys8 c5Osa4HB/xCOY+51MwVQtHw4xnl2fA=="; }; zone "." IN { type hint; file "named.ca"; }; zone "getlinux.cn." IN { // 这个 zone 的名称 type master; // 是什么类型 file "named.getlinux.cn"; // 文件放在哪里 update-policy { //添加这一段 grant web name web.getlinux.cn. A; }; }; zone "16.172.in-addr.arpa" IN { type master; file "named.172.16"; }; |
注意到上面的 grant web name web.getlinux.cn. A; 那一行, grant 后面接的就是 key 的名称,也就是说,我这把 web 的 key 在这个 zone (getlinux.cn) 里面可以修改主机名 web.getlinux.cn 的 A 的标志,即修改主机的 IP 对应!语法也就是: grant [key_name] name [hostname] 标签 也就是说,我的一把 key 其实可以给予多种权限!就看你如何规范了。
设定好之后,由于未来客户端传来的信息是由我们主机的 named 所写入, 写入的目录在 /var/named/ 当中,所以你必需要修改一下权限! 然后重新启动 DNS,然后观察一下 /var/log/messages 里面有没有错误即可! 如此一来,DDNS 主机端就设定妥当了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@zhangsir ~]#ll -d /var/named/ drwxr-x---. 5 root named 4096 12月 21 22:58 /var/named/ [root@zhangsir ~]#ll /var/named/named.getlinux.cn -rw-r--r--. 1 root root 1072 12月 21 22:58 /var/named/named.getlinux.cn [root@zhangsir ~]#chmod g+w /var/named/ [root@zhangsir ~]#chown named /var/named/named.getlinux.cn [root@zhangsir ~]#ll /var/named/named.getlinux.cn -rw-r--r--. 1 named root 1072 12月 21 22:58 /var/named/named.getlinux.cn [root@zhangsir ~]#systemctl restart named [root@zhangsir ~]#tail -n10 /var/log/messages|egrep named Dec 22 17:23:10 zhangsir named[3303]: command channel listening on ::1#953 Dec 22 17:23:10 zhangsir named[3303]: managed-keys-zone: loaded serial 0 Dec 22 17:23:10 zhangsir named[3303]: zone getlinux.cn/IN: loaded serial 2016112807 Dec 22 17:23:10 zhangsir named[3303]: zone 16.172.in-addr.arpa/IN: loaded serial 2016112806 Dec 22 17:23:10 zhangsir named[3303]: all zones loaded Dec 22 17:23:10 zhangsir named[3303]: running Dec 22 17:23:10 zhangsir named[3303]: zone 16.172.in-addr.arpa/IN: sending notifies (serial 2016112806) |
Client 端的更新:
接下来则是 DDNS Client 端的更新了。首先,你必须要由 Server 端取得刚刚建立的那两个密钥文件, 请将刚刚建立的 Kweb.+010+43850.key 及 Kweb.+010+43850.private 传送到客户端, 即那部 web.getlinux.cn 主机上头, 假设你已经将这两个文件放置到 /usr/local/ddns 里面去,然后测试看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@web ~]# cd /usr/local/ddns/ [root@web ddns]# scp root@172.16.252.33:/etc/named/Kweb.+165+06689.{key,private} ./ root@172.16.252.33's password: Kweb.+165+06689.key 100% 112 0.1KB/s 00:00 root@172.16.252.33's password: Kweb.+165+06689.private [root@web ddns]# ls -l 总用量 8 -rw-r--r--. 1 root root 112 12月 22 00:23 Kweb.+165+06689.key -rw-------. 1 root root 232 12月 22 00:23 Kweb.+165+06689.private [root@web ddns]# nsupdate -k Kweb.+165+06689.key > server 172.16.252.33 > update delete web.getlinux.cn > update add web.getlinux.cn 600 A 172.16.250.56 > send > #成功后在此按下 [ctrl]+D 退出即可 |
请注意到『 update add web.getlinux.cn 600 A 172.16.250.56 』这行, 他的意义说的是,新增一笔数据, ttl 是 600 ,给予 A 的标签,对应到 172.16.250.56 的意思~ 至于 nsupdate -k 后面加的则是我们在 Server 端产生的那个 key 文件!
然后你就会发现到在 DNS 服务器端的 /var/named/ 里面多出一个临时文件,那就是 named.getlinux.cn.jnl 当然,/var/named/named.getlinux.cn 就会随着客户端的要求而更新数据!
1 2 3 |
[root@zhangsir ~]#ls /var/named/ data named.172.16 named.empty named.localhost slaves dynamic named.ca named.getlinux.cn named.getlinux.cn.jnl named.loopback |
我们在主 DNS 查看一下有没有变化。
1 2 3 4 |
[root@zhangsir ~]#tail -n2 /var/log/messages|egrep named Dec 22 17:23:33 zhangsir named[3303]: client 172.16.250.56#45287/key web: updating zone 'getlinux.cn/IN': delete all rrsets from name 'web.getlinux.cn' Dec 22 17:23:33 zhangsir named[3303]: client 172.16.250.56#45287/key web: updating zone 'getlinux.cn/IN': adding an RR at 'web.getlinux.cn' A #从日志就能看出来已经成功了 |
由于手动更新好像挺麻烦的,我们就让 Client 自动更新吧!利用底下这个 script 即可!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[root@web ~]# vim /usr/local/ddns/ddns_update.sh #!/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin export PATH # 0. keyin your parameters basedir="/usr/local/ddns" # 基本工作目录 keyfile="$basedir"/"Kweb..+165+06689.key" # 将文件名填进去吧! ttl=600 # 你可以指定 ttl 的时间! outif="eth0" # 对外的联机接口! hostname="web.getlinux.cn" # 你向 ISP 取得的那个主机名! servername="172.16.252.33" # 就是你的 ISP ! # Get your new IP newip=`ifconfig "$outif" | grep 'inet addr' | \ awk '{print $2}' | sed -e "s/addr\://"` checkip=`echo $newip | grep "^[0-9]"` if [ "$checkip" == "" ]; then echo "$0: The interface can't connect internet...." exit 1 fi # create the temporal file tmpfile=$basedir/tmp.txt cd $basedir echo "server $servername" > $tmpfile echo "update delete $hostname A " >> $tmpfile echo "update add $hostname $ttl A $newip" >> $tmpfile echo "send" >> $tmpfile # send your IP to server nsupdate -k $keyfile -v $tmpfile |
当然,你可以让这个脚本更加完善。