文章目录
  1. 1. 前提条件
  2. 2. 环境准备
    1. 2.1. 禁用SELinux
    2. 2.2. 清空并禁用iptables
    3. 2.3. 打开IP Forward 功能
    4. 2.4. 重启机器
  3. 3. DNS服务器构成规划
  4. 4. 配置 DNS服务器
    1. 4.1. 设置IP地址以及主机名
    2. 4.2. 安装Bind
    3. 4.3. 配置Bind
      1. 4.3.1. 编辑bind的配置文件(/var/named/chroot/etc/named.conf):
      2. 4.3.2. 编辑内部Zone的定义文件
      3. 4.3.3. 编辑外部Zone的定义文件(可选)
      4. 4.3.4. 仅开放IPv4
      5. 4.3.5. 更新根域名服务器列表(可选)
    4. 4.4. 配置解析文件
      1. 4.4.1. 内部用正解文件
      2. 4.4.2. 内部用反解文件
      3. 4.4.3. 外部用正解文件(可选)
      4. 4.4.4. 外部用反解文件(可选)
    5. 4.5. 启动 bind 服务,测试运行
      1. 4.5.1. 测试
    6. 4.6. 参考

在做一些实验时,经常需要一个内网的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构成

配置 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
# vim /etc/sysconfig/network-scripts/ifcfg-eth1
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
# service network restart
# ip addr show eth1
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
# vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=server.example.com

再:

1
2
3
4
# vim /etc/hosts
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
#bind-chroot install check
rpm -q bind-chroot > /dev/null 2>&1
[ $? -ne 0 ] && echo bind-chroot not install && exit 1
# bind-chroot enabled
sed -i '/^ROOTDIR=/d' /etc/sysconfig/named
echo ROOTDIR=/var/named/chroot >> /etc/sysconfig/named
# file copy
filelist=`mktemp`
rpm -ql bind|grep ^/etc >> ${filelist}
rpm -ql bind|grep ^/var >> ${filelist}
for file in `cat ${filelist}`
do
# directory make
if [ -d ${file} ]; then
DIRNAME=/var/named/chroot${file}
[ ! -d ${DIRNAME} ] && mkdir -p ${DIRNAME}
fi
# file copy
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 {
#listen-on port 53 { 127.0.0.1; }; #注释掉
#listen-on-v6 port 53 { ::1; }; #注释掉
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; }; # 修改: 添加 localnets
recursion yes;
empty-zones-enable no; #追加: 启动时对于空的zone的错误日志不输出
dnssec-enable no; #修改: yes -> no, 不使用DNSSEC
dnssec-validation no; #修改: yes -> no, 不使用DNSSEC
#dnssec-lookaside auto; #注释掉
/* Path to ISC DLV key */
bindkeys-file "/etc/named.iscdlv.key";
forwarders{ #追加
192.168.0.2; #追加: 路由器的IP,我把本机当路由了
}; #追加
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" { #追加,可选,如果你的DNS服务器不准备连接外网的话,这里不用写
match-clients { any; };#追加,可选,如果你的DNS服务器不准备连接外网的话,这里不用写
match-destinations { any; };#追加,可选,如果你的DNS服务器不准备连接外网的话,这里不用写
recursion no; #追加,可选,如果你的DNS服务器不准备连接外网的话,这里不用写
include "/etc/named.example.com.zone.wan"; #追加:注意这里和你的域名做相应的调整,,可选,如果你的DNS服务器不准备连接外网的话,这里不用写
}; #追加,可选,如果你的DNS服务器不准备连接外网的话,这里不用写

编辑内部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

1
OPTIONS="-4" # 在文件的最后加入这行

更新根域名服务器列表(可选)

再次提醒,如果你只是内网使用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 example.com
; <<>> 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#53(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 -x 192.168.0.2
; <<>> 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#53(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)

文章目录
  1. 1. 前提条件
  2. 2. 环境准备
    1. 2.1. 禁用SELinux
    2. 2.2. 清空并禁用iptables
    3. 2.3. 打开IP Forward 功能
    4. 2.4. 重启机器
  3. 3. DNS服务器构成规划
  4. 4. 配置 DNS服务器
    1. 4.1. 设置IP地址以及主机名
    2. 4.2. 安装Bind
    3. 4.3. 配置Bind
      1. 4.3.1. 编辑bind的配置文件(/var/named/chroot/etc/named.conf):
      2. 4.3.2. 编辑内部Zone的定义文件
      3. 4.3.3. 编辑外部Zone的定义文件(可选)
      4. 4.3.4. 仅开放IPv4
      5. 4.3.5. 更新根域名服务器列表(可选)
    4. 4.4. 配置解析文件
      1. 4.4.1. 内部用正解文件
      2. 4.4.2. 内部用反解文件
      3. 4.4.3. 外部用正解文件(可选)
      4. 4.4.4. 外部用反解文件(可选)
    5. 4.5. 启动 bind 服务,测试运行
      1. 4.5.1. 测试
    6. 4.6. 参考