|
中华网络安全联盟 作者:jacoo 来源:本站原创 时间:2006-5-11
[概要]
曾经使用过 pdns(powerdns) ,它的前台界面 PowerAdmin 管理界面非常好用,美观大方整洁明晰,一经使用就不再想用别的管理界面。
但如果说使用 DNS,绝大多数人还是更喜欢使用 bind 而不是别的。
于是有人就想(比如我),PowerAdmin 管理界面要是能支持 bind 该多好呀!!!
本想自己摸索摸索,但在 sourceforge 一找,不必了,因为有德国朋友早已经为我们做了一个 PowerAdmin 到 bind 9 的一个嫁接,令 bind9 + PowerAdmin 管理环境的搭建变得非常容易。它名字也很直观,叫作 izidns,估计读音类似于英语中的 easydns 吧。
[原理简述]
通过对 izidns 的研究,发现它的想法非常朴实,思路直接而有效。
简单说,它就是通过前台管理界面向数据库写数据,一个 tcl 脚本程序定时读取数据并倒成 dns 域文件,之后 reload dns 数据文件。
也就是说 bind 并不是直接访问数据库得到数据,而是由 crontab 定时启动一个脚本生成 zone 数据并且启动 reload,reload 后也就更新了 bind 数据。
[适用情况分析]
DNS 在关于 zone 数据的获取方式上一般有几种情况: 1、通过数据库(dbms)获取 2、通过 LDAP 库(对其陌生者,可简单将它看作一种特殊数据库)获取 3、通过文件载入内存
显然 1、2 两种情况都是实时添加实时生效,因为 DNS 将直接通过数据库接口获取数据。而情况 3 则有所不同,更新了zone 数据文件后需要 reload。
在本方案中因为 zone 数据是定时生成的文件,如果数据量很大的情况,比如对于专门提供 DNS 服务的提供商则不适用,因为不断地定时 reload 对主机是负担,同时也一定程度上影响服务质量。但是如果是某个公司自用的 DNS,采用这种方案是完全可行的。
[软件准备] 0、apache2 1、mysql4.1.6 2、php + DB-1.7.6 (pear 数据库通用接口, poweradmin 需要) 3、phpMyAdmin.2.5.6.tar.gz 4、tcl 8.3/8.4 5、mysqltcl ——下载地址为 http://www.xdobry.de/mysqltcl 从网址看是德国造。 6、izidns.tar.gz (已经包含poweradmin1.2.7.tar.gz) 7、bind9.3.2
——0/1/2/7 均是大路货,比较好找 ——3/4/6 均可到 sourceforge 上找到。 ——所有软件包下载下来置于 /downloads/dns 下
[安装环境]
vmware 虚拟机 + redhat 9
[安装过程] _______________________________________________________________________ 第一、apache2 安装 _______________________________________________________________________
cd /download/dns tar xvfz httpd...tar.gz cd httpd... ./configure --prefix=/apache2 --enable-so make make install
## 此时,apache2 已经安装在 /apache2 目录下
_______________________________________________________________________ 第二、mysql4.1.6 _______________________________________________________________________
## 看下有没有缺省的安装 rpm -qa | grep mysql ## 如有干掉它,先 rpm -r ......
useradd -d /home/mysql -s /sbin/nologin mysql
./configure --prefix=/home/mysql make make install
chown -R mysql /home/mysql chgrp -R mysql /home/mysql/var
......设定管理用户与密码等...
_______________________________________________________________________ 第三、php + DB-1.7.6 _______________________________________________________________________
## ——php 解释器将会作为 apache 的模块使用 ./configure --with-apxs2=/apache2/bin/apxs \ --with-mysql=/home/mysql \ --with-pear \ --with-gettext \ --with-zlib \ --enable-session \ --enable-track-vars make make install
## 之后, cp php.ini-dist /usr/local/lib/php.ini
## 然后修理 /apache2/conf 下 httpd.conf #### 找 AddType #### 增加 AddType application/x-httpd-php .php .php3 .phtml
#### 找 DirectoryIndex 行,改为 DirectoryIndex index.php index.html index.html.var
#### 找如下这句话 LoadModule php4_module modules/libphp4.so #### 找到说明 php 作为 apache 的一个模块安装成功
## ——DB 是 php 与各类数据库之间的接口程序,后面 PowerAdmin 在安装配置时需要用到 pear install DB ## 将直接到 php 网站取 package 来安装
## 如果事先下载 DB-1.7.6.tgz pear install DB-1.7.6.tgz ## 将显示 install ok: DB 1.7.6
## 有一点要注意,如果安装 php 时不加 --with-pear 与 --with-zlib 则 pear 不能用
## 这样 php 与 DB 抽象层接口包的安装也就,O了K了
_______________________________________________________________________ 第四、phpMyAdmin _______________________________________________________________________
cd /apache2/htdocs tar xvfz /downloads/dns/phpMyAdmin2.5.6.tar.gz cd phpMyAdmin2.5.6
## 加工 config.inc.php—— #### ——设置访问地址 #### 第39行改为:$cfg['PmaAbsoluteUri'] = 'http://your.IP.or.Name/phpMyAdmin2.5.6'; #### ——设定 mysql 管理者密码 #### 第85行改为:$cfg['Servers'][$i]['password'] = 'your_password'; #### ——更改缺省使用语言及强制使用语言 #### 第374行改为:$cfg['DefaultLang'] = 'zh'; #### 第378行改为:$cfg['Lang'] = 'zh'; #### ——更改字符集 #### 第384行改为:$cfg['DefaultCharset'] = 'gb2312'; #### 存盘退出
## 此时如果 apache 启动了,通过 http://your.IP.or.Name/phpMyAdmin2.5.6 则可透过 Browser 来管理 mysql 数据库 ## 但要注意,由于打开这个页面就可进行数据库管理,十分不安全,因此还必须增加 htaccess 以加强安全......
## 当然,还有个办法就把脚本中的默认认证方式 config 改为 http,这样,在显示页面时 Browser 会弹出一框问数据库 ## 管理者的数据库密码。这里我就不啰嗦了。这要是不设防,出了安全问题可别怪我没说哦。
_______________________________________________________________________ 第五、bind9.3.2 _______________________________________________________________________
rpm -qa | grep bind ## 如有干掉它,例如显示如下: bind-9.2.1-16
rpm -e bind-9.2.1-16 ## 如有依赖则一一解决掉,先
cd /download/dns tar xvfz bind-9.3.2.tar.gz cd bind-9.3.2
## 如果之前干掉了 bind, 则用户 named 也会被干掉,所以现在添加用户 named useradd -d /home/named -s /sbin/nologin named
## 为方便管理,计划将它装在 /home/named 下 ./configure --prefix=/home/named make && make install
## 建立配置文件存放目录 etc 及用于记录进程信息的目录 var mkdir /home/named/etc /home/named/var ## 让 var 对于 named 可写 chown named var
cd /home/named/etc
## 先下载顶级 dns 的域文件 named.root (当然首先假定你的机子能上网哈) ../bin/dig > named.root
## 然后生成 named.conf #### 生成 rndc 控制命令的 key 文件 #### 需注意,这一步要求操作系统配有随机数发生器,所以系统的 random 服务不能停 #### 否则这一步,将会卡住,象没了反应一样 ../sbin/rndc-confgen > rndc.conf #### 从 rndc.conf 文件中提取 named.conf 用的 key 生成 named.conf 文件 tail -10 rndc.conf | head -9 | sed 's/# //g' > named.conf #### 此时,named.conf 内容为:
key "rndc-key" { algorithm hmac-md5; secret "O0SuB34RK+E3r+m5Fbh2eA=="; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; }; ## 增加 localhost.rev 文件,如果有 make-locahost 脚本,可以直接使用生成标准文件 ## 否则直接编辑也可,内容如下(注意将urhost/urdomain替换为实际名称): ## 它实际上是本地反向解析文件,内容如下(注意将urhost/urdomain替换为实际名称):
$TTL 3600
@ IN SOA urhost.urdomain.com. root.urhost.urdomain.com. ( 20060425 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum IN NS urhost.urdomain.com. 1 IN PTR localhost.urdomain.com. ## 这样才能把 127.0.0.1 反向解析为 localhost.urdomain.com
## 现增加一个反向解析文件192.168.0.rev,内容如下(注意将urhost/urdomain替换为实际名称):
$TTL 3600
@ IN SOA urhost.urdomain.com. root.urhost.urdomain.com. ( 20060425 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum IN NS urhost.urdomain.com. 247 IN PTR urhost.urdomain.com. ## 上面 247 是我试验机的 IP 192.168.0.247 ## 这样才能把 192.168.0.247 反解析为 urhost.urdomain.com
## 在先前说的 named.conf 中增加如下内容
zone "." IN { type hint; file "/home/named/etc/named.root"; }; zone "0.0.127.in-addr.arpa" IN { type master; file "/home/named/etc/localhost.rev"; allow-update { none; }; }; zone "0.168.192.in-addr.arpa" IN { type master; file "/home/named/etc/192.168.0.rev"; allow-update { none; }; }; ## 重启 named #### 用 nslookup 进行测试 nslookup > server 127.0.0.1 #### 你会发现 #### 127.0.0.1 会反解出 localhost.urdomain.com #### 192.168.0.247 会反解出 urhost.urdomain.com
## 或许现在会有疑问,为什么没有真正的域数据呀。 ## 是的,真正的域数据将由 tcl 脚本产生,别急,往下看。
_______________________________________________________________________ 第六、tcl 8.3/8.4 _______________________________________________________________________
cd /download/dns tar xvfz tcl8.4.13.src.gz cd tcl8.4.13 cd unix ./configure --disable-threads 或者直接 ./configure make && make test && make install
## 其实 make test 时可能会有些错,但可忽略不计
## 此时,运行 which tclsh8.4 可以看到 /usr/local/bin/tclsh8.4
## 可以整一个软连接: ln -s /usr/local/bin/tclsh8.4 /usr/local/bin/tclsh
## 至此,tcl 脚本解释器算是 O 了 K 了。 #### 注:tcl/tk 曾经大量用于 Web 前台应用程序的开发,但现在好象有些末落了,国内亚信公司曾长期使用它
_______________________________________________________________________ 第七、mysqltcl _______________________________________________________________________
cd /download/dns tar xvfz mysqltcl-3.02.tar.gz cd mysqltcl-3.02 ./configure --with-tcl=/usr/local/lib \ --with-tclinclude=/usr/local/include \ --with-mysql-include=/home/mysql/include/mysql \ --with-mysql-lib=/home/mysql/lib/mysql make make install
## 这样, tcl 的 mysql 接口也 O 了 K 了。
_______________________________________________________________________ 第八、izidns.tar.gz _______________________________________________________________________
cd /download/dns tar xvfz izidns-0.68.tar.gz cd izidns-0.68 ls ## 此时我们可以赫然看到 poweradmin-1.2.7.tar.gz ## 阅读 README 我们可以知道 通过给 poweradmin 打补丁后,令到 poweradmin 可以全面支持 bind
cd /apache2/htdocs tar xvfz /download/dns/izidns-0.68/poweradmin-1.2.7.tar.gz cd poweradmin-1.2.7 patch -p1 < /download/dns/izidns-0.68/izidns.patch cp /download/dns/izidns-0.68/libmysqltcl2.51.so ./inc/ cp /download/dns/izidns-0.68/libmysqltcl2.51.so ./2ndNS/
## 这两个 so 是 debian 下编译出来的,还好,redhat 下还可以使用。如有问题,参照 izidns 的英文文档吧
## 接下来初始化数据表,要不我们给 dns 单独建立一个库 binddb 吧 ## 当然我们也可以通过前面装的 phpMyAdmin 来建库初始化表,以下给出所有脚本
/home/mysql/bin/mysql -u root -pyourpassword create database binddb;
use binddb;
create table domains ( id INT auto_increment, name VARCHAR(255) NOT NULL, master VARCHAR(20) DEFAULT NULL, last_check INT DEFAULT NULL, type VARCHAR(6) NOT NULL, notified_serial INT DEFAULT NULL, account VARCHAR(40) DEFAULT NULL, primary key (id) )type=InnoDB;
CREATE UNIQUE INDEX name_index ON domains(name);
CREATE TABLE records ( id INT auto_increment, domain_id INT DEFAULT NULL, name VARCHAR(255) DEFAULT NULL, type VARCHAR(6) DEFAULT NULL, content VARCHAR(255) DEFAULT NULL, ttl INT DEFAULT NULL, prio INT DEFAULT NULL, change_date INT DEFAULT NULL, primary key(id) )type=InnoDB;
CREATE INDEX rec_name_index ON records(name); CREATE INDEX nametype_index ON records(name,type); CREATE INDEX domain_id ON records(domain_id);
create table supermasters ( ip VARCHAR(25) NOT NULL, nameserver VARCHAR(255) NOT NULL, account VARCHAR(40) DEFAULT NULL ); --——以下我把 binddb 的所有权限都交给 pdns,当然,安全起见最好还是在 mysql 管理前台详细授权 --——其实它只需要对 binddb 有 create/select/update/delete/insert 的权限
GRANT ALL PRIVILEGES ON binddb TO pdns@localhost IDENTIFIED BY 'yourpassword4pdns' WITH GRANT OPTION; ## 之后退出这个 mysql 会话 ## 然后,咱去配置 poweradmin
cd /apache2/htdocs/poweradmin-1.2.7 cd inc
## 先把 config-block.inc.php 改名
mv config-block.inc.php config.inc.php
## 然后对 config.inc.php 进行加工—— ## 第 15 行,添上 dbuser 的实际内容 pdns ## 第 20 行,添上 dbpass 的实际内容 yourpassword4pdns ## 第 24 行,添上 dbdatabase 的实际内容 binddb
## 接下来,修理下 config-bind.tcl 它与 config.inc.php 在一个目录中,执行过前述 patch 命令后就存在了 #### 第 7 行 set bzfd "/etc/bind/" 改为 /home/named/etc 因为我们将 named 的配置文件都放这里了 #### 第 32 行开始,配置连接数据库的参数 set sqlhost "localhost" set sqluser "pdns" set sqlpass "yourpassword4pdns" set sqldb "binddb"
## 修理完毕 ## 在 /home/named/etc 中建立目录 izidns ## 将来 config-bind.tcl 将从数据库中获得数据生成 zone 文件(它们就是真正的域数据)放在这个目录下
mkdir /home/named/etc/izidns
## 然后,在浏览器中,http://your.IP.or.Name/poweradmin-1.2.7/install.php ## 在 Browser 中创建一个 pdns 管理用户并指定其密码 ## 此时,install.php 将会创建 poweradmin 所需要的表并且创建管理者 ## 完了之后别忘了还要干掉 install.php 才能访问管理页面哦!!!
## 接下来我们 crontab -e 加入以下内容:
*/5 * * * * cd /the/path/to/your/htdocs/padmin/inc/ && tclsh ./gbzf.tcl */7 * * * * /home/named/sbin/rdnc reload >/dev/null 2>&1
## 然后我们开始修理 /home/named/etc/named.conf ## 在最后一行加入如下一行:
include "/home/named/etc/named.conf.local"
## 这个文件将由 gbzf.tcl 生成,它的内容将指向 /home/named/etc/izidns 的各个 zone 文件 ## 这些 zone 文件才是真正的域数据。
## 现在我们就可以放心大胆地在 pdns 管理页面中增减数据了。 #### 例如—— #### 现在本机主机名为 mail.dengtao75.com #### 现在我在管理页面中添加了一个 dengtao75.com 的域,又添加了若干记录 #### 几分钟后,在 /home/named/etc/izidns 下面就产生了这个域的数据文件 dengtao75.com.zone #### 文件内容显示如下: [root@mail etc]# cat izidns/dengtao75.com.zone
; Zonefile for dengtao75.com $TTL 3600 @ IN SOA ns.dengtao75.com. postmaster.dengtao75.com. ( 2006042502 ; serial number YYYYMMDDnn 28800 ; Refresh 7200 ; Retry 3600 ; Expire 360 ; Min TTL )
@ IN NS mail.dengtao75.com. @ IN NS [url]www.dengtao75.com.[/url] [url]www.dengtao75.com.[/url] IN A 192.168.0.247 dengtao75.com. IN A 192.168.0.247 mail.dengtao75.com. IN A 192.168.0.247 localhost.dengtao75.com. IN A 127.0.0.1 @ IN MX 10 mail.dengtao75.com. #### 与数据库内数据内容是相对一致的。
#### 并且 named.conf 末句所包含的那个文件 named.conf.local 的内容也发生了变化,它将有一段内 #### 容指向域数据文件如下段内容所示:
zone "dengtao75.com" { type master; file "/home/named/etc/izidns/dengtao75.com.zone"; }; ## 此时,用 nslookup 进行测试,则可以解析出 mail.dengtao75.com, www.dengtao75.com 为 192.168.0.247 ## 好了,不啰嗦了,下一步,随主机启动
_______________________________________________________________________ 第九、随主机启动 _______________________________________________________________________
这里简单说: 1> mysql 的启动, cp /home/mysql/share/mysql/mysql.server /etc/init.d/mysqld chmod +x /etc/init.d/mysqld ln /etc/init.d/mysqld /etc/rc0.d/K15mysqld ln /etc/init.d/mysqld /etc/rc1.d/K15mysqld ln /etc/init.d/mysqld /etc/rc2.d/K15mysqld ln /etc/init.d/mysqld /etc/rc3.d/S85mysqld ln /etc/init.d/mysqld /etc/rc4.d/K15mysqld ln /etc/init.d/mysqld /etc/rc5.d/S85mysqld ln /etc/init.d/mysqld /etc/rc6.d/K15mysqld
2> named 的启动,书写 named 脚本 vi /etc/init.d/named
#!/bin/bash ########################################################################################################## [ -r /home/named/etc/named.conf ] || exit 0
start() { if [ -n "`/sbin/pidof named`" ]; then echo -n $"$prog: already running" return 1 fi echo -n $"Starting $prog: " /home/named/sbin/named -u named } stop() { echo -n $"Stopping $prog: " /home/named/sbin/rndc stop kill -9 `cat /home/named/var/run/named.pid` } restart() { stop start } reload() { /home/named/sbin/rndc reload >/dev/null 2>&1 || /usr/bin/killall -HUP `/sbin/pidof -o %PPID named` } probe() { /usr/sbin/rndc reload >/dev/null 2>&1 || echo start } rhstatus() { /home/named/sbin/rndc status }
case "$1" in start) start ;; stop) stop ;; status) rhstatus ;; restart) restart ;; condrestart) [ -e /home/named/var/run/named.pid ] && restart ;; reload) reload ;; probe) probe ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|probe}" exit 1 esac
exit $? ##########################################################################################################
rm /etc/rc?.d/???named chmod +x /etc/init.d/named ln /etc/init.d/named /etc/rc0.d/K15named ln /etc/init.d/named /etc/rc1.d/K15named ln /etc/init.d/named /etc/rc2.d/K15named ln /etc/init.d/named /etc/rc3.d/S85named ln /etc/init.d/named /etc/rc4.d/K15named ln /etc/init.d/named /etc/rc5.d/S85named ln /etc/init.d/named /etc/rc6.d/K15named
3>、apache 的随主机启动 rm /etc/init.d/httpd /etc/rc?.d/???httpd cp /apache2/bin/apachectl /etc/init.d/httpd ln /etc/init.d/httpd /etc/rc0.d/K15httpd ln /etc/init.d/httpd /etc/rc1.d/K15httpd ln /etc/init.d/httpd /etc/rc2.d/K15httpd ln /etc/init.d/httpd /etc/rc3.d/S85httpd ln /etc/init.d/httpd /etc/rc4.d/K15httpd ln /etc/init.d/httpd /etc/rc5.d/S85httpd ln /etc/init.d/httpd /etc/rc6.d/K15httpd
另外啰嗦一句, 但凡涉及管理的页面最好用 htaccess 文件令其只对有限的 IP 范围(如公司内某几个IP)开放.
[抛砖引瓦] ——有没有进一步的办法,使得前台不变,bind 直接访问数据库而不是定时 reload 呢?那样就更完美了。 ——我突发奇想,是否可以将后台数据表内容做成视图,在 bind 加上 mysql-bind 后,直接访问视图? ——找个时间再研究研究,要是能那样的话,一定非常完美。 ——另外:本文没有对反解析以及双主从 DNS 作进一步的探讨,从 izidns 的 README.bind 中可以看到, 有时间再说。 bigmoyo -- tom.dane%gmail.com
|