knotdns

简介

Knot ,High-performance authoritative-only DNS server

BIND VS Knot DNS - compare differences & reviews? (saashub.com)

  1. 一个开源DNS软件
  • The first public release of Knot DNS (0.8) was published in 2011
  1. 号称第3个支持完全RFC标准的DNS服务器(另外2个为: BIND & NSD)

    • more speed, less memory used, better security

    • 由运营 .CZ 顶级域名的团队 CZ.NIC(捷克) 创建,Knot DNS 也为 .CZ TLD 提供支持

  2. 一个高性能的权威 DNS 服务器

    • 3500K的QPS
    • 每秒处理超过 50 万个查询
    • 内存使用量保持在 BIND 9 以下
    • knot 3.0.0开始 支持 高性能XDP (AF_XDP) 模式, 可以显着提高 UDP 响应性能,但是需升级内核到 4.18.x(推荐使用 5.x 内核).
    • Knot 利用 userspace-rcu 库(Linux Kernel Read-Copy-Update (RCU) 用户空间实现版本) 技术消耗更多的内存来加速DNS响应:

授权协议: GPL / 操作系统: Linux / 开发语言: C

Both Knot DNS / Knot Resolver are open source and are completely free to download and use. The source code is available under GPL license.

Knot Resolver 是一个缓存 DNS 解析器,可以加速和保护 Linux 工作站上的 DNS 解析。

日志:dnstap

Catalog Zones:

1
knot DNS has processing of DNS Catalog Zones since Knot DNS Version 3.0.0, which was released on September 9, 2020.

简化的yaml语法:

  1. 如果value包含空格或其他特殊字符,则需要将value放在双引号””中
  2. 注释#
  3. 多个值[]
  4. 可在当前文件的顶层引入其他的配置文件
    • 文件路径可以是相对、绝对路径
    • 文件路径可以使用正则表达式,eg. dir/*.conf
    • include: otherfilepath
1
2
3
4
5
address: [10.0.0.1, 10.0.0.2]


address: 10.0.0.1
address: 10.0.0.2

knot.conf文件

There are 14 fixed sections ,Module sections are prefixed with the mod- prefix (e.g. mod-stats).

module,

server,

key,

acl,

control,

statistics,

database,

keystore,

submission,

policy,

remote,

template,

zone,

log

沟通交流

  1. Knot DNS官网
    http://www.knot-dns.cz/
  2. Issue tracking and source code
    Knot projects / Knot DNS · GitLab (nic.cz)
  3. Mailing list
    knot-dns-users@lists.nic.cz

安装

下载地址:Download – Knot DNS (knot-dns.cz)

安装knot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cd /etc/yum.repos.d/

vim knot.repo
[copr:copr.fedorainfracloud.org:group_cznic:knot-dns-latest]
name=Copr repo for knot-dns-latest owned by @cznic
baseurl=https://download.copr.fedorainfracloud.org/results/@cznic/knot-dns-latest/epel-7-$basearch/
type=rpm-md
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://download.copr.fedorainfracloud.org/results/@cznic/knot-dns-latest/pubkey.gpg
repo_gpgcheck=0
enabled=1
enabled_metadata=1

yum list knot-*

repotrack knot knot-utils knot-resolver -p /data/knot
(yum install knot knot-utils knot-resolver -y)

rpm -Uvh --force --nodeps *.rpm

knot-utils——kdig等

1
kdig +short @localhost . NS

knotdns下载地址

Index of /results/@cznic/knot-dns-latest/ (copr-be.cloud.fedoraproject.org)

源码安装

下载地址:Download – Knot DNS (knot-dns.cz)

选择SourceCode Tarball

1
2
3
4
5
6
tar -xvf knot-3.0.8.tar.xz
configure
make
make install

#可能需要一些其他的依赖

centos7在线安装

1
yum install knot

基础配置

1
2
3
knotd -v #查看版本号

systemctl enable knot # 开机启动

master配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#备份默认配置
cat /etc/knot/knot.conf
cp /etc/knot/knot.conf /etc/knot/knot.conf-default

#去编辑配置文件
vim /etc/knot/knot.conf

#手动生成域名zone文件
vim /var/lib/knot/run.com.zone
chown knot:knot run.com.zone
chmod 640 run.com.zone
#chown root:knot run.com.zone
kzonecheck /var/lib/knot/run.com.zone

systemctl restart knot
systemctl status knot

kdig @127.0.0.1 dns1.run.com -p 58
kdig @10.154.5.163 dns1.run.com -p 58
kdig dns1.run.com -p 58 #不可执行。。。

Knot 配置文件 /etc/knot/knot.conf 使用简化的 YAML 格式。缩进4个空格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# This is a sample of a minimal configuration file for Knot DNS.
# See knot.conf(5) or refer to the server documentation.

server:
rundir: "/run/knot"
user: knot:knot #安装Knot时自动创建了用户knot
listen: [ 127.0.0.1@53, ::1@53 ]

# TSIG,keygen 生成
key:
- id: tsigkey1.
algorithm: hmac-sha256
secret: base64-keyvalue

log:
- target: syslog # syslog,stdout,stderr 或 文件名
any: info


#log:
# - target: stdout
# any: debug

database:
storage: "/var/lib/knot"

# authorized slaves ,定义备机
#请注意,master接受多个remote列表。第一个remote具有最高优先级,其他remote用于故障转移。当服务器从列出的远程接收区域update通知时,该远程将是后续传输的首选。
remote:
- id: slave1
address: 192.168.1.1@53
key: tsigkey1.
- id: slave2
address: 192.168.2.1@53
key: tsigkey1.

# the server's access control lists (ACLs),若无ACL规则,则zone的所有行为都被拒绝
# 如果一个zone配置了多个acl,以第一个acl优先级最高
acl:
- id: acl_axfr
action: transfer #用于接收来自slave的 AXFR 请求
key: tsigkey1. #Access based just on TSIG key
- id: acl_upme
address: 127.0.0.0/24
action: update #促进源自本地主机的 nsupdate 请求
key: tsigkey1.
- id: acl_primary
address: [ 127.0.0.0/24, 172.28.1.20 ]
action: [transfer, notify]
- id: deny_rule
address: 192.168.2.100
action: transfer #no action specified and deny on implies denial of all actions
deny: on
- id: owner_type_rule
action: update
update-type: [A, AAAA, MX] # Updates are only allowed to update records of the specified types
update-owner: name # The allowed owners are specified by the list on the next line
update-owner-name: [a, b.example.com.] # Non-FQDN names are relative to the effective zone name
update-owner-match: equal # The owners of records in an update must be exactly equal to the names in the list



#可以添加多个模板。模板必须存在于 knot.conf 中,否则Knot启动时报错。
template:
- id: default
storage: "/var/lib/knot"
file: "%s.zone"
- id: slave
storage: "/var/lib/knot/slave"

zone:
# # Primary zone
- domain: example.com
file: "cpu-chow-local.zone" #可以没有file,若有,不允许是路径(template提供路径)
notify: slave1
acl: acl_axfr
acl: acl_upme
# template: template-id #可以手动指定template
semantic-checks: on #语义检查,对zone文件进行额外的语法检查
disable-any: on #a -t ANY query to prevent DNS zone-reflection attacks
serial-policy: increment #确保动态更新将触发zone的序列号增量。

# # Secondary zone
# - domain: example.net
# master: primary
# acl: acl_primary
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# Configuration export (Knot DNS 3.0.8)

server:
rundir: "/run/knot"
user: "knot:knot"
listen: [ "127.0.0.1@53", "100.71.9.148@53", "100.73.9.148@53" ]
tcp-workers: 100
background-workers: 100
udp-workers: 100
log:
- target: "syslog"
any: "info"

database:
storage: "/var/lib/knot/confdb"

mod-stats:
- id: custom
request-protocol: on
server-operation: on
request-bytes: off
response-bytes: off
# edns-presence: on
# flag-presence: on
response-code: on
# request-edns-option: on
# response-edns-option: on
reply-nodata: on
query-type: on
# query-size: on
# reply-size: on

statistics:
timer: 1
file: "/var/lib/knot/stats.yaml"
append: on

template:
- id: "default"
storage: "/var/lib/knot"
file: "%s.zone"
global-module: mod-stats/custom

zone:
- domain: "yx1.com."

- domain: "example.com."

- domain: "mascotdokky.com."

slave配置

第二个 Knot 实例,需要创建第二个运行目录和存储位置。

利用/usr/sbin/knotc来启动运行指定配置文件的实例

1
2
3
4
5
6
7
/usr/sbin/knotc -c config-file [ command ]
/usr/sbin/knotc -c /etc/knot/slave.conf
/usr/sbin/knotd -c /etc/knot/knot.conf

#启动、停服
knotd -d -c /etc/knot/knot.conf
knotc -c knot.conf stop
1
2
3
mkdir -p /run/snot /var/lib/snot
chown knot:knot /run/snot /var/lib/snot
chmod 755 /run/snot /var/lib/snot
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
vim /etc/knot/slave.conf

server:
listen: slaveIp@53
user: knot:knot
rundir: /run/snot

key:
- id: tsigkey1.
algorithm: hmac-sha256
secret: base64-keyvalue

template:
- id: default
storage: /var/lib/snot

#slave必须设置。
remote:
- id: master1 #自定义
address: 127.0.0.9@53
key: tsigkey1.

acl:
- id: notify_from_master
address: 主机ip
action: notify #
key: tsigkey1.

log:
- target: stdout
any: debug

zone:
- domain: example.com
master: master1 #masterId
acl: notify_from_master

日志

1
tail -f /var/log/syslog

###

GeoIP

您想为世界各地的许多客户提供您的网站 www.example.com。您可以将站点数据存储在单个服务器上,供所有客户端访问。或者,您可能将站点的多个副本存储在世界各地的多个数据服务器上。

当客户端请求服务器的 IP 地址时,选择离客户端最近的服务器,从而节省路由时间并最大程度地减少延迟不是很好吗?

BIND、PowerDNS 和 Knot DNS等DNS 服务器中的 GeoIP,就是一种可以做到这一点的机制。

Knot DNS的GeoIP模块

两种不同的运行模式:

  1. subnet模式:在子网模式下,根据client源地址是属于 IPv4 还是 IPv6 地址的特定子网来选择适当的响应。不需要任何外部数据库,使用较为简单。
  2. geodb模式:在 geodb 模式下,根据client地址关联的地理数据进行响应,这些数据是从一个 MaxMind 格式的外部 GeoIP 数据库中检索的,例如 GeoIP2 或免费的 GeoLite2。根据数据库,或模块的配置情况,响应的选择可以考虑客户的大陆、经济、城市、自治系统编号 (ASN)、互联网服务提供商 (ISP) 等因素。

GeoIP模块支持DNSSEC。

实验

  1. 为了测试geodb模式,需要下载解压免费的GeoLite2 City数据库。

  2. vim example.com.zone

1
2
3
4
5
6
7
8
9
10
11
12
13
$ORIGIN example.com.
$TTL 3600
@ SOA dns1.example.com. hostmaster.example.com. (
2010111213 ; serial
6h ; refresh
1h ; retry
1w ; expire
1d ) ; minimum

NS dns1
dns1 A 192.0.2.1
www A 203.0.113.50
TXT "default server"
  1. 配置文件
graph TB
A(配置文件) --主配置-->B(/etc/knot/knot.conf)
A --subnet mode--> C(net.conf)
A --geodb mode--> D(geo.conf)
knot.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server:
listen: 127.0.0.1@53
edns-client-subnet: on #启用 EDNS 客户端子网选项

# 子网模式
mod-geoip:
- id: net
config-file: "/path/to/net.conf"
mode: subnet

# geodb模式
mod-geoip:
- id: geo
config-file: "/path/to/geo.conf"
mode: geodb
geodb-file: "/path/to/GeoLite2-City.mmdb"
geodb-key: [country/iso_code, city/names/en] #specifies a list of database keys,据此返回合适的response。Here we use the client’s economy referred to by its ISO code, and if available, their city specified by its name in English (note that the order in which the keys are given is important).

zone:
- domain: example.com.
file: "/path/to/example.com.zone"
module: mod-geoip/net
module: mod-geoip/geo
net.conf
1
2
3
4
5
www.example.com: 
- net: 192.0.2.0/24
A: 192.0.2.50
- net: 198.51.100.0/24
A: 198.51.100.50

如果客户端从 192.0.2.0-192.0.2.255 范围内的地址查询域 www.example.com 的 A 记录,Knot 将响应 192.0.2.50,类似地使用第二个选项。如果客户端从其他地址发送查询,将收到来自 example.com 区域的默认的A记录返回值。

geo.conf
1
2
3
4
5
6
7
8
9
10
www.example.com: 
- geo: "CZ;Prague"
A: 192.0.2.0
TXT: "Prague"
- geo: "CZ;Brno"
A: 192.0.2.1
TXT: "Brno"
- geo: "CZ;*"
A: 192.0.2.2
TXT: "Czechia"

如果客户从Prague或Brno查询,将要返回指定的 A 和 TXT 记录。如果客户在捷克共和国CZ上述两个城市之外的地方进行查询,则适用第三个选项。 * 代表“任何城市”。最后,如果客户端从其他地方查询,则返回区域中的默认记录。

启动项目:

1
2
3
systemctl start knot

knotd -c /etc/knot/knot.conf

子网模式示例

1
2
3
4
5
kdig @127.0.0.1 A www.example.com +subnet=192.0.2.66

#得到192.0.2.50

#+subnet:specify different source addresses and

geodb模式示例

1
2
3
kdig @127.0.0.1 TXT www.example.com +subnet=88.146.42.14

#得到Brno

Knot Resolver

DNS 缓存解析器(caching DNS resolver),可以帮助加速、保证安全的DNS解析。

1
kresd -h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#默认监察localhost:53端口(通过kresd.conf修改ip:port),且一核cpu
systemctl start kresd@1.service #single instance of kresd, responding on localhost
systemctl status kresd@1.service

#开启及重启(reboot后启动)
systemctl enable --now kresd@1.service

#使用手册
man kresd.systemd

#多核cpu-start和enable
#如果您希望 kresd 在共享cache和sockets的同时利用所有可用内核的优势,您应该启用和启动与内核数量一样多的 kresd@.service 实例。
#通常,每个实例都只是命名为 kresd@N.service,其中 N 是十进制数。例如,启用和启动 3 个并发守护进程
systemctl start kresd@1.service kresd@2.service kresd@3.service
systemctl enable --now kresd@1.service kresd@2.service kresd@3.service
#或者,bash {}批量start / enable
systemctl enable --now kresd@{1..4}.service

#或者批量start所有的enabled kresd daemons
systemctl start kresd.target

#The systemd-managed kresd service set is grouped in the system-kresd.slice slice. The slice includes all running daemons (instances of kresd@.service).

#多核restart (这个glob表达式不能用在start或enable上)
systemctl restart 'kresd@*'


#systemd 管理的 kresd 服务集合 利用 system-kresd.slice 切片进行分组
#该切片包括所有正在运行的守护进程(kresd@.service 的实例)。

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
vim /etc/knot-resolver/kresd.conf

#示例文件/usr/share/doc/knot-resolver-5.3.2/examples/

-- SPDX-License-Identifier: CC0-1.0
-- vim:syntax=lua:set ts=4 sw=4:
-- Refer to manual: https://knot-resolver.readthedocs.org/en/stable/

-- Network interface configuration
net.listen('127.0.0.1', 58, { kind = 'dns' })
net.listen('127.0.0.1', 853, { kind = 'tls' })
--net.listen('127.0.0.1', 443, { kind = 'doh2' })
--net.listen('::1', 58, { kind = 'dns', freebind = true })
--net.listen('::1', 853, { kind = 'tls', freebind = true })
--net.listen('::1', 443, { kind = 'doh2' })

-- Load useful modules
modules = {
'hints > iterate', -- Load /etc/hosts and allow custom root hints
'stats', -- Track internal statistics
'predict', -- Prefetch expiring/frequent records
}

-- Cache size
cache.size = 100 * MB

#####

两种DNS加密协议:

DoT:DNS-over-TLS, TCP port 853

DoH:DNS-over-HTTPS

1
2
3
net.listen('192.0.2.1') # 53port,udp,unencrypted DNS queries
net.listen('2001:db8::1')
net.listen(net.eth0, 853, { kind = 'tls' })

区域传输

1
2
3
4
5
6
[root@fnc05 knot]# keymgr -t key_knsupdate
# hmac-sha256:key_knsupdate:LNL9O44NLCGmSkvUH6IIF/7lljBpB2j0kkkbdB33xhA=
key:
- id: key_knsupdate
algorithm: hmac-sha256
secret: LNL9O44NLCGmSkvUH6IIF/7lljBpB2j0kkkbdB33xhA=

动态更新

动态更新是临时的(until the server stop)!!!

要想持久化,必须使用指定的配置database或者初始化默认database。

1
knotc conf-init

Knot DNS 使用zone parser( Ragel 编写)来实现启动时快速加载zones。

knotc

Knot DNS 使用“knotc”来动态的更改配置文件并重新加载服务器,以达到动态添加和删除区域的目的。

conf配置文件操作

1
2
3
knotc conf-init
knotc conf-import /etc/knot/knot.conf (-f 会强制覆盖既有data.mdb。 从conf导出到data.mdb)
knotc conf-export output.conf (从data.mdb导出到output.conf)
1
2
3
4
5
6
7
8
9
systemctl stop knotc

knotc conf-import /etc/knot/knot.conf (-f)

#生成了/var/lib/knot/confdb

chown knot:knot /var/lib/knot/confdb -R

systemctl start knotc

这个配置数据库mdb,无法打开。

利用mdbtools工具:mdb-tables data.mdb 报错 File does not appear to be an Access database

利用windows的excel和access都打开失败。

目前只能: knotc conf-import conf =》 data.mdb

然后要看的时候,再从data.mdb =》 conf文件,进行查阅

conf操作

对conf文件的操作

1
2
3
knotc conf-init # 初始化,生成目录文件/var/lib/knot/confdb/data.mdb和/var/lib/knot/confdb/lock.mdb
knotc conf-import knont.conf # con => db
knotc conf-export knont.conf # db => conf,得到knont.conf文件
zone操作
动态增加want.com示例
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@fnc05 knot]# knotc conf-begin
OK
[root@fnc05 knot]# knotc conf-set 'zone[want.com]'
OK
[root@fnc05 knot]# knotc conf-diff
+zone.domain = want.com.
[root@fnc05 knot]# knotc conf-commit
OK
[root@fnc05 knot]# knotc conf-read 'zone.domain'
zone.domain = lu.org.
zone.domain = run.com.
zone.domain = want.com.
zone.domain = example.com.
1
2
3
4
5
6
7
8
9
10
knotc conf-set 'zone[catalog.default].catalog-role' 'interpret'
knotc conf-set 'zone[catalog.default].catalog-template' 'default'

zone:
- domain: "catalog.default."
notify: "slave"
acl: [ "acl_update", "acl_slave" ]
semantic-checks: "on"
catalog-role: "interpret"
catalog-template: "default"
动态删除want.com示例
1
2
3
4
5
6
7
8
9
10
11
12
[root@fnc05 knot]# knotc conf-begin
OK
[root@fnc05 knot]# knotc conf-unset 'zone[want.com]'
OK
[root@fnc05 knot]# knotc conf-diff
-zone.domain = want.com.
[root@fnc05 knot]# knotc conf-commit
OK
[root@fnc05 knot]# knotc conf-read 'zone.domain'
zone.domain = lu.org.
zone.domain = run.com.
zone.domain = example.com.
安全增删zone

安全修改zone文件的方法是首先冻结zone events)

1
2
3
4
5
6
7
knotc -b zone-freeze example.com.
knotc -b zone-flush example.com. #刷新zone文件,对zone调用freeze后,可能还有zone操作(例如signing)在运行,导致冻结挂起。因此,使用阻塞模式来确保操作完成。然后可以将该zone刷新到文件中。

vim example.com.zone #修改文件

knotc -b zone-reload example.com. #load被修改的zone
knotc zone-thaw example.com. #解冻
zone文件-增删解析记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
knotc conf-begin
knotc conf-set 'zone[yun.com]'
knotc conf-diff
knotc conf-commit
knotc conf-read 'zone.domain'

vim /var/lib/knot/want.com.zone或者动态添加zone——
#真正产生zone文件
knotc zone-begin yun.com
knotc zone-set yun.com @ 7200 SOA ns1 grover.yun.com. 1 86400 900 691200 3600
knotc zone-set yun.com @ 3600 NS ns1
knotc zone-set yun.com ns1 3600 A 1.1.1.2
knotc zone-set yun.com @ 3600 A 1.1.1.3
knotc zone-set yun.com www 3600 A 1.1.1.4
knotc zone-diff yun.com
knotc zone-commit yun.com

knotc zone-abort yun.com #终止


kdig @127.0.0.1 www.yun.com -p 58 +short
kdig @127.0.0.1 www.yx1.com -p 58 +short
cd /var/lib/knot
1
2
3
4
5
6
7
8
9
10
11
#校验
knotc zone-check example.com

#获取每个zone文件的SOA情况
knotc zone-read -- @ SOA

knotc zone-read --
knotc zone-read example.com
knotc zone-read example.com ns1
knotc zone-read example.com ns1 NS
knotc zone-read example.com dns1 A
修改解析记录

增加2条新记录

1
2
3
4
5
6
7
8
9
10
11
$ knsupdate
> server 192.168.1.1
> zone example.com.
> origin example.com.
> ttl 3600
> add test1.example.com. 7200 A 192.168.2.2
> add test2 TXT "hello"
> show
> send
> answer
> quit

虽然可以动态更改大多数配置参数或通过配置文件重新加载,但部分服务器中的一些参数需要重新启动服务器,以便更改生效。这些参数是:rundir、user、pidfile、tcp-reuseport、udp-workers、tcp-workers、background-workers 和 listen。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#获取当前服务配置
knotc conf-read server

#重载所有配置
knotc reload

#获取当zones列表
knotc conf-read zone.domain


#获取 lu.com 区域的master
knotc conf-read 'zone[lu.com].master'

#动态添加zone
knotc conf-begin #开始

knotc conf-set 'zone[lu.org]'
knotc conf-set 'zone[lu.org].file' '/var/zones/example.org.zone'
knotc conf-set 'server.identity' 'Knot DNS'
knotc conf-set 'server.listen' '0.0.0.0@53' '::@53'
knotc conf-set 'zone[example.com]'
knotc conf-set 'zone.slave' 'slave2'

#取消配置
$ knotc conf-unset
$ knotc conf-unset 'zone'
$ knotc conf-unset 'zone[example.com]'
$ knotc conf-unset 'zone[example.com].master'
$ knotc conf-unset 'zone[example.com].master' 'remote2' 'remote5'

knotc conf-commit #结束
knotc conf-abort #放弃

主从同步

draft-ietf-dnsop-dns-catalog-zones-02 - DNS Catalog Zones

kcatalogprint utility is provided to manage the catalog.

1
warning: [yun.com.] notify, outgoing, remote 10.154.5.162@58, server responded with error 'NOTAUTH'

性能测试

如何选择最佳(和最快)备用DNS服务器 - 如何 - 2021 (omatomeloanhikaku.com)

压力测试简介 (zhangyu.guru)

windows GRC’s | DNS Nameserver Performance Benchmark

  1. 缓存的查询–返回解析器名称缓存中已经存在的域名的时间。
  2. 未缓存的查询–返回尚未在解析器的名称缓存中的子域名的时间。
  3. Dotcom查找–为域名服务商咨询域名服务器选择的dotcom解析器的时间。

image-20210802113606027

并发用户数、响应时间、系统吞吐量间的关系。

负载的执行时间、传输速度、吞吐量、资源占用率

QPS(TPS)= 并发数/平均响应时间 或者 并发数 = QPS*平均响应时间

  • 首先需要明确系统的关键指标, 如:

    • DNS服务每秒可以响应20W个查询请求
    • 95%的查询请求响应时间在5ms以内
    • 当请求量达到25W每秒时,其中的20W请求能正确处理,响应时间波动在5%以内

    其次需要明确资源限制,如:

    • 硬件:如网口速率,CPU核心数,内存大小,是否SSD,交换机速率等
    • OS:如内核版本,是否支持zero copy,是否支持bbr等
    • 应用软件:如asyncio,coroutine,GIL,是否采用DPDK等

    接下来就需要定义压测的场景,如:

    • A类内部DNS请求场景
    • A类转发外部DNS请求场景
    • AAAA类内部DNS请求场景
  1. 基准测试:许多DNS提供商都专注于速度,只有运行基准测试才能告诉您哪种方法最适合您。
  1. 后端性能测试(Back-end Performance Test)
    1. 性能测试工具模拟大量的并发用户请求,然后获取系统性能的各项指标
    2. 并发用户数、响应时间和系统吞吐量外,还包括各类资源的使用率,比如系统级别的CPU占用率、内存使用率、磁盘I/O和网络I/O等,再比如应用级别以及JVM级别的各类资源使用率指标等。
    3. 模拟的并发用户数,通常在「几百」到「几百万」的数量级,所以选择的性能测试工具,一定不是基于GUI的,而是要采用基于协议的模拟方式,也就是去模拟用户在GUI操作的过程中实际向后端服务发起的请求。
  2. 前端性能测试(Front-end Performance Test)
  3. 代码级性能测试(Code-level Performance Test)
  4. 压力测试(Load/Stress Test)
    1. 一般采用后端性能测试的方法,不断对系统施加压力,并验证系统化处于或长期处于临界饱和阶段的稳定性以及性能指标,并试图找到系统处于临界状态时的主要瓶颈点。所以,压力测试往往被用于系统容量规划的测试。
  5. 配置测试(Configuration Test)
    1. 通过性能基准测试(Performance Benchmark)建立性能基线(Performance Baseline)
    2. 在此基础上,调整配置
    3. 基于同样的性能基准测试,观察不同配置条件下系统性能的差异,根本目的是要找到特定压力模式下的最佳配置。
      1. 宿主操作系统的配置;
      2. 应用服务器的配置
      3. 数据库的配置
      4. JVM的配置
      5. 网络环境的配置
  6. 并发测试(Concurrence Test)
  7. 以及可靠性测试(Reliability Test)

600万qps

2s

生成queries.txt文件

1
cat want.com.zone  | awk "{print \$1,\$3}" | grep -E "(NS|DS|A|AAAA|PTR|MX|SOA)$" | sort -u -R > queries.txt

dnsperf测试

1
2
dnsperf -c 1000 -d ./queries.txt -p 58 -s 10.144.85.96
dnsperf -c 1000 -d ./130w.txt -p 58 -s 10.154.5.163
1
2
3
4
5
6
7
8
9
10
11
12
13
-s     用来指定DNS服务器的IP地址,默认值是127.0.0.1
-p 用来指定DNS服务器的端口,默认值是53
-d 用来指定DNS消息的内容文件,该文件中包含要探测的域名和资源记录类型,见下文
-t 用来指定每个请求的超时时间,默认值是3000ms
-Q 用来指定本次压测的最大请求数,默认值是1000 (-q: 请求多少次)
-c 用来指定并发探测数,默认值是100. dnsperf会从-d指定的文件中随机选取100个座位探测域名来发送DNS请求.
-l 用来指定本次压测的时间,默认值是无穷大。
-e 本选项通过EDNS0,在OPT资源记录中运用edns-client-subnet来指定真实的client ip.

-P 指定用哪个传输层协议发送DNS请求,udp或者tcp。默认值是udp
-f 指定用什么地址类型发送DNS请求,inet或者inet6。默认值是inet
-v 除了标准的输出外,还输出每个相应码的个数。
-h 打印帮助
1
2
3
4
5
6
7
8
9

- domain: "yx1.com."

- domain: "want.com."

www.yx1.com A
www.example.com A
host1.example.com A
www.mascotdokky.com A

kxdpgun Linux kernel 4.18+ is required.

kxdpgun – DNS benchmarking tool — Knot DNS 3.1.0 documentation (knot-dns.cz)

1
kxdpgun -t 120 -Q 6000000 -i ./queries.txt -b 5 -r -p 58 10.144.85.96

the famous Winston Churchill’s quote may have come to your mind: “I only believe in statistics that I doctored myself

通过具有10GbE网络连接的UDP每秒的峰值响应数超过50万。

We discovered one important thing while benchmarking DNS: the network card chipset can make a huge difference. As a rule of thumb, the Intel server NIC chipsets are never a bad choice.

网络芯片,导致巨大的差异。根据经验,英特尔服务器NIC芯片组从来都不是一个坏的选择。

Files · master · Knot projects / dns-benchmarking · GitLab (nic.cz)

PF_RING

提高数据包捕获速度。高速数据包捕获库,通过它可以实现将通用 PC 计算机变成一个有效且便宜的网络测量工具箱,进行数据包和现网流量的分析和操作。

现状:CPU的多数时间都被用在把网卡接收到的数据包经过内核的数据结构队列发送到用户空间的过程中。也就是说是从网卡–>内核, 再从内核–>用户空间,这两个步骤,花去了大量CPU时间,从而导致没有其他时间用来进行数据包的进一步处理。在传输过程中sk_buff结构的多次拷贝,以及涉及用户空间和内核空间的反复系统调用极大的限制了接收报文的效率,尤其是对小报文的接收影响更为明显。

PF_RING提出的核心解决方案便是减少报文在传输过程中的拷贝次数。

robdns using PF_RING seems to be able to deliver about 1 million packets per second per core.

使用 PF_RING 的 robdns 似乎能够每秒每核传输大约 100 万个数据包。

查看网卡带宽

1
2
3
4
5
ifconfig
ethtool eth0
ethtool bond1

#Speed: 1000Mb/s

查看内存RAM

1
2
3
free -h

#376G

查看CPU

1
lscpu
Performance Tuning
  1. UDP workers:handle all network requests coming through UDP protocol
  2. TCP workers
  3. Background workers:used to execute background operations (zone loading, zone updates, etc.)

默认,Knot通过CPU核数来确定各个workers种类的合适数量(well-fitting)。

用户可以自定义每个workers 数量,通过配置 configuration/server section: udp-workers, tcp-workers, background-workers.

当服务器落后于预期性能而 CPU 使用率低时,增加工作线程数:用户应该尝试将(相关类型的)worker 的数量稍微增加到 100 以上,如果性能变得更好,他可以决定进一步的精确设置。

工具:dnsperf

自变量:the number of threads/processes

因变量:queries per second

多次迭代获取比较稳定的结果

运行操作系统:Linux 4.19.25-200.1.el7.bclinux.x86_64

knotd (Knot DNS), version 3.0.8

number of threads qps
1
2
3

image-20210805110115421

工具:pcap/tcpreplay based (Benchmark | YADIFA

自变量:qps(queries per second)(每秒查询量)

因变量:percentage of lost queries (丢失查询的百分比)

image-20210805110820737

Sender

  • Server: HP ProLiant DL160 G5
  • CPU: 2x Quad core (Intel(R) Xeon(R) CPU E5405 @ 2.00GHz)
  • Memory: 4x 4GiB DDR2 (FB-DIMM DDR2 FB-DIMM Synchronous 667 MHz (1.5 ns))
  • NIC: Broadcom Corporation NetXtreme BCM5722 Gigabit Ethernet PCI Express
  • OS: Ubuntu 12.04 kernel 3.2.0 (minimal server install)

Receiver

  • Server: Supermicro X8DTU
  • CPU: 2x Quad core HT enabled (Intel(R) Xeon(R) CPU L5630 @ 2.13GHz)
  • Memory: 6x 8GiB (DIMM DDR-3-1333 1066 MHz (0.9 ns))
  • NIC: Intel Corporation 82576 Gigabit Network Connection
  • OS: Ubuntu 12.04 minimal server install or FreeBSD 8.2
  1. 创建具有6 00万个UDP DNS查询报文的单个PCAP文件。
  2. 在客户端上使用tcpreplay,以预置速率发送一些包 packets 到服务器上
  3. 回复率 = 10万qps * 80%的回复率 = 8万aps(answers per second)

措施

  1. 应尽量增加worker(相关类型的)的数量略高于100%,如果性能有所提升,再具体设置更细的具体数量。
  2. 升级,使用kxdpgun 发包

10Gb 以太网是主要瓶颈

1
2
3
4
5
6
7
8
9
10
11
[root@fnc13 bak]# lspci | grep -i 'eth'
06:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
06:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
16:00.0 Ethernet controller: Broadcom Inc. and subsidiaries NetXtreme BCM5719 Gigabit Ethernet PCIe (rev 01)
16:00.1 Ethernet controller: Broadcom Inc. and subsidiaries NetXtreme BCM5719 Gigabit Ethernet PCIe (rev 01)
16:00.2 Ethernet controller: Broadcom Inc. and subsidiaries NetXtreme BCM5719 Gigabit Ethernet PCIe (rev 01)
16:00.3 Ethernet controller: Broadcom Inc. and subsidiaries NetXtreme BCM5719 Gigabit Ethernet PCIe (rev 01)
81:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
81:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

扩展10G口,82599ES网卡

网卡队列数64——是否48个队列最好?The number of nameserver threads/processes was set to 128

1
2
3
ethtool -S ens5f0
ethtool -S ens4f0
队列数64
Sysctl 和 NIC (网卡)优化

如果您的 NIC 驱动程序允许(请参阅 /proc/interrupts ),请手动设置 CPU (/proc/irq/$IRQ/smp_affinity),以便每个 NIC 通道由唯一的 CPU 内核提供服务。您必须先关闭 irqbalance 服务以避免配置覆盖。

Configure sysctl:

/etc/sysctl.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
socket_bufsize=1048576
busy_latency=0
backlog=40000
optmem_max=20480

net.core.wmem_max = $socket_bufsize #发送窗口的最大大小
net.core.wmem_default = $socket_bufsize #每一个TCP socket默认的用于TCP发送数据的缓存大小,字节
net.core.rmem_max = $socket_bufsize #每一个TCP socket最大的接收数据缓的最大存
net.core.rmem_default = $socket_bufsize
net.core.busy_read = $busy_latency
net.core.busy_poll = $busy_latency
net.core.netdev_max_backlog = $backlog
net.core.optmem_max = $optmem_max

Disable huge pages.

Configure your CPU to “performance” mode. This can be achieved depending on architecture, e.g. in BIOS, or e.g. configuring /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor to “performance”.

Tune your NIC device with ethtool:

网卡修改参数

1
2
3
4
5
6
7
ethtool -A $dev autoneg off rx off tx off #自协商传输模式关闭
ethtool -K $dev tso off gro off ufo off
ethtool -G $dev rx 4096 tx 4096
ethtool -C $dev rx-usecs 75
ethtool -C $dev tx-usecs 75
ethtool -N $dev rx-flow-hash udp4 sdfn
ethtool -N $dev rx-flow-hash udp6 sdfn
DNS Shotgun

https://gitlab.labs.nic.cz/knot/shotgun

https://ripe79.ripe.net/programme/meeting-plan/dns-wg/

  1. 模拟真实的DNS基准Realistic DNS benchmarking
  2. 新的工具集

DNS Shotgun操作步骤:

第1阶段:数据准备

第2阶段:流量回复

第3阶段:绘制漂亮图表

「测试」 - 性能 & 性能测试基本方法 - 未完成 - 知乎 (zhihu.com)

knot_exporter

rpm -ivh libffi-devel-3.0.13-19.el7.x86_64.rpm

cd Python-3.6.4/

make && make install

pip3 install psutil -i http://pypi.douban.com/simple/ –trusted-host pypi.douban.com

python3 -m pip install –upgrade –force pip

python3 -m pip install –upgrade –force pip -i http://pypi.douban.com/simple/ –trusted-host pypi.douban.com

pip3 install libknot -i http://pypi.douban.com/simple/ –trusted-host pypi.douban.com

pip3 install prometheus_client -i http://pypi.douban.com/simple/ –trusted-host pypi.douban.com

./knot_exporter –knot-library-path /usr/lib64/libknot.so.11 –web-listen-addr 100.71.9.148

日志

1
kjournalprint -l 5 /var/lib/knot/journal groverchou.com

响应限速

1
2
rate-limit 100; # 限制响应100qps以内
rate-limit-slip 2;

Jan-Piet Mens :: Knot-DNS: Dynamic Updates and a bit of RRL (jpmens.net)

tcpreplay

tcpreplay 用于重放 UDP 流量、速率、 数据包总量。

在高速率下 tcpreplay 不会 有足够的分辨率来每秒输出请求的数据包,这会导致 X 轴上的条带。相信这对实验影响不大 虽然无法测试中间利率

抓包

准备一个 pcap 文件 (UDP IPv4 queries is prepared)

1
2
3
4
5
6
7
tcpdump udp -i bond0.1209 -n  -w dump-ip.pcap -v
-i #是指定要抓取的网卡
-w #指定结果保存的位置

kdig @100.71.9.148 www.yx1.com -p 53 +short
kdig @100.71.9.148 host1.example.com -p 53 +short
kdig @100.71.9.148 www.mascotdokky.com -p 53 +short
1
2
3
4
5
#使用tcpprep区分client和server端,生成cache文件。
tcpprep -a client -i dump-ip.pcap -o dump-ip.cache

#生成目的端口为80的报文缓存文件
tcpprep -i dump-ip.pcap -o dump-ip.cache -p 80

对包文件进行改写:

1
2
3
4
5
6
7
8
9
10
tcprewrite -e 192.85.1.2:192.85.2.2 
--enet-dmac=00:15:17:2b:ca:14,00:15:17:2b:ca:15
--enet-smac=00:10:f3:19:79:86,00:10:f3:19:79:87
-c test.cache
-i test.tcpdump
-o 1.pcap


#把报文的端口修改为80->8080
tcprewrite -r 80:8080 -i dump-ip.pcap -o dump-ip-test.pcap
1
tcpreplay-edit #直接回放编辑后的报文,不生成中间文件
1
2
3
tcpliveplay was designed to work only with TCP connections, as this is
where client is required to send to the server data relevant for its
responses (in regards to SEQ & ACK numbers). This is not needed for UDP.

该软件默认是线速发包,试验发现会有错误的包和乱序的包。配置为1000个包/s时,不会失序。

推测失序原因:在高速发包时,特别依赖于网卡,只要网卡有抖动,可能会导致client端和服务器端发送的包在通过DUT时,排序有问题。

1
2
3
4
5
6
7
8
9
10
11
12
tcpreplay -i bond0.1209 -l 0 -p 100 dump-ip.pcap 
tcpreplay -i bond0.1209 -I bond0.1209 -p 1000 -c dump-ip.cache dump-ip.pcap
tcpreplay -i bond0.1209 -I bond0.1209 -l 0 -p 1000 -c dump-ip.cache dump-ip.pcap

tcpreplay-edit --unique-ip -l 1000 -M 1000 -i bond0.1209 dump-ip.pcap

#以最快的速度循环播放1000次
tcpreplay -i bond0.1209 -t -K -l 1000 -M 1000 dump-ip.pcap
#或者以每秒 100 个数据包的速率继续重播一分钟:
tcpreplay -i bond0.1209 -K --pps 100 --duration 60 dump-ip.pcap

tcpreplay-edit --unique-ip -l 1000 -M 1000 -i bond0.1209 dump-ip.pcap
1
2
3
4
5
6
7
8
9
10
-i : 设置报文回放的出端口,即报文是从这台linux的哪个端口出去的。
-l : 设置报文回放的次数, 1 即为一次, 0 为不断循环回放。
-p: 设置报文回放的速度,每秒多少个包,这里设置为100即为每秒回放100个包。
最后的为指定回放的是哪个pcap 报文。

-K的作用就是将数据包预先读取到内存中.发出数据包时就可以不受硬盘读写速度的限制,保证较为稳定的流量。

由于内存的限制,不可能将很大的PCAP文件读取到内存中,我们可以利用tcpreplay-edit的loop功能配合一些选项,让数据包不断循环回放,从而达到延长测试时间的目的。

-unique-ip的作用是每一次循环回放时,都修改数据包中的IP地址,从而形成新的流。-l是循环回放PCAP文件。

DNSSEC

reuseport

reuseport是一种套接字复用机制,它允许你将多个套接字bind在同一个IP地址/端口对上,这样一来,就可以建立多个服务来接受到同一个端口的连接。
using reuseport for UDP
2021-08-06T14:22:32+0800 info: binding to interface 127.0.0.1@58
2021-08-06T14:22:32+0800 info: binding to interface 10.154.5.163@58
2021-08-06T14:22:32+0800 info: binding to interface ::1@58

对于不同的内核,处理机制是不一样的,总的说来,reuseport分为两种模式,即热备份模式和负载均衡模式,在早期的内核版本中,即便是加入对reuseport选项的支持,也仅仅为热备份模式,而在3.9内核之后,则全部改为了负载均衡模式,两种模式没有共存

Knot DNS 使用教程 (groverchou.com)

knot DNS 01 Tips_奋斗中拥有-CSDN博客

ubuntu安装Knot 域名权威Authoritative DNS服务器配置ddns动态更新ip - 海运的博客 (haiyun.me)

Knot DNS: One Tame and Sane Authoritative DNS Server | Linux Journal

GeoIP in Knot DNS 2.7 | APNIC Blog

Get faster and more secure DNS resolution with Knot Resolver on Fedora (ctrl.blog)

DNS Tutorial part 1 – DNS basics – DNS monitor

统计

Knot DNS: src/knot/modules/stats/stats.rst | Fossies

-------------Keep It Simple Stupid-------------
0%