公司内部一直缺少一个管理DNS的平台,故搭建了一个WEB页面,用来管理内部的DNS解析。期间遇到的一些坑,分享一下。

一、BIND-DNS主从模式选择

  • 如果使用web页面来管理DNS,其实BIND-DNS最方便的是主和从都采用数据库作为后端数据存储。主DNS使用主数据库,然后从DNS使用从数据库。然后web页面修改了主数据库后,那么从数据库也会实时同步更新。达到DNS主从同步的目的;
  • 采用以上方法虽然简单,但是一个致命的问题。就是如果使用数据库作为DNS的后端存储,那么DNS的解析速度是远远不如使用文件作为后端数据存储的(对比下图);
  • 综上,故建议主DNS使用数据库存储,然后web页面管理主DNS。而从DNS使用文件存储,每次修改主DNS数据库,自动同步数据到从DNS的文件上,所有的主机使用从DNS作为DNS服务器,达到管理方便和解析快速的双重目的;
  • 一张解析速度对比图:

二、DNS主从同步实时处理

  • 一般来说,DNS主从同时使用相同模式,基本不存在数据不同步的问题。但是如果主从使用不同模式部署,就会出现数据不同步的异常;
  • 采用不同模式,在主DNS修改了数据之后,从DNS是根据设定的refresh值来同步的。如果解析可接受延迟,那么可把refresh值修改的短一点,实现主从同步;
  • 如果接受不了延迟,那么可使用rndc命令手动强制刷新,在修改了主DNS的数据后,强制同步从DNS,示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
# 手动强制refresh记录,不等300s
def record_refresh(domain_name):
DNS_slave_ip = settings.DNS_SLAVE_IP
result_code = []
for slave_ip in DNS_slave_ip:
command = 'rndc -s {} -p 953 -k rndc.key refresh "{}"'.format(slave_ip, domain_name)
result_code.append(subprocess.call(command, shell=True))
for i in range(len(result_code)):
if result_code[i] != 0:
return False
print('refresh success..')

三、serial导致的不同步

  • serial是SOA默认参数,这个参数非常重要,当从DNS需要refresh解析的时候,会先去查下serial 的值是否改变(增加),若serial有增加,则会refresh当前从DNS的解析记录,反之则不进行任何变动;
  • 当你在web页面编辑DNS解析的时候,不管是增加、删除,或者修改,都需要变动serial 的值,每变动一次都需要将数值其增加;

参考: