配置BIND 9 DNS Views 的原理和需求
--------------------------------------------------------------------------
DNS服务器最基本的任务就是响应域名的查询,返回该域名的地址数据. 在DNS服务器中将一个
域名分成内部与外部做不同的View解析, 可以提升安全性,以及分类应付不同区域的查询请求.
例如您的单位需要分成内部网和外部网,希望将同一个域名解析为不同的IP地址, 以提高安全
防护的目的, 或者应付不同业务的应用; 又比如您需要将业务按地域来划分,打算在各个地区
分别设置各自的主机来处理访问请求(或者单机双线也适用),以图解决中国南北网(电信/网通)
互不相通所导致的速度差异之问题,希望将电信用户解释到由电信网络所提供的IP地址上, 而
网通用户则解释到由网通网络所提供的IP地址上;

要实现将来自不同地域(用IP段来标识)的请求, 自动引导到不同区域的主机,可以采用域名的
多解释方法来简单实现. 在BIND9中有个新的view指令可以完成达到这个目的, 方法就是设置
多个view段落来响应同一个域名的查询请求. 只需要在每个view段落的match-clients项目中,
设置所需匹配的客户端IP段落, 并且在每个段落中都设置该域名的区域数据,但不同的view则
指向不同的区域文件, 然后在各自的区域文件中分别设置相应的区域内容,这样就可以达到按
请求者的IP段落,来分别响应并提供不同的查询结果了.

针对访问者不同的IP段,来解释主机域名的相应的IP地址, 也可以轻易实现负载均衡或者化解
地区局限. 举个例子来说, 目前国内的网络因为种种原因,同外部网络的联机经常出现不稳定
的状况,造成从大陆内部无法访问外部,而外部也无法访问内部,尤其是导致电邮收发异常缓慢
甚至丢失反弹,非常令人头疼. 而且很多时候造成这种不稳定的因素, 还常常是源自于国家级
主干网络的非技术性故障,这就很难从主机供货商方面寻求解决问题的方案. 如果要彻底解决
这个问题的话, 那么一个可能的方案就是按地域来划分业务. 例如,分别在不同地区设置一台
主机(假设在北京设置一台主机,在广州设置一台主机,在香港设置另一台主机),然后就可设法
将大陆内部北方的客户引导到北京(网通)的主机, 将南方的客户引导到广州(电信)的主机,而
将海外的客户则引导到香港的主机.

请注意: view指令是BIND 9的新功能, BIND 8以前的版本无此功能;
----------------------------------------------------------------------------------


----------------------------------------------------------------------------------
(2) 配置BIND 9 DNS Views 的实验范例
----------------------------------------------------------------------------------
【实验环境】

操作系统:        Debian 4.1;
BIND版本:        BIND 9.3.4;
DNS服务器:        192.168.0.8;
内部IP段:        192.168.0.0/24;
外部IP段:        除192.168.0.0/24之外的所有IP;
解释域名:        mytest.com;

希望内部IP和本机IP(192.168.0.8)所解析到www.mytest.com的IP地址为1.1.1.1;
希望外部IP段(192.168.0.7和192.168.0.17)则解析到2.2.2.2;
希望其他IP段(我的测试IP是192.168.0.2)则解释到3.3.3.3;


【BIND9的配置文件】

vi /etc/bind/named.conf;        #
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
include "/etc/bind/named.conf.options";

view "internal" {
        match-clients      { localhost; 192.168.0.8; };
        match-destinations { any; };
        recursion yes;
        allow-query     { localhost; 192.168.0.0/24; };
        allow-transfer  { 192.168.0.7; };
        include "/etc/bind/named.internal.zones";
        include "/etc/bind/named.conf.local";
};

view "external" {
        match-clients      { 192.168.0.7; 192.168.0.17; };
        match-destinations { any; };
        recursion yes;
        allow-query     { any; };
        allow-transfer  { 192.168.0.7; };
        include "/etc/bind/named.external.zones";
        include "/etc/bind/named.conf.local";
};

view "others" {
        match-clients      { any; };
        match-destinations { any; };
        recursion yes;
        allow-query     { any; };
        allow-transfer  { 192.168.0.7; };
        include "/etc/bind/named.others.zones";
        include "/etc/bind/named.conf.local";
};
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
请注意: 各个View指令的应用是按先后顺序执行的,即是按首先符合的条件返回结果,例如本地
请求首先符合第一View指令, 则返回结果,不再检查其他的View; 来自192.168.0.7的请求符合
第二个View指令, 则返回结果, 不再检查后面的View; 所以,如果要在该View的match-clients
中设置任何条件(即any)的话, 就必须将这个View摆在最后面, 而绝不能放在其他View的前面.

vi /etc/bind/named.internal.zones;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
zone "." {
        type hint;
        file "/etc/bind/db.root";
};

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

zone "mytest.com" IN {
        type master;
        file "/etc/bind/mytest.com.internal";
};
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

vi /etc/bind/named.external.zones;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
zone "." {
        type hint;
        file "/etc/bind/db.root";
};

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

zone "mytest.com" IN {
        type master;
        file "/etc/bind/mytest.com.external";
};
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

vi /etc/bind/named.others.zones;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
zone "." {
        type hint;
        file "/etc/bind/db.root";
};

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

zone "mytest.com" IN {
        type master;
        file "/etc/bind/mytest.com.others";
};
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


vi /etc/bind/mytest.com.internal;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
$TTL 4320       ; 1 hour 12 minutes
@       IN      SOA     ns.mytest.com.  root.ns.mytest.com.      (
                                2007101701      ;
                                3600            ;
                                1800            ;
                                36000           ;
                                3600 )          ;
        IN      NS      ns.mytest.com.
ns      IN      A       192.168.0.8
www     IN      A       1.1.1.1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

vi /etc/bind/mytest.com.external;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$TTL 4320       ; 1 hour 12 minutes
@       IN      SOA     ns.mytest.com.  root.ns.mytest.com.      (
                                2007101701      ;
                                3600            ;
                                1800            ;
                                36000           ;
                                3600 )          ;
        IN      NS      ns.mytest.com.
ns      IN      A       192.168.0.8
www     IN      A       2.2.2.2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

vi /etc/bind/mytest.com.others;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
$TTL 4320       ; 1 hour 12 minutes
@       IN      SOA     ns.mytest.com.  root.ns.mytest.com.      (
                                2007101701      ;
                                3600            ;
                                1800            ;
                                36000           ;
                                3600 )          ;
        IN      NS      ns.mytest.com.
ns      IN      A       192.168.0.8
www     IN      A       3.3.3.3
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


【测试与结果】

设置好后重启BIND服务: /etc/init.d/bind9 restart;

如果一切设置正常的话,现在DNS服务器应该能分别针对不同IP地址的请求,来返回不同的主机
解释了, 这里测试从192.168.0.2,192.168.0.7和192.168.0.8(本机)查询结果是:

从192.168.0.2查询(dig @191.168.0.2 www.mytest.com;)则返回3.3.3.3;
从192.168.0.7查询(dig @191.168.0.7 www.mytest.com;)则返回2.2.2.2;
从192.168.0.8查询(dig @191.168.0.8 www.mytest.com;)则返回1.1.1.1;