在做一些实验时,经常需要一个内网的DNS服务器。本文详细描述了构建整个DNS服务器的过程。
前提条件
- 使用 VirtualBox 虚拟机,联网方式选择 内部网络,如果你不知道怎么配置网络,看 这里
- Oracle Linux 6.5 (可以认为=CentOS)下,Desktop软件组已经安装好
- 不使用IPv6
- 不使用DNSSEC
- 域名是 example.com
- DNS服务器的内网IP地址是 192.168.0.2
- DNS服务器的主机名是 server.example.com
- DNS服务器的外网IP地址是 192.168.1.2(真正的外网肯定不是这种地址,这里只是实验)
- 全部操作以root用户完成
环境准备
强烈推荐在安装任何服务之前先把SELinux和iptables(也就是防火墙)暂时禁止掉,这样的话我们可以专注于安装服务本身,而不会被各种SELinux上下文和防火墙规则所干扰。
在全部服务都安装好之后,你可以根据需要,开启SELinux和iptables。注意,本文不包含SELinux和iptables的配置。
禁用SELinux
# vim /etc/sysconfig/selinux
SELINUX=disabled # 由enforcing 改成 disabled
清空并禁用iptables
# iptables -F
# iptables -L
# service iptables save
也可以彻底关闭iptables服务:
# service iptables stop
# chkconfig iptables off
打开IP Forward 功能
之所以打开这个功能,是因为我想把Linux当做一个路由器来用。
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 #修改:由0改成1
# sysctl -p
重启机器
为了让SELinux的禁用的设置生效,必须重启机器。
DNS服务器构成规划
如下图所示:
配置 DNS服务器
设置IP地址以及主机名
这里不使用图形界面,使用命令行的方式来配置。
首先配置一下IP(192.168.0.2)以及相关的参数(因为我的虚拟机有多个网卡,这里用第二个网卡 eth1 来进行配置)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| DEVICE=eth1 TYPE=Ethernet UUID=06dbc3e2-4d24-4cb5-9b24-89c166a71e5a ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=none HWADDR=08:00:27:6D:CA:57 IPADDR=192.168.0.2 NETMASK=255.255.255.0 PREFIX=24 DEFROUTE=no IPV4_FAILURE_FATAL=yes IPV6INIT=no NAME="System eth1" HWADDR=08:00:27:C6:79:2B MTU=1500 UUID=9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04 LAST_CONNECT=1409908255
|
重启网络服务,并查看eth1的配置信息:
1 2 3 4 5 6 7 8
| 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:c6:79:2b brd ff:ff:ff:ff:ff:ff inet 192.168.0.2/24 brd 192.168.0.255 scope global eth1 inet6 fe80::a00:27ff:fec6:792b/64 scope link valid_lft forever preferred_lft forever ```language
|
修改主机名(server.example.com),先:
1 2 3
| NETWORKING=yes HOSTNAME=server.example.com
|
再:
1 2 3 4
| 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.0.2 server.example.com
|
重启,使 hostname 生效:
# reboot
安装Bind
使用yum进行安装:
# yum -y install bind bind-chroot
编写一个 chroot(/root/bind-chroot-admin)脚本,内容如下:
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 33 34
| #!/bin/sh rpm -q bind-chroot > /dev/null 2>&1 [ $? -ne 0 ] && echo bind-chroot not install && exit 1 sed -i '/^ROOTDIR=/d' /etc/sysconfig/named echo ROOTDIR=/var/named/chroot >> /etc/sysconfig/named filelist=`mktemp` rpm -ql bind|grep ^/etc >> ${filelist} rpm -ql bind|grep ^/var >> ${filelist} for file in `cat ${filelist}` do if [ -d ${file} ]; then DIRNAME=/var/named/chroot${file} [ ! -d ${DIRNAME} ] && mkdir -p ${DIRNAME} fi if [ -f ${file} ]; then DIRNAME=/var/named/chroot`dirname ${file}` [ ! -d ${DIRNAME} ] && mkdir -p ${DIRNAME} /bin/cp -a ${file} ${DIRNAME} fi done rm -f ${filelist} chown named:named /var/named/chroot/var/named/data chmod 770 /var/named/chroot/var/named/data chown named:named /var/named/chroot/var/named/dynamic exit
|
执行此脚本:
# sh bind-chroot-admin
配置Bind
编辑bind的配置文件(/var/named/chroot/etc/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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| // // named.conf // // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS // server as a caching only nameserver (as a localhost DNS resolver only). // // See /usr/share/doc/bind*/sample/ for example named configuration files. // 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 { localhost; localnets; }; recursion yes; empty-zones-enable no; dnssec-enable no; dnssec-validation no; /* Path to ISC DLV key */ bindkeys-file "/etc/named.iscdlv.key"; forwarders{ 192.168.0.2; }; managed-keys-directory "/var/named/dynamic"; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; category lame-servers { null; }; }; view "internal" { match-clients { localnets; }; match-destinations { localnets; }; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key"; include "/etc/named.example.com.zone"; }; view "external" { match-clients { any; }; match-destinations { any; }; recursion no; include "/etc/named.example.com.zone.wan"; };
|
编辑内部Zone的定义文件
文件名: /var/named/chroot/etc/named.example.com.zone
1 2 3 4 5 6 7 8
| zone "example.com" { type master; file "example.com.db"; }; zone "0.168.192.in-addr.arpa" { type master; file "0.168.192.in-addr.arpa.db"; };
|
编辑外部Zone的定义文件(可选)
文件名: /var/named/chroot/etc/named.example.com.zone.wan
如果你的DNS服务器不打算接入Internet的话,这个文件不需要。
1 2 3 4 5 6 7 8 9 10
| zone "example.com" { type master; file "example.com.db.wan"; allow-query { any; }; }; zone "1.168.192.in-addr.arpa" { type master; file "1.168.192.in-addr.arpa.db"; allow-query { any; }; };
|
仅开放IPv4
文件名: /etc/sysconfig/named
更新根域名服务器列表(可选)
再次提醒,如果你只是内网使用DNS的话,这一小节的内容请无视。
# dig . ns @198.41.0.4 +bufsize=1024 > /var/named/chroot/var/named/named.ca
为了方便起见,可以使用一个自动脚(named.root_update)本来跟新根DNS域名服务器的列表:
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 33 34
| #!/bin/bash new=`mktemp` errors=`mktemp` dig . ns @198.41.0.4 +bufsize=1024 > $new 2> $errors if [ $? -eq 0 ]; then sort_new=`mktemp` sort_old=`mktemp` diff_out=`mktemp` sort $new > $sort_new sort /var/named/chroot/var/named/named.ca > $sort_old diff --ignore-matching-lines=^\; $sort_new $sort_old > $diff_out if [ $? -ne 0 ]; then ( echo '-------------------- old named.root --------------------' cat /var/named/chroot/var/named/named.ca echo echo '-------------------- new named.root --------------------' cat $new echo '---------------------- difference ----------------------' cat $diff_out ) | mail -s 'named.root updated' root cp -f $new /var/named/chroot/var/named/named.ca chown named. /var/named/chroot/var/named/named.ca chmod 644 /var/named/chroot/var/named/named.ca /etc/rc.d/init.d/named restart > /dev/null fi rm -f $sort_new $sort_old $diff_out else cat $errors | mail -s 'named.root update check error' root fi rm -f $new $errors
|
然后让这个脚本可执行;
# chmod 700 named.root_update
最后让这个脚本每个月自动执行(前提是你的crond已经打开):
# mv named.root_update /etc/cron.monthly/
配置解析文件
内部用正解文件
也就是从域名到IP地址的解析关系。
文件名: /var/named/chroot/var/named/example.com.db
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| $TTL 86400 @ IN SOA example.com. root.example.com.( 2013120801; Serial 28800 ; Refresh 14400 ; Retry 3600000 ; Expire 86400 ) ; Minimum IN NS example.com. IN MX 10 example.com. @ IN A 192.168.0.2 * IN A 192.168.0.2 dns IN A 192.168.0.2 server IN A 192.168.0.2 ldap IN A 192.168.0.2 www IN A 192.168.0.2 mail IN A 192.168.0.2 ftp IN A 192.168.0.2 sgd-server IN A 192.168.0.3 win IN A 192.168.0.4 lin IN A 192.168.0.5 sol IN A 192.168.0.6 wins IN A 192.168.0.7
|
内部用反解文件
也就是从IP到域名的关系。
文件名: /var/named/chroot/var/named/0.168.192.in-addr.arpa.db
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $TTL 86400 @ IN SOA example.com. root.example.com.( 2013120801 ; Serial 28800 ; Refresh 14400 ; Retry 3600000 ; Expire 86400 ) ; Minimum IN NS example.com. 2 IN PTR example.com. 2 IN PTR dns.example.com. 2 IN PTR server.example.com. 2 IN PTR ldap.example.com. 2 IN PTR www.example.com. 2 IN PTR mail.example.com. 2 IN PTR ftp.example.com. 3 IN PTR sgd-server.example.com. 4 IN PTR win.example.com. 5 IN PTR lin.example.com. 6 IN PTR sol.example.com. 7 IN PTR wins.example.com.
|
外部用正解文件(可选)
也就是从外部访问时,从域名到IP地址的解析关系。
文件名: /var/named/chroot/var/named/example.com.db.wan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $TTL 86400 @ IN SOA ns1.example.com. root.example.com.( 2013120801 ; Serial 7200 ; Refresh 7200 ; Retry 2419200 ; Expire 86400 ) ; Minimum IN NS ns1.example.com. IN MX 10 example.com. ns1 IN A 192.168.1.2 @ IN A 192.168.1.2 www IN A 192.168.1.2 ftp IN A 192.168.1.2 mail IN A 192.168.1.2 server IN A 192.168.1.2 ldap IN A 192.168.1.2 dns IN A 192.168.1.2 example.com. IN TXT "v=spf1 ip4:192.168.1.2 ~all"
|
外部用反解文件(可选)
文件名: /var/named/chroot/var/named/1.168.192.in-addr.arpa.db
1 2 3 4 5 6 7 8 9 10 11
| $TTL 86400 @ IN SOA example.com. root.example.com.( 2013120801 ; serial 3600 ; refresh (1 hour) 900 ; retry (15 minutes) 604800 ; expire (1 week) 86400 ; negative (1 day) ) IN NS example.com. 2 IN PTR example.com. ```language
|
启动 bind 服务,测试运行
启动服务:
# service named start
开机自动运行DNS服务:
# chkconfig named on
配置网卡eth1的DNS,使用本机做为DNS服务器:
# vim /etc/sysconfig/network-scripts/ifcfg-eth1
DNS1=127.0.0.1
测试
先测试正向解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.0.2.el6_4.6 <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5153 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 86400 IN A 192.168.0.2 ;; AUTHORITY SECTION: example.com. 86400 IN NS example.com. ;; Query time: 4 msec ;; SERVER: 127.0.0.1 ;; WHEN: Tue Sep 9 15:08:27 2014 ;; MSG SIZE rcvd: 59
|
观察上面的 ANSWER SECTION,可以看出解析成功了。
接下来试试反向解析:
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
| ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.0.2.el6_4.6 <<>> -x 192.168.0.2 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31947 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;2.0.168.192.in-addr.arpa. IN PTR ;; ANSWER SECTION: 2.0.168.192.in-addr.arpa. 86400 IN PTR mail.example.com. 2.0.168.192.in-addr.arpa. 86400 IN PTR ftp.example.com. 2.0.168.192.in-addr.arpa. 86400 IN PTR example.com. 2.0.168.192.in-addr.arpa. 86400 IN PTR dns.example.com. 2.0.168.192.in-addr.arpa. 86400 IN PTR server.example.com. 2.0.168.192.in-addr.arpa. 86400 IN PTR ldap.example.com. 2.0.168.192.in-addr.arpa. 86400 IN PTR www.example.com. ;; AUTHORITY SECTION: 0.168.192.in-addr.arpa. 86400 IN NS example.com. ;; ADDITIONAL SECTION: example.com. 86400 IN A 192.168.0.2 ;; Query time: 4 msec ;; SERVER: 127.0.0.1 ;; WHEN: Tue Sep 9 15:09:31 2014 ;; MSG SIZE rcvd: 210 ```language
|
观察上面的 ANSWER SECTION,可以看出解析也成功了。
至于外部解析,因为和上面的步骤相同,这里就不在赘述。
至此为止,所有的配置都完成了。
参考
[1] http://www.mk-mode.com/octopress/2013/12/21/centos-6-5-bind-installation/
(END)