在Ubuntu 14.04上配置Bind作为缓存型/转发型DNS服务器

提供:ZStack云计算

系列教程

本教程为7篇系列中的第4篇:DNS管理简介

前言

DNS(域名系统)是经常容易配置出错的一个网络组件。直接使用现成的DNS服务是大部分人的选择,服务提供方可能是托管商或者域名注册机构,不过自己架设DNS服务器也有很多好处。

本文介绍将Bind9作为缓存型/转发型DNS服务器安装在Ubuntu 14.04上的步骤。这两种DNS服务器在网络上各有其适合的场景。

准备工作与目标

在进入本文操作步骤之前,你需要先对DNS的相关术语有所了解。有关DNS的概念与术语可以通过这篇文章获取。

我们将展示两种不同的配置,一种用于缓存型DNS服务器,一种用于转发型DNS服务器,两者的目标类似。

你需要准备两台主机,其中至少一台是Ubuntu 14.04系统。一台作为客户端,另一台作为服务器。两台主机的细节如下表:

功用IP地址
DNS服务器192.0.2.1
客户端192.0.2.100

我们将展示客户端的配置方法,以及DNS服务器的两种配置方法。

缓存型DNS服务器

首先是缓存型DNS服务器的配置。此类服务器也常被称为resolver,因为它能够处理递归请求,从其他服务器获取正确的DNS数据。

缓存型服务器在针对客户端请求进行查询后,将回复返回给客户端,同时将其缓存到本机,存留时间取决于该记录的TTL时长。缓存到本机的记录可以快速的返回给其他关于本记录的请求。

在一个网络配置中,可能我们接触的大部分DNS服务器都是缓存型,其目的是服务缺乏DNS解析能力的大量客户端。缓存型服务器适用于很多场景。如果你不想依赖ISP提供的DNS或其他公开的DNS,则可以自己搭建一个缓存型DNS。自驾的DNS服务如果离其大部分客户端较近,则可以很大程度上提升查询的效率。

转发型DNS服务器

其次,我们将配置一个转发型DNS服务器。对客户端而言,转发型和缓存型没有任何区别,然而服务器端的运行机制和负载则有很大不同。

跟缓存型服务器一样,转发型服务器也在本地进行缓存,以快速的给客户端返回DNS解析结果。跟缓存型服务器不同的是,转发型服务器自己并不参与到递归查询的工作中,而是单纯的将所有请求转发给另一台解析服务器,并把获得的结果缓存到本地。

所以,转发型服务器的工作量是比较小的,这比较适合对外带宽吃紧的环境,经常需要更换缓存服务器的环境,或者是希望将内网请求和公网请求分开处理的场景。

安装Bind

无论是缓存型还是转发型,搭建的第一个步骤都是安装Bind软件。

在Ubuntu下,Bind软件可以从默认repo中安装。运行如下命令以安装bind以及相关文档工具:

sudo apt-get update
sudo apt-get install bind9 bind9utils bind9-doc

安装完毕之后,可以开始配置服务器。缓存型服务器的配置可以作为转发型服务器的基础,所以我们先开始缓存型服务器的配置。

配置缓存型DNS服务器

缓存型DNS服务器的配置将迫使服务器在接受一个客户端请求后,从其他DNS服务器递归寻找答案。也就是说,它会针对相关的服务器一个一个的问下去,直到获得完整的回复为止。

Bind配置文件默认位于/etc/bind。先进入该目录:

cd /etc/bind

该目录下有很多文件,大部分我们都无需操心。主配置文件为named.confnamedbind是同一个应用的两个名字),该文件是named.conf.optionsnamed.conf.localnamed.conf.default-zones这三个文件的集合引用。

对于缓存型服务器,我们只需要修改named.conf.options文件即可。用编辑器打开该文件:

sudo nano named.conf.options

当前,文件内容是这样的(删除了注释的部分以方便阅读):

options {
        directory "/var/cache/bind";

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

首先我们要设置一个访问权限控制列表,即ACL。

由于DNS服务器要处理的是递归请求,因此我们不希望有恶意用户造成滥用。有一种很讨厌的攻击叫做DNS放大攻击(DNS amplification attack),就是把你的DNS服务器拉入一场DDoS攻击作为帮凶。

DNS放大攻击是恶意用户搞垮一台服务器或网站所用的方式之一。他们首先寻找可以处理递归请求的公网DNS服务器,假装成受害者的IP地址向DNS服务器发送请求,这种特殊的请求会返回很大的回复信息,于是受害者的IP地址会接收大量的信息阻塞其带宽。

公共的递归DNS服务器的托管涉及大量的特殊配置与维护工作,大部分情况下这会增加不必要的工作量,所以我们可以把我们的服务器配置为仅对一个可信列表中的主机提供服务,从而免去了被恶意滥用的危险。

options内容块上方,创建一个名为acl的内容块。我们需要为该ACL组创建一个标签,这里我们就叫它goodclients

acl goodclients {
};

options {
    . . .

在本内容块内,列出被允许使用该DNS服务器的主机IP地址和网络。在本示范中,服务器和客户端都在同一个/24子网下,所以我们就仅对此子网开放权限。此外我们还要添加localhostlocalnets

acl goodclients {
    192.0.2.0/24;
    localhost;
    localnets;
};

options {
    . . .

配置好了ACL,现在可以编辑options块了。在本块下添加如下内容:

options {
    directory "/var/cache/bind";

    recursion yes;
    allow-query { goodclients; };
    . . .

我们特意将recursion(递归)开启,并在allow-query参数中使用刚才指定的ACL列表。我们还可以使用别的参数,比如使用allow-recursion来引用ACL。在present和recursion均开启的状态下,allow-recursion参数中列入的客户端将被允许使用递归查询服务。

如果allow-recursion没有进行设置,则Bind会检查allow-query-cache中的列表,然后是allow-query中的列表,最后是默认的localnetslocalhost限定。由于我们配置的是缓存型服务器,其不具备权威型所负责的区域,也不对请求进行转发,所以所有的请求都是递归请求,相当于allow-query就等同于allow-recursion。我们使用allow-query,是因为这是最通用的指定ACL的方法。

编辑完成后,保存退出。

对于缓存型DNS服务器,这差不多是全部所需的配置了。如果你只是需要一台缓存型服务器,则可以直接跳过下一部分,直接进入后面的配置文件检查、重启服务和客户端配置的部分。

如果你需要一台转发型DNS服务器,则继续往下看。

转发型DNS服务器的配置

如果转发型服务器更适合你架构的需要,那么可以做如下配置。这个配置工作是比较简单的。

以刚才完成的配置文件作为起点,当前的named.conf.options文件看起来应该是这样的:

acl goodclients {
        107.170.41.189;
        localhost;
        localnets;
};

options {
        directory "/var/cache/bind";

        recursion yes;
        allow-query { goodclients; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

我们将使用同样的ACL列表用于限制可以使用该DNS服务的客户端,不过我们要对配置进行一些变更,让服务器不再亲自处理递归类的请求。

要达到这个目的,并不是简单的将recursion改为no,因为转发型服务器仍然需要对其不负责的区的请求提供递归服务。我们的做法是为转发请求单独设置一个列表。

options {}内容块内,创建一个名为forwarders的内容块,该块下包含了我们的转发目标,也就是其他的递归服务器的IP地址。本示范将使用Google的公共DNS服务器,即8.8.8.88.8.4.4

. . .
options {
        directory "/var/cache/bind";

        recursion yes;
        allow-query { goodclients; };

        forwarders {
                8.8.8.8;
                8.8.4.4;
        };
        . . .

然后,我们将forward条目设置为“only”,即服务器仅做转发,不亲自参与解析工作。

现在的配置文件看起来应该是这样的:

acl goodclients {
        107.170.41.189;
        localhost;
        localnets;
};

options {
        directory "/var/cache/bind";

        recursion yes;
        allow-query { goodclients; };

        forwarders {
                8.8.8.8;
                8.8.4.4;
        };
        forward only;

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

最后,我们需要更改dnssec的参数。根据目前的配置,我们在服务器运行的日志中会看到如下错误信息:

Jun 25 15:03:29 cache named[2512]: error (chase DS servers) resolving 'in-addr.arpa/DS/IN': 8.8.8.8#53
Jun 25 15:03:29 cache named[2512]: error (no valid DS) resolving '111.111.111.111.in-addr.arpa/PTR/IN': 8.8.4.4#53

我们需要更改dnssec-validation的设置为“yes”,同时明确的启用dnssec,以避免此错误信息:

. . .
forward only;

dnssec-enable yes;
dnssec-validation yes;

auth-nxdomain no;    # conform to RFC1035
. . .

保存退出。转发型DNS服务器这样就配置好了,接下来是配置文件的检查工作以及重启守护进程的工作。

检查配置文件并重启Bind

完成上述配置变更后,我们需要使这些变更生效。

在重启Bind之前,最好用Bind内置的工具检查一下配置文件的语法。

输入如下命令进行检查:

sudo named-checkconf

如果没有语法错误,则命令行控制符会直接回到正常状态,终端没有输出信息。

如果有语法错误,则错误的内容和位置会显示在输出信息中。

确认无误后,输入以下指令重启Bind以使配置生效:

sudo service bind9 restart

重启后,注意一下服务器的日志,确保没有什么错误。可以在服务器上让下面这个命令一直跑着:

sudo tail -f /var/log/syslog

现在可以打开一个新的终端窗口去配置客户端了。

配置客户端

服务器端正常运行后,现在可以配置客户端以使用该DNS服务。

登陆到客户端的主机上(该主机必须在刚才设置的goodclients ACL列表中,否则DNS服务器会拒绝为其服务)。

我们需要编辑/etc/resolv.conf文件,将请求指向刚才设置好的DNS服务器。此处进行的变更一旦系统重启就会失效,所以适合在测试的时候用,测试通过后再通过另外的方法使配置永久生效。

使用编辑器打开该文件:

sudo nano /etc/resolv.conf

该文件包含了该客户端将使用的DNS服务器,每一台服务器通过一条nameserver条目进行设置。将原来的条目都注释掉,然后在最上面新增一个nameserver条目,将刚才我们设置好的服务器IP地址填写进去:

nameserver 192.0.2.1
# nameserver 8.8.4.4
# nameserver 8.8.8.8
# nameserver 209.244.0.3

保存退出。

现在我们可以用一些常用的工具来检测请求的解析。

我们可以用ping来测试针对域名的连接是否能够建立:

ping -c 1 google.com


PING google.com (173.194.33.1) 56(84) bytes of data.
64 bytes from sea09s01-in-f1.1e100.net (173.194.33.1): icmp_seq=1 ttl=55 time=63.8 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 63.807/63.807/63.807/0.000 ms

以上信息说明客户端成功的通过该DNS服务器连接到了google.com

我们也可以使用类似dig的DNS工具获取更详细的信息。这次试试另一个域名:

dig linuxfoundation.org


; <<>> DiG 9.9.5-3-Ubuntu <<>> linuxfoundation.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35417
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;linuxfoundation.org.       IN  A

;; ANSWER SECTION:
linuxfoundation.org.    6017    IN  A   140.211.169.4

;; Query time: 36 msec
;; SERVER: 192.0.2.1#53(192.0.2.1)
;; WHEN: Wed Jun 25 15:45:57 EDT 2014
;; MSG SIZE  rcvd: 64

可以看到,该请求花费了36毫秒。如果我们再次发起同样的请求,这个时间应该会减少,因为服务器会从缓存直接返回数据:

dig linuxfoundation.org


; <<>> DiG 9.9.5-3-Ubuntu <<>> linuxfoundation.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18275
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;linuxfoundation.org.       IN  A

;; ANSWER SECTION:
linuxfoundation.org.    6012    IN  A   140.211.169.4

;; Query time: 1 msec
;; SERVER: 192.0.2.1#53(192.0.2.1)
;; WHEN: Wed Jun 25 15:46:02 EDT 2014
;; MSG SIZE  rcvd: 64

如上所示,响应时间(1 msec)大大的减少了。

我们还可以用dig工具的-x选项测试反向查询的功能。比如查询140.211.169.4的域名:

dig -x 140.211.169.4


; <<>> DiG 9.9.5-3-Ubuntu <<>> -x 140.211.169.4
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61516
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;4.169.211.140.in-addr.arpa.    IN  PTR

;; ANSWER SECTION:
4.169.211.140.in-addr.arpa. 3402 IN CNAME   4.0-63.169.211.140.in-addr.arpa.
4.0-63.169.211.140.in-addr.arpa. 998 IN PTR load1a.linux-foundation.org.

;; Query time: 31 msec
;; SERVER: 192.0.2.1#53(192.0.2.1)
;; WHEN: Wed Jun 25 15:51:23 EDT 2014
;; MSG SIZE  rcvd: 117

如上,反向查询的测试也成功通过了。

回到DNS服务器的终端窗口看一下日志,检查是否出现错误。一个经常会出现的错误是这样的:

. . .
Jun 25 13:16:22 cache named[2004]: error (network unreachable) resolving 'ns4.apnic.net/A/IN': 2001:dc0:4001:1:0:1836:0:140#53
Jun 25 13:16:22 cache named[2004]: error (network unreachable) resolving 'ns4.apnic.com/A/IN': 2001:503:a83e::2:30#53
Jun 25 13:16:23 cache named[2004]: error (network unreachable) resolving 'sns-pb.isc.org/AAAA/IN': 2001:500:f::1#53
Jun 25 13:16:23 cache named[2004]: error (network unreachable) resolving 'ns3.nic.fr/A/IN': 2a00:d78:0:102:193:176:144:22#53

该错误的意思是,服务器尝试解析IPv6的信息,但它并没有针对IPv6做过配置。我们可以将Bind配置为IPv4限定,这样就不会出现这个错误了。

用sudo权限打开/etc/default/bind9文件:

sudo nano /etc/default/bind9

编辑OPTIONS参数,加入-4标识,即限定仅使用IPv4:

OPTIONS="-u bind -4"

保存退出。

重启服务器:

sudo service bind9 restart

现在应该不会再出现上面那个错误信息了。

使客户端配置永久生效

如上所述,/etc/resolv.conf的设置变更在系统重启后就会失效。如果需要该配置永久生效,则需要去编辑一个用于生成该文件的文件。

对于Debian或Ubuntu客户端,可以以sudo权限打开/etc/network/interfaces文件:

sudo nano /etc/network/interfaces

找到dns-nameservers参数,将我们的DNS服务器替换或者添加进去:

. . .
iface eth0 inet static
        address 111.111.111.111
        netmask 255.255.255.0
        gateway 111.111.0.1
        dns-nameservers 192.0.2.1
. . .

保存退出。下次服务器重启后,该配置会自动生效。

对于CentOS或Fedora客户端,则需要编辑/etc/sysconfig/network/network-scripts/ifcfg-eth0文件:

sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0

在文件内找到以DNS开头的条目,将DNS1更改为我们的DNS服务器IP。如果不想要其他的备用DNS服务器,则可以把它们都删除掉:

DNS1=192.0.2.1

保存退出。下次服务器重启后,该配置会自动生效。

总结

至此,我们已经配置好了一台缓存型或者转发型的DNS服务器,这将有效的提升我们所管理的主机们的DNS请求速度。

如果你想要为你自己的域名区配置一台权威型DNS服务器,则可以参考这篇权威型DNS服务器的配置教程

本文来源自DigitalOcean Community。英文原文:How To Configure Bind as a Caching or Forwarding DNS Server on Ubuntu 14.04 by Justin Ellingwood

翻译:lazycai

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值