一、DNS基本安全控制


在DNS基本安全控制中,常常需要对某些网段内的主机做匹配,并对这些匹配到的主机做安全控制。在这个过程中,匹配这一过程可以由acl来控制。什么是acl?简单来说,acl就是访问控制列表,可以将一个或多个地址归并为一个命名的集合,随后通过此名称即可对该集合内的所有主机实现统一调用。


在bind程序中,acl的配置建议写在/etc/named.conf的全局配置段之前。acl格式如下:

acl acl_name {
    ip;
    ipnet/prelen;
};

其中,acl_name是自定义名称,ip指的是IP地址,ipnet/prelen指的是IP网段。


示例,将192.168.10.0/24和127.0.0.0/8这两个网段做acl归并起来,并命名这个集合为mynet.

acl mynet {
    192.168.10.0/24;
    127.0.0.0/8;
};


这里的'mynet'是我们自定义的acl,而在bind中有四个内置的acl,它们分别是:

none:没有一个主机
any:任意主机
local:本地
localnet:本机所属IP所在的网络


做好acl之后,就可以借助于acl匹配到的主机地址做基本安全控制了。基本安全控制可由访问控制指令来控制,常用的访问控制指令有:

allow-query {};    //设置允许哪些主机向当前DNS服务器查询(“白名单”)。
allow-transfer {};    //设置允许向哪些主机做区域传送,默认是允许向所有主机做区域传送,应
                      //该配置为仅允许从服务器做区域传送。
allow-recursion {};    //允许哪些主机向当前DNS服务器发起递归请求。
allow-update {};    //配置DDNS时使用,即允许动态更新区域数据库文件中的内容。一般情况下所 
                    //有zone都应该配置为'allow-update { none; };'。


'allow-recursion {};'的应用


如果在公司内有服务器要向互联网上的主机提供服务时,那就需要在公司中搭建DNS服务器。通常会将这个DNS服务器设置为仅允许为公司内部其他主机在访问互联网时做递归查询,而对于互联网上外来的DNS查询请求则分情况处理:①如果外来主机要查询的主机是本地(即公司)所负责管理的服务器,则返回查询结果;②如果外来主机要查询的主机不是本地(即公司)所负责管理的服务器,则拒绝为其做递归查询。


具体做法一般是先用acl归并公司内的所有主机地址,内部主机地址归并的acl名称可自定义为internal,而外部主机地址归并的acl名称可自定义为external,这样的好处是容易识别和记住。假如公司内部主机所在网络为192.168.10.0/24,分别为内部主机和外部主机做acl,具体操作如下:

acl internal { 192.168.10.0/24; };    //针对内部主机的来源IP做acl.
acl external { ! 192.168.10.0/24; any; };    //针对外部主机的来源IP做acl,加上感叹号(!) 
                                              //表示反选的意思。

option {
    ... ...
    allow-recursion { internal; };    //仅允许内部主机向当前DNS服务器发起递归查询请求。
//  recursion yes;    //如果在全局配置段中有这一项就用(//)注释掉。
    ... ...
};



二、DNS view功能的应用


假设有这样一个场景:在我的公司内部有一台DNS服务器(这里暂不做主从),另外还有一台Web服务器,这两台服务器都能向外提供服务。其中DNS服务器有两个接口,分别是192.168.10.140(对内)和10.1.1.140(对外);Web服务器也有两个接口,分别是192.168.10.100(对内)和10.1.1.100(对外)。现在有两台主机想要基于主机名访问公司的Web服务器,这两台主机一部来自公司内部(192.168.10.128),另一部来自互联网上的外部主机(10.1.1.128),它们都向同一台DNS服务器查询。问题是,如何使得公司内部的这部主机(192.168.10.128)查询DNS服务器之后获取到的Web服务器IP地址为192.168.10.100,而外部的主机(10.1.1.128)查询DNS服务器之后获取到的Web服务器IP地址为10.1.1.100呢?


我们不妨假设,内部主机(192.168.10.128)查询DNS服务器之后获取到Web服务器的IP地址是10.1.1.100,这时就需要跨网段访问了,另外,不仅访问时需要进行NAT地址翻转,还会导致访问速度变慢。应该如何解决这一问题?为了准确地根据客户端的不同来源将主机名解析为不同的结果或解析为不同范围内的专用结果,可以使用DNS view(DNS视图)技术。


问题场景图:

wKioL1jiJibBExKMAAPDBZciLeI070.jpg这里实验环境准备三台主机,分别作为上图中的test1, test2, test3,且IP地址分别对应,因为是实验环境,所以这里直接使用网络接口别名来代替其他网络接口。


实验步骤:


(1)为各个主机配置IP地址。


test1:

[root@test1 ~]# ifconfig ens33 192.168.10.140/24
[root@test1 ~]# ifconfig ens33:0 10.1.1.140/24


test2:

[root@test2 ~]# ifconfig ens33 192.168.10.128/24


test3:

[root@test3 ~]# ifconfig ens33:0 10.1.1.128/24



(2)配置test1为DNS服务器。


修改配置文件/etc/named.conf:

[root@test1 ~]# vim /etc/named.conf
# 修改如下内容。

options {
    listen-on port 53 { any; };
    directory   "/var/named";
    allow-query     { any; };
    dnssec-enable no;
    dnssec-validation no;
};



(3)定义acl,分别将192.168.10.0/24和外部网络地址归并为集合。


可在/etc/named.conf或/etc/named.rfc.1912.zones中定义:

[root@test1 ~]# vim /etc/named.conf
# 添加或修改如下内容。

acl internal { 192.168.10.0/24; };    //针对内部主机的来源IP做acl.
acl external { ! 192.168.10.0/24; any; };    //针对外部主机的来源IP做acl.

option {
    ... ...
    allow-recursion { internal; };    //仅允许内部主机向当前DNS服务器发起递归查询请求。
//  recursion yes;    //如果在全局配置段中有这一项就用(//)注释掉。
    ... ...
};

# 对于此处option段中的配置,可以全部注释掉,而在view中用recursion这个子参数直接实现。



(4)定义view,分别匹配公司内部和外部地址,并在view中定义区域。


在配置文件/etc/rfc1912.zones中定义如下内容:

[root@test1 ~]# vim /etc/named.rfc1912.zones

view INTERNAL {                     //定义INTERNAL视图,用于匹配内部网络。
    match-clients { internal; };    //匹配内部网络。
    recursion yes;             //允许为内部主机做递归查询。
    zone "." IN {              //必须包含根域,这样才可以解析其他域(非itab.com)的主机名。
        type hint;
        file "name.ca";
    };
    zone "itab.com" IN {        //针对match-client匹配到的主机定义itab.com正向解析区域。
        type master;
        file "itab.com/internal";    //区域数据库文件路径。
    };
};

view EXTERNAL {                //定义INTERNAL视图,用于匹配内部网络。
    match-clients { any; };    
    //匹配外部网络。DNS是从上往下查找的,如果上面的internal没有匹配到的话,就匹配此处的
    any,因此相当于外部网络。这里也可以使用external来匹配。
    
    recursion no;            //如果外部主机想要解析的主机不属于本地负责的itab.com域,则不
                             //允许为之做递归查询。所以这里可以不需要根域的定义。
    zone "itab.com" IN {     //针对match-client匹配到的主机定义itab.com正向解析区域。
        type master;
        file "itab.com/external";    //区域数据库文件路径。
    };
};

注意:在配置文件/etc/named.conf和/etc/named.rfc1912.zones中的所有zone都必须包含在view中!这里只是实验环境,为了避免占用太多篇幅,所以直接把无关紧要的zone注释掉了。




(5)分别为不同view中(内部和外部)的itab.com这个域的正向区域定义区域数据库文件。


区域所在的VIEW:INTERNAL

[root@test1 itab.com]# vim /var/named/itab.com/internal 

$TTL 3600
$ORIGIN itab.com.
@       IN      SOA     ns1.itab.com.       dnsadmin.itab.com.  (
                2017040301
                1H
                10M
                2H
                1W )
        IN      NS      ns1
        IN      NS      ns2
ns1     IN      A       192.168.10.140
ns2     IN      A       192.168.10.130
www     IN      A       192.168.10.100


区域所在的VIEW:EXTERNAL

[root@test1 itab.com]# vim /var/named/itab.com/external

$TTL 3600
$ORIGIN itab.com.
@       IN      SOA     ns1.itab.com.       dnsadmin.itab.com.  (
                2017040301
                1H
                10M
                2H
                1W )
        IN      NS      ns1
        IN      NS      ns2
ns1     IN      A       10.1.1.140
ns2     IN      A       10.1.1.130
www     IN      A       10.1.1.100



(6)检查语法错误。


检查配置文件是否有语法错误:

[root@test1 itab.com]# named-checkconf 
[root@test1 itab.com]#


检查区域数据库文件是否有语法错误:

[root@test1 itab.com]# vim /var/named/itab.com/internal
[root@test1 itab.com]# named-checkzone itab.com /var/named/itab.com/internal 
zone itab.com/IN: loaded serial 2017040301
OK
[root@test1 itab.com]# vim /var/named/itab.com/external 
[root@test1 itab.com]# named-checkzone itab.com /var/named/itab.com/external 
zone itab.com/IN: loaded serial 2017040301
OK



(6)这一步容易被忘记!要把/var/named/itab.com/目录及其目录下的所有文件的属组设置为root,属组设置为named,否则named进程无法加载定义的区域数据库文件。


为view中定义的区域的目录/var/named/itab.com设置特殊权限:

[root@test1 ~]# mkdir /var/named/itab.com
//因为此时还未加载区域数据库文件,需要自行创建此目录。

[root@test1 ~]# chown root.named /var/named/itab.com
//将该目录属主属组对应改为root和named.

[root@test1 ~]# chmod g+s /var/named/itab.com
//为了确保在该目录下创建的文件的属组为named,可以使用特殊权限SGID.

[root@test1 ~]# ll /var/named/itab.com -d    //查看目录权限。
drwxr-sr-x. 2 root named 38 4月   3 16:16 /var/named/itab.com



(7)重载DNS服务。


[root@test1 ~]# rndc reload



以上为配置test1这台DNS服务器的所有步骤,test1是公司的DNS服务器。现在假如内部主机(test2:192.168.10.128)和外部主机(test3:10.1.1.128)都想要基于主机名www.itab.com访问公司的Web服务器,并且都向公司的test1这台DNS服务器查询www.itab.com的IP地址。在正常情况下,内部主机取得的Web服务器IP地址应该是192.168.10.100,而外部主机取得的Web服务器IP地址应该是10.1.1.100。并且,内部主机可以向公司的DNS服务器(test1)发起递归查询请求,而外部主机则不被允许向公司的DNS服务器(test1)发起递归查询请求。测试过程如下。


在内部主机(test2:192.168.10.128)上

查询公司内Web服务器的IP地址:

[root@test2 ~]# dig -t A www.itab.com @192.168.10.140

;; ANSWER SECTION:
www.itab.com.		3600	IN	A	192.168.10.100    //结果正确!

接下来内部主机就可以访问192.168.10.100这台Web服务器了。


内部主机发起递归请求:

[root@test2 ~]# dig -t A www.baidu.com @192.168.10.140

;; ANSWER SECTION:    //发起递归请求成功!
www.baidu.com.		1200	IN	CNAME	www.a.shifen.com.
www.a.shifen.com.	300	IN	A	14.215.177.37
www.a.shifen.com.	300	IN	A	14.215.177.38



在外部主机(test3:10.1.1.128)上

查询公司的Web服务器的IP地址:

[root@test3 ~]# dig -t A www.itab.com @10.1.1.140

;; ANSWER SECTION:
www.itab.com.		3600	IN	A	10.1.1.100    //结果正确!

接下来外部主机就可以访问10.1.1.100这台Web服务器了。


外部主机发起递归请求:

[root@test3 ~]# dig -t A www.baidu.com @10.1.1.140

; <<>> DiG 9.9.4-RedHat-9.9.4-37.el7 <<>> -t A www.baidu.com @10.1.1.140
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 7980
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available        //发起递归请求失败!

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.baidu.com.			IN	A

;; Query time: 0 msec
;; SERVER: 10.1.1.140#53(10.1.1.140)
;; WHEN: Tue Apr 04 02:54:09 CST 2017
;; MSG SIZE  rcvd: 42

测试完毕,谢谢观看^_^


另外在许多网络游戏上有开设多个游戏区,有电信区、网通区、移动区等。如果用户接入的是电信的光纤,那么进入电信区的游戏速度会更快,这都是DNS VIEW的应用。