参考:《OReilly DNS and BIND 5th(2006)》
1.视图(view)
大家都知道,现在中国大陆上有三大运营商:联通、电信、移动。他们彼此之间的网络都是独立的,而它们彼此之间相连的带宽非常之小,这就导致了我们跨运营商网络访问的服务因为带宽原因变得缓慢。假设我们的用户大都是电信和移动的用户,那么如果我们把服务器单独放在电信或者移动机房都会导致一部分人访问缓慢。解决方法就是使用双线机房,服务器开双网卡,一个接入电信的网络,一个接入移动的网络,然后,让电信的用户访问电信的网,移动的访问移动的。
这个主意确实不错,可以完美解决我们的问题。但是,具体怎么实现呢?假设我们一个用户过来访问,我们怎么知道它是哪个网络的用户呢? 这就意味的,我们需要一个ip库,这个ip库记录着ip归属哪个网络,而根据这些信息把不同ip指挥到不同地方的功能在bind软件的实现中就是view。 显而易见,ip库越庞大和准确,我们的指挥效果越好,当然,庞大的数据意味着效率的降低,所以,数据库的优化,一直都是个值得探讨的问题。
view的选项很多,只提取必备的话,就可以很简短
view string optional_class { match-clients { address_match_element; ... }; zone string optional_class { type ( master | slave | stub | hint | forward | delegation-only ); file quoted_string; }; };
view的原理是,进来的链接地址匹配某个ip库,给匹配到的ip使用特定的区域文件,给其他匹配到的ip使用其他的区域文件,这样,我们就可以在不同的区域文件中给出不一样的解析。
所以它必备的参数有:
match-clients :匹配客户端地址
zone:区域文件
当然,match-clients 可以匹配很多形式的ip,比如内置变量any、localhost等,还有单个ip如1.1.1.1,网段127.0.0.1/8等等。 如果我们匹配的ip很多,这个时候使用match-clients 一条条写就很费力了。 bind官方最终提出的解决方案是把这些ip放进mysql之类的数据库里。
这里,因为我只是做下实验,网络规模不大,所以直接使用match-clients了。当然,如果view比较多的话,每次都写一大串也是很烦人的,所以这里我使用了acl。
acl的语法非常简单:
acl string { address_match_element; ... };
string:给acl取个别名
address_match_element:ip地址参数,比如1.1.1.1、any、127.0.0.0/8等。
我最终的named.conf非常简单,如下:
acl local { 172.16.0.0/16 ;}; options { directory "/var/named"; }; view insides IN { match-clients { local;}; zone linzb.com IN { type master; file "linzb.com.zone"; }; }; view besides IN { match-clients { any;}; zone linzb.com IN { type master; file "linzb.com.zone.1"; }; };
linzb.com.zone 内容如下:
$TTL 600 @ IN SOA ns1.linzb.com. admin.linzb.com. ( 2 1H 2W 3D 600 ) IN NS ns1 ns1 IN A 172.16.1.2 www IN A 172.16.1.4 test IN CNAME www
linzb.com.zone.1 内容如下:
$TTL 600 @ IN SOA ns1.linzb.com. admin.linzb.com. ( 2 1H 2W 3D 600 ) IN NS ns1 ns1 IN A 192.168.2.127 www IN A 192.168.2.38 test IN CNAME www
之所以这么设,是因为bind这台有两个ip,192.168.2.127和172.16.1.2,请根据自己的实际情况来
测试的话也很简单:dig -t A www.linzb.com @192.168.2.127和dig -t A www.linzb.com @172.16.1.2 就能看到dns返回不同结果了。
2.日志
日志的作用自然不必多说,bind的提供非常弹性的日志。它有两个关键参数:
channel:即信道,指定了日志数据发送到哪,它们可以是:文件、syslog、标准错误输出、字节桶等
category:即类别,表明什么样的数据会被记录到日志,例如queries(查询日志)、xfer-in(区域文件传入日志)等
它的语法如下:
logging { channel string { file log_file; //日志写入到log_file syslog optional_facility; //写入到syslog null; //不写入 stderr; //标准错误输出 severity log_severity; //日志级别 print-time yes_or_no; //日志是否打印时间戳,yes为是 print-severity yes_or_no; //打印级别 print-category yes_or_no; //是否打印类别 }; category string { string; ... }; //第一个string表示category的类别,有queries等,第二个string表示使用哪个channel,可以同时使用多个channel };
channel的日志级别有以下几种:critical、error、warning、notice、info、debug、dynamic
其中debug和dynamic是bind特有的等级,debug自身也有级别,默认为1,serverity的默认级别为info (详见:《OReilly DNS and BIND 5th(2006)》 第133-137页)
category的类别也有很多,它们的相关解释在 《OReilly DNS and BIND 5th(2006)》137-138页
这里我做了简单的配置,最终named.conf如下:
acl local { 127.0.0.1/8 ;}; options { directory "/var/named"; }; logging { channel default_log { file "/var/log/bind.log"; severity info; print-time yes; print-severity yes; print-category yes; }; category queries { default_log; }; }; view insides IN { match-clients { local;}; zone linzb.com IN { type master; file "linzb.com.zone"; }; }; view besides IN { match-clients { any;}; zone linzb.com IN { type master; file "linzb.com.zone.1"; }; };
dig -t A www.linzb.com @192.168.2.127 测试,查看日志如下:
28-Feb-2017 16:35:58.188 queries: info: client 192.168.2.127#57851: view besides: query: www.linzb.com IN A + (192.168.2.127)
debug:
1.出现“/etc/named.conf:16: expected quoted string near '/'”
这个表示在第16行,参数后面的值需要加 “” 号。
2.配置了日志但是没有日志生成。
可以tail -f /var/log/messages 查看相关日志信息,一般是没权限,比如我的是/var/log/bind.log,named用户在这个地方没写权限,所以我
touch /var/log/bind.log
chown -R named:named /var/log/bind.log 解决