跳到主要内容

mysql配合bind9

about bind

Bind(Berkely Internet Name Domain,伯克利Internet域名系统)是DNS协议的一种实现。最初由伯克利大学的研究生编写,但从v8版本后由ISC开发和维护。它提供了一组可重新发布使用的DNS相关组件,包括:域名系统服务器(named)、域名系统解析库、域名系统服务器调试工具.

BIND(Berkeley Internet Name Domain)是现今互联网上最常用的开源DNS服务器软件,据BIND 9第一版发布10年之后,其继任者BIND 10的开发已全面展开。BIND 10将集中于灵活性,安全性,可扩展性。 Internet Systems Consortium (ISC)的BIND 10项目经理Shane Kerr说,BIND 10的一个目标是让用户轻松的定制和扩展。ISC目前负责BIND开发与维护,BIND 10的开发得到了日本注册服务有限公司(JPRS),加拿大互联网注册管理局(CIRA)和.org顶级域名管理机构Afilias等的赞助。BIND 10的完成可能需要五年时间,Kerr称BIND 9是BIND至今最成功的DNS服务器软件,当BIND 10取代BIND 9之时,他们需要确保用户感到满意。

Bind的4个版本如下

  • V4:98年发布,多数unix捆绑的版本,但目前只有OpenBSD在使用。
  • V8:版本。
  • V9:如今使用最多的版本。
  • V10: 最新版。
提示
  • bind9-9.17.1是最后支持--with-dlz-mysql的版本
  • bind9-9.17.2及后续版本,不再支持--with-dlz-mysql

bind的解析数据可以采用如下方式来存储

  • 文件本文件。如zone file,采用该方式时动态更新比较麻烦
  • 各类数据库,如mysql等,采用该方式时动态更新比较方便,但要采用DLZ或SDB等中间件技术和软件。

在网上有很多bind9以mysql为存储后台的贴子,但大数多是采用--with-dlz-mysql,在bind9-9.17.2及后续版本,不再支持--with-dlz-mysql

本文采用bind9-9.19.18为例来讲述如何配置myql.

测试环境

# cat /etc/redhat-release 
CentOS Stream release 9

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:c2:ad:2e brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.3.66/24 brd 192.168.3.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever

# mysql -V
mysql Ver 8.0.26 for Linux on x86_64 (Source distribution)

bind9官方提供的help
https://ftp.isc.org/isc/bind9/9.19.18/doc/arm/html/chapter10.html

准备

To build BIND 9, the following packages must be installed:

  • libcrypto, libssl
    # yum -y install openssl openssl-devel
  • liburcu
    # yum -y install userspace-rcu userspace-rcu-devel
  • libuv
    # yum -y install libuv libuv-devel
  • perl
    # yum -y install perl
  • pkg-config / pkgconfig / pkgconf
    # yum -y install pkg-config pkgconfig pkgconf

同时还需要安装如下包

yum -y install mysql-devel

在centos9的yum中,上述所需的包中,有些没有devel开发包,需要用源代码手工安装. 源码安装时先安装编译器,如:

yum -y install gcc make gcc-c++ cmake
yum -y install autoconf automake libtool

liburcu包

https://ftp.gnu.org/gnu/autoconf
https://ftp.gnu.org/gnu/automake
https://liburcu.org

# yum remove -y userspace-rcu userspace-rcu-devel

# wget https://lttng.org/files/urcu/userspace-rcu-0.14.0.tar.bz2
# tar xvfj userspace-rcu-0.14.0.tar.bz2
# cd userspace-rcu-0.14.0
# ./configure --prefix=/usr/local/rcu
# make
# make install
# cp -fr /usr/local/rcu/lib/pkgconfig/* /usr/lib64/pkgconfig/

libuv包

http://libuv.org/ https://dist.libuv.org/dist/

# yum -y remove libuv
# wget https://dist.libuv.org/dist/v1.47.0/libuv-v1.47.0.tar.gz
# tar zxvf libuv-v1.47.0.tar.gz
# cd libuv-v1.47.0
# sh autogen.sh
# ./configure --prefix=/usr/local/libuv
# make
# make install
# cp /usr/local/libuv/lib/pkgconfig/libuv.pc /usr/lib64/pkgconfig/

libnghttp2包

https://nghttp2.org/ https://github.com/nghttp2/nghttp2/releases

# wget https://github.com/nghttp2/nghttp2/releases/download/v1.58.0/nghttp2-1.58.0.tar.bz2
# tar jxvf nghttp2-1.58.0.tar.bz2
# cd nghttp2-1.58.0
# ./configure --prefix=/usr/local/libnghttp2
# make
# make install
# cp /usr/local/libnghttp2/lib/pkgconfig/libnghttp2.pc /usr/lib64/pkgconfig/

安装

# wget https://ftp.isc.org/isc/bind9/9.19.18/bind-9.19.18.tar.xz
# tar xfv bind-9.19.18.tar.xz
# cd bind-9.19.18
# more README.md # 查看安装说明
# ./configure --help
# ./configure --prefix=/usr/local/bind
# make
# make install
# cd contrib/dlz/modules/mysqldyn/
# make
# cp dlz_mysqldyn_mod.so /usr/local/bind/lib/

# ln -s /usr/local/bind/sbin/rndc /usr/sbin/rndc
# ln -s /usr/local/bind/sbin/named /usr/bin/named
# ln -s /usr/local/bind/sbin/named-checkconf /usr/bin/named-checkconf
# ln -s /usr/local/bind/bin/dig /usr/bin/dig
# ln -s /usr/local/bind/bin/nslookup /usr/bin/nslookup
# ln -s /usr/local/bind/bin/host /usr/bin/host

基本配置

创建配置目录及目录
mkdir -p /usr/local/bind/{etc,var/named/{datas,dynamic,slaves,run}}

rndc配置

/usr/local/bind/sbin/rndc-confgen > /usr/local/bind/etc/rndc.conf
tail -10 /usr/local/bind/etc/rndc.conf | head -9 | sed s/#\ //g > /usr/local/bind/etc/rndc.key

named.ca文件

named.ca是根域的ns记录。
/usr/local/bind/bin/dig @a.root-servers.net . -t ns > /usr/local/bind/etc/named.ca

named.conf文件

内容如下

acl LAN-user {
10.0.0.0/8;
172.16.0.0/12;
192.168.0.0/16;
};

options {
listen-on port 53 { any; }; // listen any interface
//listen-on-v6 port 53 { ::1; };

directory "/usr/local/bind/var/named";
dump-file "/usr/local/bind/var/named/data/cache_dump.db";
statistics-file "/usr/local/bind/var/named/data/named_stats.txt";
memstatistics-file "/usr/local/bind/var/named/data/named_mem_stats.txt";
secroots-file "/usr/local/bind/var/named/data/named.secroots";
recursing-file "/usr/local/bind/var/named/data/named.recursing";

allow-query { localhost; LAN-user; };

recursion yes;

dnssec-validation auto;
managed-keys-directory "/usr/local/bind/var/named/dynamic";

forwarders {
8.8.8.8;
223.6.6.6;
};

pid-file "/usr/local/bind/var/named/run/named.pid";
session-keyfile "/usr/local/bind/var/named/run/session.key";

/* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
channel default_debug {
file "datas/named.run";
severity dynamic;
};
};

include "/usr/local/bind/etc/rndc.key";

// DNS Root
zone "." IN {
type hint;
file "/usr/local/bind/etc/named.ca";
};

自启配置

# touch /usr/lib/systemd/system/named.service
# vi /usr/lib/systemd/system/named.service
[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Before=nss-lookup.target
After=network.target
After=syslog.target
After=mysqld.service


[Service]
Type=forking
PIDFile=/usr/local/bind/var/named/run/named.pid

ExecStart=/bin/sh -c '/usr/local/bind/sbin/named -c /usr/local/bind/etc/named.conf -u root 2>/dev/null'
ExecReload=/bin/sh -c '/usr/local/bind/sbin/rndc -c /usr/local/bind/etc/rndc.conf reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID'
ExecStop=/bin/sh -c '/usr/local/bind/sbin/rndc -c /usr/local/bind/etc/rndc.conf stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'

PrivateTmp=true

[Install]
WantedBy=multi-user.target

# chmod +x /usr/lib/systemd/system/named.service
# systemctl enable named.service
# systemctl start/stop/reload/restart/status named.service

启动 systemctl start named.service

测试

# nslookup www.baidu.com 192.168.3.66
Server: 192.168.3.66
Address: 192.168.3.66#53

Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com.
Name: www.a.shifen.com
Address: 183.2.172.42
Name: www.a.shifen.com
Address: 183.2.172.185
Name: www.a.shifen.com
Address: 240e:ff:e020:9ae:0:ff:b014:8e8b
Name: www.a.shifen.com
Address: 240e:ff:e020:966:0:ff:b042:f296

配置DLZ(Dynamic Loadable Zones)支持

提示

默认已安装mysql,root密码123abc

step1: 产生动态库文件

# cd bind-9.19.18/contrib/dlz/modules/mysqldyn
# make # 产生dlz_mysqldyn_mod.so文件
# cp dlz_mysqldyn_mod.so /usr/local/bind/lib/

step2: 创建初始化数据库

# cat dlz.schema
CREATE DATABASE `BindDB_dyn` DEFAULT CHARACTER SET latin1;
USE `BindDB_dyn`;

CREATE TABLE `ZoneData` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`zone_id` int(11) NOT NULL,
`name` varchar(128) NOT NULL DEFAULT '',
`type` varchar(16) NOT NULL DEFAULT '',
`data` varchar(128) NOT NULL DEFAULT '', /* 若值为域名,则以点(.)为结尾 */
`ttl` int(11) NOT NULL DEFAULT '86400',
PRIMARY KEY (`id`),
KEY `zone_idx` (`zone_id`),
KEY `name_idx` (`zone_id`, `name`),
KEY `type_idx` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `Zones` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`domain` varchar(128) NOT NULL DEFAULT '', /* 域名 */
`host` varchar(128) NOT NULL DEFAULT '', /* 主NS,采用ZoneData表中name档位的值 */
`admin` varchar(128) NOT NULL DEFAULT '', /* 管理员 */
`serial` int(11) NOT NULL DEFAULT '1',
`expire` int(11) NOT NULL DEFAULT '86400',
`refresh` int(11) NOT NULL DEFAULT '86400',
`retry` int(11) NOT NULL DEFAULT '86400',
`minimum` int(11) NOT NULL DEFAULT '86400',
`ttl` int(11) NOT NULL DEFAULT '86400',
`writeable` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `domain_idx` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

# cat dlz.data
use BindDB_dyn;
insert into `Zones`
( `id`, `domain`, `host`, `admin`, `serial`, `expire`,
`refresh`, `retry`, `minimum`, `ttl`, `writeable`) VALUES
(1, 'example.com', '@', 'info', 2014040100, 10800,
7200, 604800, 86400, 86400, 1);

insert into `ZoneData`
(`zone_id`, `name`, `type`, `data`) VALUES
(1, '@', 'NS', 'ns1.example.com.'),
(1, '@', 'NS', 'ns2.example.com.'),
(1, '@', 'MX', '10 mail.example.com.'),
(1, '@', 'A', '192.168.0.2'),
(1, '@', 'TXT', '"v=spf1 ip:192.168.0.3 ~all"'),
(1, 'www', 'CNAME', 'example.com.'),
(1, 'mail', 'A', '192.168.0.3'),
(1, 'ns1', 'A', '192.168.1.111'),
(1, 'ns2', 'A', '192.168.1.222');

导入数据库

mysql --user='root' --password='123abc' < dlz.schema
mysql --user='root' --password='123abc' < dlz.data

step3: named.conf

dlz "test" {
database "dlopen /usr/local/bind/lib/dlz_mysqldyn_mod.so BindDB_dyn localhost root 123abc";
};

重启服务

step4: 测试

# nslookup mail.example.com 192.168.3.66
服务器: UnKnown
Address: 192.168.3.66

名称: mail.example.com
Address: 192.168.0.3

在数据库存中添加记录
insert into ZoneData (zone_id,name,type,data,ttl) values(1,'abc','A','2.2.2.2',86400);

查看数据库

# mysql --user='root' --password='123abc' -e 'use BindDB_dyn;select * from Zones;select * from ZoneData;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+-------------+------+-------+------------+--------+---------+--------+---------+-------+-----------+
| id | domain | host | admin | serial | expire | refresh | retry | minimum | ttl | writeable |
+----+-------------+------+-------+------------+--------+---------+--------+---------+-------+-----------+
| 1 | example.com | @ | info | 2014040100 | 10800 | 7200 | 604800 | 86400 | 86400 | 1 |
+----+-------------+------+-------+------------+--------+---------+--------+---------+-------+-----------+
+----+---------+------+-------+------------------------------+-------+
| id | zone_id | name | type | data | ttl |
+----+---------+------+-------+------------------------------+-------+
| 1 | 1 | @ | NS | ns1.example.com. | 86400 |
| 2 | 1 | @ | NS | ns2.example.com. | 86400 |
| 3 | 1 | @ | MX | 10 mail.example.com. | 86400 |
| 4 | 1 | @ | A | 192.168.0.2 | 86400 |
| 5 | 1 | @ | TXT | "v=spf1 ip:192.168.0.3 ~all" | 86400 |
| 6 | 1 | www | CNAME | example.com. | 86400 |
| 7 | 1 | mail | A | 192.168.0.3 | 86400 |
| 8 | 1 | ns1 | A | 192.168.1.111 | 86400 |
| 9 | 1 | ns2 | A | 192.168.1.222 | 86400 |
| 10 | 1 | abc | A | 2.2.2.2 | 86400 |
+----+---------+------+-------+------------------------------+-------+

查看是否可以解析

# nslookup abc.example.com 192.168.3.66
服务器: UnKnown
Address: 192.168.3.66

名称: abc.example.com
Address: 2.2.2.2

后续

有了数据库支持,后续可以写各类API、webadmin等等。