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等等。