「BIND9」- DLZ(Dynamically Loadable Zones)

  CREATED BY JENKINSBOT

问题描述

使用 BIND 最不方便的地方在于:每次添加新的解析记录,在修改配置文件后,需要执行命令重新加载。如果可以从数据库动态读取 DNS 记录就完美了;

该笔记将记录:使用 DLZ 的配置,实现从数据库中动态读取 DNS 记录;

解决方案

动态可加载区域(DLZ)是 BIND 9 的补丁,它简化了 BIND 管理,并减少了内存使用和启动时间;

该技术允许将 DNS 记录存储在数据库中,在解析时从数据库中查询 DNS 记录。与使用脚本不同,在数据库中的更改会立即体现在 BIND 对 DNS 查询的响应中,因此无需重新加载或重新启动 BIND 服务,并且不需要在内存中载入及缓存 DNS 记录,因此也减少内存的使用;

注意事项

这是个非常老的项目了,最后一个版本:DLZ-0.7.0,修改时间 2004-04-17(Bind DLZ)。前人在公司内网 DNS 解析中使用了这个技术,又不能轻易替换;

如果正在寻找数据库存储 DNS Record 的解决方案,请慎用(官方文档也存在部分问题),我们已经开始使用 PowerDNS 服务;

服务部署

项目地址:http://bind-dlz.sourceforge.net

安装及部署,可以参考官方的文档:「Examples

通过源码编译

GCC/3.14 Options for Linking
GCC how to add before the default linker search path by default? LIBRARY_PATH not working

只要在编译 BIND 的时候指定了–with-dlz-mysql=yes 选项,即可以支持 MySQL 后端来存储 ZONE 信息;

… /usr/bin/ld: cannot find -lmysqlclien …
1)问题描述:在 CentOS 上编译时,已经安装安装了 MySQL 应用,且 libmysqlclient 也是存在的,但是依旧有这个错误。执行make VERBOSE=1后,发现执行编译命令时,/usr/lib64/mysql并不在 gcc 的库查找路径中;
2)解决方案:在编译时,增加库的搜索路径,即执行命令LIBRARY_PATH=/usr/lib64/mysql make即可。当然可能还有其他办法;

通过包管理器

# 在 CentOS 中的 Bind 是支持 DLZ 的,但是位于 bind-sdb 软件包中
yum install -y bind-sdb

systemctl start bind-sdb

在早期使用 sdb 模块时,我们遇到过内存溢出问题,一直没有解决。后来,我们切换到 PowerDNS 服务;

通过网页后台管理(BLZ WEBUI)

原始项目:https://github.com/1032231418/Bind-Web
其他项目:「php+mysql 构建的 web 管理平台

性能测试

-「附加说明

# 关于官方文档
-「Bind 9.7.0_p1 and DLZ?
文档已经是旧的了。文档中还有错误:示例中使用了’%zone%’、’%record%’ ,但是应该是’$zone$’、’$record$’。不知道哪个版本变了,但是没更新;

# 关于 MySQL Bind 扩展
-「MySQL BIND SDB Driver
这是另外一个扩展,和「DLZ 的 MySQL 驱动」是不同的东西,但提供相同的功能;

# 主机名不能以点结尾
-「[Bind-dlz-testers] IPv6 & AAAA support ?

常见错误

… unsupported DLZ database driver ‘mysql’ …

问题描述:
在 CentOS 7.6 中的 bind 软件包,编译时已经指定了--with-dlz-mysql=yes选项,按理说应该是支持 DLZ 的,但是ldd /usr/sbin/named文件,没有看到libmysqlclient.so库(mysqlclient)的链接。使用 MySQL 驱动时,也输出了标题中的错误;

问题原因:
-「Unsupported Bind9 with mariadb on CentOS 7?
这是一个相同的问题,但是人家最后使用了 LADP 进行记录的存储,我们的目的是相同的,使用数据库之类易于管理的存储来维护记录,而不是使用文件;

-「BIND9 Issue
这篇文章提到了 MySQL 驱动成功加载了,题主安装的是「bind-sdb」包,然后我也安装了 bind-sdb 包,在该包里包含了/usr/sbin/named-sdb命令。在ldd /usr/sbin/named-sdb后,我看到了libmysqlclient.so的链接。紧接着对systemctl start named进行 TAB 补全,发现了named-sdb.service单元文件。这就表示 DLZ 和 SDB 可能是单独编译的二进制文件。在yum info bind-sdb后,描述中提到了对 SDB 和 DLZ 的支持;

安装 bind-sdb 包进行测试。果不其然,原始包 bind 并不支持 DLZ 扩展,而 DLZ 在 bind-sdb 这个包中,启动则是systemctl start named-sdb.service命令

解决办法:

#!/bin/sh

yum install bind-sdb
systemctl start bind-sdb

… ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 52398 …

-「AAAA Filtering
-「filter-aaaa-on-v4 does not filter AAAA if there is no existing A Record with the same FQDN – working as designed?
-「AAAA DNS query on ipv4 interface

问题描述:
对于某个域名,数据库只有 A 记录,没有 AAAA 记录。当进行 AAAA 记录解析时,查询返回 SERVFAIL 状态;

问题原因:
从错误日志看,由于 DLZ 内部的 query.c 中产生了错误;

解决办法:
由于我们目前并没有使用 IPv6 地址,但是应用程序又同时发出了 IPv4 的 A 记录和 IPv6 的 AAAA 记录(这是 IPv4 向 IPv6 过渡期间的一个常见问题);

所以,我们在 DLZ 的数据库中加入了 IPv6 的 AAAA 记录,然后使用 BIND 的filter-aaaa-on-v4选项对 AAAA 查询响应进行过滤调。之所以「在 DLZ 的数据库中加入了 IPv6 的 AAAA 记录」,是因为filter-aaaa-on-v4不会对SERVFAIL的状态进行过滤,所以要先让它正常解析,然后再过滤调;

参考文献

BIND DLZ Home
What is DLZ?
Configure BIND with database backend and DLZ support
CentOS 7 系统下 bind 9.9.4 如何调用 MariaDB/mysql 中的 zone 数据?
Bind-DLZ with MySQL