如何在权威BINDDNS服务器上设置DNSSEC

来自菜鸟教程
跳转至:导航、​搜索

关于 DNSSEC

我们都知道DNS是一种将域名解析为IP地址的协议,但是我们怎么知道返回的IP地址的真实性呢? 攻击者有可能篡改 DNS 响应或 毒化 DNS 缓存 并将用户带到地址栏中具有合法域名的恶意站点。 DNS 安全扩展 (DNSSEC) 是旨在维护 DNS 响应的数据完整性的规范。 DNSSEC 使用 PKI(公钥基础设施)对区域的所有 DNS 资源记录(A、MX、CNAME 等)进行签名。 现在启用 DNSSEC 的 DNS 解析器(如 Google 公共 DNS)可以使用公共 DNSKEY 记录验证 DNS 回复(包含 IP 地址)的真实性。

DNSSEC 资源记录

资源记录 (RR) 包含有关域的特定信息。 一些常见的有包含域 IP 地址的 A 记录、包含 IPv6 信息的 AAAA 记录和具有域邮件服务器的 MX 记录。 可以在 此处 找到 DNS RR 的完整列表。

同样,DNSSEC 也需要多个 RR。

  • DNSKEY 保存解析器用来验证的公钥。
  • RRSIG 存在于每个 RR 并包含记录的数字签名。
  • DS - 委托签名者 - 此记录存在于 TLD 的名称服务器中。 因此,如果 example.com 是您的域名,则 TLD 为“com”,其名称服务器为 a.gtld-servers.net.b.gtld-servers.net.m.gtld-servers.net.。 此记录的目的是验证 DNSKEY 本身的真实性。

设置环境

域名: 例子.com

我使用了一个真正的 .COM 域来执行此操作,但在本文中已将其替换为 example.com

主域名服务器: IP地址: 1.1.1.1 主机名: master.example.com 操作系统: Debian 7

从名称服务器: IP地址: 2.2.2.2 主机名: slave.example.com 操作系统: CentOS

文件位置和名称

BIND 的配置文件和区域文件的名称和位置根据使用的 Linux 发行版而有所不同。

Debian/Ubuntu

服务名称:bind9 主配置文件:/etc/bind/named.conf.options 区域名称文件:/etc/bind/named.conf.local 默认区域文件位置:/var/cache/bind/

CentOS/Fedora

服务名称:named 主要配置和区域名称文件:/etc/named.conf 默认区域文件位置:/var/named/

如果您使用 bind-chroot,这些可能会改变。 在本教程中,我将 Debian 用于 Master NS,将 CentOS 用于 Slave NS,因此请根据您的发行版进行更改。

DNSSEC 主配置

通过在 options{ } 中添加以下配置指令来启用 DNSSEC

nano /etc/bind/named.conf.options

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

这些可能已经添加到某些发行版中。 导航到您的区域文件的位置。

cd /var/cache/bind

使用以下命令创建区域签名密钥 (ZSK)。

dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE example.com

如果你已经安装了haveged,生成这个key只需要几秒钟; 否则需要很长时间。 样本输出。

root@master:/var/cache/bind# dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE example.com
Generating key pair..................+++ .............+++
Kexample.com.+007+40400

使用以下命令创建密钥签名密钥 (KSK)。

dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE example.com

样本输出。

root@master:/var/cache/bind# dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE example.com
Generating key pair......................++ .............................................................................................................................................................................................................++
Kexample.com.+007+62910

该目录现在将有 4 个密钥 - ZSK 和 KSK 的私有/公共对。 我们必须将包含 DNSKEY 记录的公钥添加到区域文件中。 下面的 for 循环将执行此操作。

for key in `ls Kexample.com*.key`
do
echo "\$INCLUDE $key">> example.com.zone
done

使用 dnssec-signzone 命令对区域进行签名。

dnssec-signzone -3 <salt> -A -N INCREMENT -o <zonename> -t <zonefilename>

用随机的东西代替盐。 这是一个输出示例。

root@master:/var/cache/bind# dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o example.com -t example.com.zone
Verifying the zone using the following algorithms: NSEC3RSASHA1.
Zone signing complete:
Algorithm: NSEC3RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
                        ZSKs: 1 active, 0 stand-by, 0 revoked
example.com.zone.signed
Signatures generated:                       14
Signatures retained:                         0
Signatures dropped:                          0
Signatures successfully verified:            0
Signatures unsuccessfully verified:          0
Signing time in seconds:                 0.046
Signatures per second:                 298.310
Runtime in seconds:                      0.056

必须输入 16 个字符的字符串作为“salt”。 以下命令

head -c 1000 /dev/random | sha1sum | cut -b 1-16

输出一个 16 个字符的随机字符串,将用作盐。

这将创建一个名为 example.com.zone.signed 的新文件,其中包含每个 DNS 记录的 RRSIG 记录。 我们必须告诉 BIND 加载这个“签名”区域。

nano /etc/bind/named.conf.local

更改 zone { } 部分内的 file 选项。

zone "example.com" IN {
    type master;
    file "example.com.zone.signed";
    allow-transfer { 2.2.2.2; };
    allow-update { none; };
};

保存此文件并重新加载绑定

service bind9 reload

检查是否在同一台服务器上使用 dig 的 DNSKEY 记录。

dig DNSKEY example.com. @localhost +multiline

样本输出

root@master:/var/cache/bind# dig DNSKEY example.com. @localhost +multiline
;; Truncated, retrying in TCP mode.

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> DNSKEY example.com. @localhost +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43986
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;example.com.       IN DNSKEY

;; ANSWER SECTION:
example.com.        86400 IN DNSKEY   256 3 7 (
                AwEAActPMYurNEyhUgHjPctbLCI1VuSj3xcjI8QFTpdM
                8k3cYrfwB/WlNKjnnjt98nPmHv6frnuvs2LKIvvGzz++
                kVwVc8uMLVyLOxVeKhygDurFQpLNNdPumuc2MMRvV9me
                fPrdKWtEEtOxq6Pce3DW2qRLjyE1n1oEq44gixn6hjgo
                sG2FzV4fTQdxdYCzlYjsaZwy0Kww4HpIaozGNjoDQVI/
                f3JtLpE1MYEb9DiUVMjkwVR5yH2UhJwZH6VVvDOZg6u6
                YPOSUDVvyofCGcICLqUOG+qITYVucyIWgZtHZUb49dpG
                aJTAdVKlOTbYV9sbmHNuMuGt+1/rc+StsjTPTHU=
                ) ; key id = 40400
example.com.        86400 IN DNSKEY   257 3 7 (
                AwEAAa2BE0dAvMs0pe2f+D6HaCyiFSHw47BA82YGs7Sj
                qSqH3MprNra9/4S0aV6SSqHM3iYZt5NRQNTNTRzkE18e
                3j9AGV8JA+xbEow74n0eu33phoxq7rOpd/N1GpCrxUsG
                kK4PDkm+R0hhfufe1ZOSoiZUV7y8OVGFB+cmaVb7sYqB
                RxeWPi1Z6Fj1/5oKwB6Zqbs7s7pmxl/GcjTvdQkMFtOQ
                AFGqaaSxVrisjq7H3nUj4hJIJ+SStZ59qfW3rO7+Eqgo
                1aDYaz+jFHZ+nTc/os4Z51eMWsZPYRnPRJG2EjJmkBrJ
                huZ9x0qnjEjUPAcUgMVqTo3hkRv0D24I10LAVQLETuw/
                QOuWMG1VjybzLbXi5YScwcBDAgtEpsQA9o7u6VC00DGh
                +2+4RmgrQ7mQ5A9MwhglVPaNXKuI6sEGlWripgTwm425
                JFv2tGHROS55Hxx06A416MtxBpSEaPMYUs6jSIyf9cjB
                BMV24OjkCxdz29zi+OyUyHwirW51BFSaOQuzaRiOsovM
                NSEgKWLwzwsQ5cVJBEMw89c2V0sHa4yuI5rr79msRgZT
                KCD7wa1Hyp7s/r+ylHhjpqrZwViOPU7tAGZ3IkkJ2SMI
                e/h+FGiwXXhr769EHbVE/PqvdbpcsgsDqFu0K2oqY70u
                SxnsLB8uVKYlzjG+UIoQzefBluQl
                ) ; key id = 62910

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Nov 27 18:18:30 2013
;; MSG SIZE  rcvd: 839

检查是否存在 RRSIG 记录。

dig A example.com. @localhost +noadditional +dnssec +multiline
; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> A example.com. @localhost +noadditional +dnssec +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32902
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;example.com.         IN A

;; ANSWER SECTION:
example.com.          86400 IN A 93.184.216.119
example.com.          86400 IN RRSIG A 7 2 86400 20131227171405 (
                            20131127171405 40400 example.com.
                            JCoL8L7As1a8CXnx1W62O94eQl6zvVQ3prtNK7BWIW9O
                            lir/4V+a6c+0tbt4z4lhgmb0sb+qdvqRnlI7CydaSZDb
                            hlrJA93fHqFqNXw084YD1gWC+M8m3ewbobiZgBUh5W66
                            1hsVjWZGvvQL+HmobuSvsF8WBMAFgJgYLg0YzBAvwHIk
                            886be6vbNeAltvPl9I+tjllXkMK5dReMH40ulgKo+Cwb
                            xNQ+RfHhCQIwKgyvL1JGuHB125rdEQEVnMy26bDcC9R+
                            qJNYj751CEUZxEEGI9cZkD44oHwDvPgF16hpNZGUdo8P
                            GtuH4JwP3hDIpNtGTsQrFWYWL5pUuuQRwA== )

;; AUTHORITY SECTION:
example.com.          86400 IN NS master.example.com.
example.com.          86400 IN NS slave.example.com.
example.com.          86400 IN RRSIG NS 7 2 86400 20131227171405 (
                            20131127171405 40400 example.com.
                            hEGzNvKnc3sXkiQKo9/+ylU5WSFWudbUc3PAZvFMjyRA
                            j7dzcVwM5oArK5eXJ8/77CxL3rfwGvi4LJzPQjw2xvDI
                            oVKei2GJNYekU38XUwzSMrA9hnkremX/KoT4Wd0K1NPy
                            giaBgyyGR+PT3jIP95Ud6J0YS3+zg60Zmr9iQPBifH3p
                            QrvvY3OjXWYL1FKBK9+rJcwzlsSslbmj8ndL1OBKPEX3
                            psSwneMAE4PqSgbcWtGlzySdmJLKqbI1oB+d3I3bVWRJ
                            4F6CpIRRCb53pqLvxWQw/NXyVefNTX8CwOb/uanCCMH8
                            wTYkCS3APl/hu20Y4R5f6xyt8JZx3zkZEQ== )

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Nov 28 00:01:06 2013
;; MSG SIZE  rcvd: 1335

主服务器配置完成。

DNSSEC 从站配置

从属服务器 只需要启用 DNSSEC 并更改区域文件位置。 编辑 BIND 的主配置文件。

nano /etc/named.conf

如果这些行不存在,请将它们放在 options { } 部分中。

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

编辑 zone { } 部分内的 file 选项。

zone "example.com" IN {
    type slave;
    file "example.com.zone.signed";
    masters { 1.1.1.1; };
    allow-notify { 1.1.1.1; };
};

重新加载 BIND 服务。

service named reload

检查是否有新的 .signed 区域文件。

[root@slave ~]# ls -l /var/named/slaves/
total 16
-rw-r--r-- 1 named named  472 Nov 27 17:25 example.com.zone
-rw-r--r-- 1 named named 9180 Nov 27 18:29 example.com.zone.signed

瞧! 就是这样。 只是为了确保一切正常,如上一节所述,使用 dig 查询 DNSKEY。

使用注册商配置 DS 记录

当我们在 .signed 区域文件之外运行 dnssec-signzone 命令时,还会创建一个名为 dsset-example.com 的文件,其中包含 DS 记录。

root@master:/var/cache/bind# cat dsset-example.com.
example.com.        IN DS 62910 7 1 1D6AC75083F3CEC31861993E325E0EEC7E97D1DD
example.com.        IN DS 62910 7 2 198303E265A856DE8FE6330EDB5AA76F3537C10783151AEF3577859F FFC3F59D

这些必须在您的域名注册商的控制面板中输入。 下面的屏幕截图将说明 GoDaddy 上的步骤。

登录到您的域注册商的控制面板,选择您的域,然后选择管理 DS 记录的选项。 GoDaddy 的控制面板如下所示。

这是 dsset-example.com. 文件中的数据分解。

DS 记录 1:

密钥标签: 62910 算法: 7 摘要类型: 1 摘要: 1D6AC75083F3CEC31861993E325E0EEC7E97D1DD

DS 记录 2:

密钥标签: 62910 算法: 7 摘要类型: 2 摘要: 198303E265A856DE8FE6330EDB5AA76F3537C10783151AEF95D3577859FFFC3

dsset-example.com. 文件中的第二个 DS 记录在摘要中有一个空格,但是当以表格形式输入时,您应该省略它。 点击Next,点击FinishSave记录。

保存这些更改需要几分钟时间。 要检查是否已创建 DS 记录,请查询您的 TLD 的名称服务器。 我们可以做一个更简单的 dig +trace,而不是查找 TLD 的名称服务器。

root@master:~# dig +trace +noadditional DS example.com. @8.8.8.8 | grep DS
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.6 <<>> +trace +noadditional DS example.com. @8.8.8.8
example.com.          86400   IN      DS      62910 7 2 198303E265A856DE8FE6330EDB5AA76F3537C10783151AEF3577859F FFC3F59D
example.com.          86400   IN      DS      62910 7 1 1D6AC75083F3CEC31861993E325E0EEC7E97D1DD

确认后,我们可以使用以下任何在线服务检查 DNSSEC 是否正常工作。

第一个工具很简单,而第二个工具为您提供了事物的视觉表示。 这是第一个工具的屏幕截图。

注意我标记的行。 第一个提到了 DS 记录的 Key tag 值 (62910),而第二个 key id (40400) 是保存 ZSK(区域签名密钥)的 DNSKEY 记录。

修改区域记录

每次您通过添加或删除记录来编辑区域时,都必须对其进行签名才能使其正常工作。 所以我们将为此创建一个脚本,这样我们就不必每次都输入长命令。

root@master# nano /usr/sbin/zonesigner.sh

#!/bin/sh
PDIR=`pwd`
ZONEDIR="/var/cache/bind" #location of your zone files
ZONE=$1
ZONEFILE=$2
DNSSERVICE="bind9" #On CentOS/Fedora replace this with "named"
cd $ZONEDIR
SERIAL=`/usr/sbin/named-checkzone $ZONE $ZONEFILE | egrep -ho '[0-9]{10}'`
sed -i 's/'$SERIAL'/'$(($SERIAL+1))'/' $ZONEFILE
/usr/sbin/dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N increment -o $1 -t $2
service $DNSSERVICE reload
cd $PDIR

保存文件并使其可执行。

root@master# chmod +x /usr/sbin/zonesigner.sh

每当您想添加或删除记录时,请编辑 example.com.zone而不是 .signed 文件 。 该文件还负责增加序列值,因此您无需在每次编辑文件时都这样做。 编辑后通过传递域名和区域文件名作为参数运行脚本。

root@master# zonesigner.sh example.com example.com.zone

您不必在从属名称服务器上执行任何操作,因为递增的序列号将确保该区域是否被传输和更新。

从区域漫游保护 DNSSEC 设置

ZoneWalking是一种通过查询NSEC(Next-Secure)记录来查找一个区域的所有资源记录的技术。 NSEC3 已发布,它使用盐“散列”了此信息。 回想一下 dnssec-signzone 命令,我们在其中指定了 -3 选项,然后是另一个精心制作的命令来生成随机字符串。 这是可以使用以下 dig 查询找到的盐。

# dig NSEC3PARAM example.com. @master.example.com. +short
1 0 10 7CBAA916230368F2

所有这些都使区域行走变得困难但并非不可能。 一个坚定的黑客使用 彩虹表 可以破解散列,尽管这需要很长时间。 为了防止这种情况,我们可以定期重新计算这个盐,这使得黑客的尝试是徒劳的,因为在他/她可以找到旧盐的散列之前有一个新的盐。 使用我们之前创建的 zonesigner.sh 脚本创建一个 cron 作业来为您执行此操作。 如果您以 root 运行 cronjob,则不必担心文件所有权。 或者确保您放置 cron 的用户对区域目录 具有 写入权限,对私钥 具有 读取权限(Kexample.com 。*。私人的)。

root@master:~# crontab -e

0       0       */3     *       *       /usr/sbin/zonesigner.sh example.com example.com.zone

这将每 3 天对该区域进行一次签名,结果将生成新的盐。 您还将收到一封电子邮件,其中包含 dnssec-signzone 命令的输出。

提交者:http: [[“%3Ca|//jesin.tk/]] [[“%3C/a|”>杰辛A]]