第八章:BIND策略和翻转

BIND根据密钥和签名策略(Key and Signing Policy —— KASP)执行密钥翻转。该策略还设置了区域使用的密钥类型和所有时间。除了第7章中讨论的所有内容外,您还必须了解使用BIND正确滚动密钥的政策。默认策略是故意保守的,旨在适用于您可能拥有的任何设备,包括Raspberry Pi。如果你想做任何更复杂的事情,你需要制定自己的政策。

BIND包括其他密钥管理工具,如 dnssec-keymgr(8)dnssec-keygen(8)dnssec-setdate(8) ,但截至BIND 9.16,这些工具已被KASP完全淘汰。

首先,让我们看看如何在政策中表示时间。

第八章:BIND策略和翻转持续时间格式策略组件计时选项keys 章节默认策略与您的策略NSEC3KSK 策略将旧配置迁移到策略执行滚动手动ZSK滚动KSK滚动最小化KSK翻转中的父区域交互滚动 CSKs更改区域策略

持续时间格式

区域文件传统上以秒表示持续时间,偶尔会使用date(1)-style的标记来表示小时(3h)或分钟(15m)。几十年来,这一直很有效,但人们开始迁移到ISO 8601持续时间格式。虽然旧的方法将在我职业生涯的剩余时间里继续使用,但你也应该了解ISO格式。

所有持续时间定义都以大写字母 P 开头。Y表示年数,M表示月数,W表示周数,D表示天数(the number of days)。P3Y表示“为期三年”,而P1Y2M3W4D表示“为期一年两个月三周四天”。

“Months”是一个模棱两可的术语,我建议你避免使用它。如果你想让密钥每三个月过期一次,请使用P90D(九十天)这样的期限。

T 表示一天或更长时间的单位与小于一天的单位之间的分割,就像小数点一样。在一天内,单位为H表示小时,M表示分钟,S表示秒。与小数点完全一样,当表示小于一天的时间时,T是必需的。持续时间P5M为五个月,而PT5M为五分钟。P1YT5M表示“一年零五分钟的持续时间”。

您应该在策略中使用哪一项?我看到的大多数策略都混合了ISO 8601和 date(1) 标记。如果你有这种倾向,你现在可能会开始哭泣。

策略组件

策略定义了您的密钥以及您如何对区域进行签名。它还允许您设置有关外部实体的信息,如区域父级的TTL,以便BIND可以智能地旋转密钥。策略必须在 named.conf 中,可能是通过包含文件。策略看起来像任何其他BIND named.conf 组件。

BIND包括一个默认策略,其中包括平均区域的合理设置。您无法重新定义默认策略;相反,为您的区域创建一个新策略。通过复制默认策略来启动策略。这是BIND 9.16政策。

政策包括关键定义和时间细节。keys 节允许您定义是使用KSK和ZSK还是独立的CSK,以及它们将使用哪些算法。

在密钥定义之后,我们看到了时间选项。每个人都是孤独的。选择默认值是为了使新的DNSSEC管理员不必立即安排滚动。

我们将首先讨论计时选项,然后讨论密钥。

计时选项

该策略的时间选项使该策略能够表达第7章中讨论的TTL和复制因素。您的辅助名称服务器需要四个小时才能从主服务器复制一个区域?你的一个区域有两个月的TTL?有这样的选择。以下是BIND 9.16默认策略中设置的计时选项。

dnskey-ttl 选项允许您设置所有DNSKEY记录的TTL。默认值为一小时。

当BIND旋转密钥时,它会根据区域中的时间计算TTL,就像你在第7章中所做的那样。 -safety 选项允许您添加额外的时间作为填充,以绝对确定远程名称服务器已从其缓存中清除了旧数据。 publish-safety 设置被添加到在区域中发布密钥和使用它创建RRSIG之间的时间。即使密钥不再处于活动状态,也会在钥匙留在该区域的时间内添加 retire-safety 选项。每个小时的默认值为1小时。

经过几年的自动轮换,密钥文件可以建立起来。 purge-kyes 选项允许您自动删除已发布、已使用、未发布和已从服务中删除的密钥。默认值P90D在停用90天后删除关键文件。

接下来将显示签名生命信息。

当记录被签名时,签名会被分配一个到期日期。各种 signatures- 选项设置了到期日期,并规定了签名何时续订。这些过期日期与区域的TTL无关。生成签名的计算成本很高,你不想一直这样做。

当BIND签署记录集以创建RRSIG时,它会检查 signatures-validity 以设置到期日期。默认值为十四天。

同样, signatures-validity-dnskey 允许您为DNSKEY记录上的签名设置单独的签名生命周期。您不需要更改默认的14天,因为该区域的TTL规定了客户端丢弃和刷新数据的频率。

signatures-refresh 设置告诉named在签名到期前多少天应该重新签名所有内容。默认值为五天。如果您的签名的最长生存期为14天,则签名在9天后会重新生成。假设你想每六天重新生成一个新签名?将 signatures-refresh 设置为8,以便在14天到期前8天续订。不要将签名刷新时间缩短到五天以内。如果你的服务器在周五下午出现签名问题,你宁愿在周六早上解决这个问题,浪费你的周末,还是等到周一下午?

然后,我们有关于区域和复制的时间细节。

max-zone-ttl 设置控制使用此策略签名的区域中数据的最大允许TTL。对于大多数区域,默认值86400秒或一天应该足够了。密钥轮换高度依赖于TTL,因此DNSSEC策略必须知道最大可能值。如果您的区域包含超过一天的TTL,则必须增加 max-zone-ttl 以匹配。

如果主名称服务器和辅助名称服务器之间的复制速度较慢,您可以使用 zone-propagation-delay 来设置适当的时间。如果NOTIFY在主服务器和辅助服务器之间工作,则默认值300秒应该完全可以。

最后,我们为父域设置定时值:

parent-ds-ttl 允许您设置父区域的TTL,因此BIND知道您的DS记录将在其他名称服务器的缓存中保留多长时间。大多数区域的TTL为几个小时,但将其保留在一天是一个安全的选择。

大多数父区域,如 .com.org ,都有可靠的名称服务器复制,但 parent-propagation-delay 可以让您增加安全裕度。默认值为一小时。

keys 章节

策略的 keys 章节声明了区域将使用什么类型的密钥:

我们可以在此处列出多个密钥,但默认策略只有一个组合签名密钥(Combined Signing Key)。密钥存储在密钥目录中。每个密钥都有一个生命周期,或者它的有效期有多长。在默认策略中,密钥永远有效(终身无限)。最后,该密钥使用算法13:ECDSAP256SHA256。

这项政策唯一奇怪的是,钥匙永远不会过期。默认策略旨在供DNSSEC初学者使用,他们还不了解密钥翻转以及与注册表和RIR的交互。默认策略的目标是使DNSSEC功能正常,现在或将来都不会破坏任何东西。这就像训练轮(training wheels)。您将编写适合您的环境和密钥轮换需求的自己的策略。

默认策略与您的策略

按照默认策略定义您的策略:

dnssec-policy "policyname" { options here; ​ };

您未在策略中设置的任何选项都会从默认策略中吸收。BIND的默认策略被编译为named,但您可以从源代码中获取副本。在这里,我编写了一个与默认值完全匹配的策略,除了我们想要使用的一个漂亮的设置:

这样的策略最初可能很有效,但未来的主要版本可能会更改默认策略。(侵入性更新仅发生在主要版本,如9.18到9.20。)但是,如果未来的BIND版本将默认策略算法从13更改为19,则升级时策略引擎将立即生成新密钥并开始滚动。虽然我确信这项政策不会让你的区域变得虚假,但它会用额外的工作来伏击你。没有人喜欢伏击劳动。

通过始终完整地定义您的政策来避免这种风险。为了避免无数冗长的策略使 named.conf 变得混乱,可以考虑使用include文件。

升级BIND安装时,请查看新的默认策略,以获取有关应计划升级的提示。如果默认算法发生更改,请开始计划一个受控的、深思熟虑的算法滚动。

我保留了一份从BIND源代码树复制的默认策略的副本。每当我想创建新策略时,我都会将默认值复制到新文件中,为其命名,并对其进行编辑以满足我的需求。

NSEC3

DNSSEC提供了两种安全地证明记录不存在的方法,NSEC和NSEC3。第二章讨论了两者。NSEC更简单,但它确实允许客户端枚举和检查您区域中的所有条目。提供NSEC3记录需要权威名称服务器执行更多计算,但对于大多数区域来说,负载可以忽略不计。保守的默认策略使用NSEC。您需要一个新策略来部署NSEC3。

通过添加 nsec3param 选项启用NSEC3。

NSEC3具有多次通过哈希算法传递记录以及添加盐以进一步混淆条目的可选功能。最近的研究表明,这些并不能提高安全性,但会降低响应性并增加系统负载。两者都禁用。如果不指定这些选项,BIND 9.16默认使用5次迭代和8个盐长度。BIND 9.18将默认使用零迭代和无盐。

您还可以通过启用NSEC3选择退出来更改NSEC3表示子区域的方式。不过,只有当你有数千个代表团时,它才有用。如果你是那些不幸的人之一,请考虑退出。

KSK 策略

虽然默认的CSK策略对低价值区域(low-value zones)很有用,但如果您正在运行电子商务网站或其他高价值网站,您可能需要KSK和ZSK。在策略的 keys节中配置这些,如下所示:

keys { key-role lifetime period algorithm algorithm; ​ };

key-role 决定此密钥是CSK(CSK)、KSK(KSK)还是ZSK(ZSK)。

您经常会看到 key-directory 的第二个参数。这是一个关于密钥存储位置的可选语句。未来的BIND版本可能能够直接在HSM上存储密钥。现在,所有密钥都放在配置的密钥目录中。

lifetime 设置密钥将使用多长时间。我们看到默认策略的 lifetime 设置为 unlimited ,创建了一个没有过期日期的密钥。滚动KSK需要与该区域的注册商或RIR进行交互,因此我建议将此类密钥设置为永不过期,并使用日历(calendar)安排手动滚动。为ZSK指定密钥生命周期,BIND将自动为您执行翻转。

最后, algorithm 关键字设置密钥算法。您可以使用数字或算法的正式名称。像RSASHA256这样的算法也可以获取密钥长度,因此将其添加为额外的参数。

以下是我如何在策略中设置KSK和ZSK。

此策略使用算法13或ECDSAP256SHA256创建永不过期的KSK。ZSK也使用ECDSAP256SHA256,但它每90天过期一次。

我从默认策略复制此策略的其余部分,以保护我在升级过程中免受意外更改。现在,我可以使用 named.conf 中的 dnssec-policy ksk 语句将此策略应用于我的测试区域,并重新配置我的名称服务器。我的域名服务器对此区域的DNSSEC有何看法?

4060是新的ZSK,而50062是全新的KSK。重复的 rumoured 状态表明,我最近应用了这项政策,以至于远程域名服务器还没有机会更新他们的缓存。几小时后,一旦TTL到期,BIND将把本地状态更新为 omnipresent 。一旦DNSKEY和签名变为 omnipresent ,就可以安全地发布DS记录。DS记录将成为 rumoured ,该地区将发布新的CDS和CDNSKEY记录。

一旦我在父区域中发布了DS记录并验证了它确实存在于野外,我就可以使用 rndc(8) 更新密钥的状态。

BIND将等待TTL过期,然后更新密钥的状态。

将旧配置迁移到策略

如果您在几年前设置了DNSSEC,但自那以后就没有碰过它,请更新您的配置以使用策略。所有新的管理工具都需要策略,旧的配置方法最终将被删除。在触摸任何东西之前,请确保您对区域和关键文件有良好的备份。也不要在密钥滚动期间启动此迁移。

我们将把BIND 9.9中的内联签名配置迁移到KASP策略中。这是本书第一版中使用的配置。

这些较旧的DNSSEC方法需要使用您想要的任何算法和密钥长度手动生成密钥。本书的第一版使用了RSASHA256密钥,即算法8,具有2048位KSK和1024位ZSK。不幸的是, rndc dnssec -status 在使用旧配置的区域上不起作用,因此您无法使用它来验证当前密钥是否与原始值匹配。然而,策略创建的每个密钥在其他密钥文件中都有一个 .state 文件,给出了算法和长度。使用以下网站进行双重检查 https://dnsviz.net

现在定义一个使用这些键的策略。所有内容都可以使用与默认设置相同的设置,但您需要一个自定义 keys 节。我以这本书的第一版命名这项政策为 dm1

将策略应用于您的区域,并注释掉 inline-signingauto-dnssec 选项。

您触摸了配置,因此请碰撞该区域的序列号。重新加载名称,或至少是区域。

BIND将查找并使用现有密钥。您现在正在使用策略。您必须完全重新加载以 rndc dnssec 命名的区域才能在该区域上工作。

执行滚动

DNSSEC密钥翻转可以在BIND中自动管理,也可以通过 rndc(8) 在命令行进行管理。密钥翻转的处理方式取决于外部世界所需的任何变化。

ZSK完全在一个区域内管理,不需要与外界交互。BIND在没有系统管理员干预的情况下对ZSK进行滚动,这取决于密钥生命周期的策略设置。ZSK使用预发布滚动方法(pre-publishing rollover method),在该方法中,新密钥的DNSKEY记录在用于签署任何记录之前被发布并无处不在。

更改KSK和CSK需要与域注册商或RIR进行交互。即使您在KSK和CSB上配置了最长生存期,BIND也不会停止使用旧密钥,直到您通知它新密钥的DS记录已发布。您的注册商可能有附加软件,可以让您自动滚动这些密钥,但我们大多数人都必须监督滚动。

一般来说,一次只能滚动一个区域中的一个密钥。如果您想滚动KSK,但ZSK处于中间滚动状态,请等待ZSK滚动完成,并且旧密钥不再在区域中,然后再开始KSK滚动。你可以同时做多个滚动,但你可能会混淆自己。

在您的第一次滚动中,我强烈建议启用第6章中讨论的DNSSEC调试日志。您将确切地看到BIND采取了什么行动和各种倒计时。一旦您对滚动感到满意,请保留调试日志,以便在事情变得奇怪时使用。

虽然最后一章讨论了执行展期的不同方法,但政策总是使用最安全的方法进行此类展期。您不能通过策略更改滚动方法。

我们将从执行更简单的ZSK辊开始,然后使用我们所学到的知识来执行更复杂的KSK和CSK辊。

手动ZSK滚动

首先检查您所在区域的DNSSEC密钥的状态:

这个区域有两个密钥。密钥4060是ZSK,密钥50062是KSK。我们必须绝对确保只滚动密钥4060,保持密钥50062不变。使用 rndc dnssec -overover 触发滚动。 -key 参数允许我们指定一个密钥:

这似乎太容易了。检查该区域的状态:

密钥4060的ZSK的描述已经更改。在发布数据之后,有一份声明称密钥将在某个日期和时间退役。此密钥的目标是 hidden ,表示我们想从区域中删除该密钥。现有的记录是 omnipresent ,这意味着任何缓存服务器仍然有这些记录。

密钥50062(KSK)的条目保持不变。

不过,在底部,我们有一个全新的密钥条目。

密钥31047是一款全新的ZSK。它与 rndc dnssec -rowloon 声明的时间完全一致,但尚未用于区域签名。这符合预发布滚动方法。根据策略中设置的时间和区域的TTL,此密钥可以在两小时五分钟后用于签名。

使用dig验证新密钥的可用性。

这里的中间条目是密钥31047。它确实在我们的DNS中。不过,检查该区域的RRSIG记录表明它尚未使用。如果你检查DNSViz这样的工具,你会看到密钥31047已签名,但没有任何东西挂断。

真正的考验是当我们在两个多小时零五分钟后返回,看看这个区域是什么样子的。

密钥4060是旧的ZSK。它在区域中发布,但不会用于生成新的签名。我们看到密钥将从区域中删除的日期和时间。区域rrsig值为unrelictive意味着现有签名可以保留,但当用此密钥签名的签名过期时,它们将不会被替换。

我们的KSK记录没有改变,但我们有了新的ZSK。

此密钥已准备好签署记录。当用旧密钥签名的RRSIG记录过期时,它们将被用此新密钥生成的签名替换。

KSK滚动

作为入侵者有价值的目标的网站,如电子商务公司和任何包含个人身份信息的网站,应使用单独的KSK和ZSK,并每年左右轮换KSK。命令行过程与ZSK滚动非常相似,但需要在关键时刻与注册商或RIR进行交互。BIND使用双签名翻转方法。您发布新密钥的DNSKEY记录,等待其传播,然后在父密钥上切换DS记录。

在开始KSK滚动之前,检查父区域的TTL,看看它重新分发更新的DS记录的速度有多快。验证DNSSEC策略是否匹配或超过TTL,以便BIND可以安全地更改密钥状态。

这是该区域的当前密钥。

密钥15296是KSK,而55383是ZSK。我们只有一个ZSK,下一次展期计划在一个月后,所以我们可以以最小的风险展期KSK。

像ZSK一样,用 rndc dnssec -rover 开始翻转。使用 -key 指定密钥标记:

BIND确认收到其指示。让我们看看它做了什么。

我们的旧KSK已被标记为要删除。

密钥61372是我们现在创建的新KSK。这里的关键点(critical point)是 ds 条目显示为 “hidden” 。信任链还不知道这个新密钥。

对于我们的第一次KSK翻转,我们将格外小心。一旦你理解了这个过程,并对翻转的工作原理感到满意,我们将优化这个过程,以尽量减少与父区域的交互。去告诉你的父区域关于新的DS记录。完成此操作后,请等待,直到您可以验证新记录在该区域中可用。只有当密钥对公众开放时,您才能通知BIND密钥已发布。

区域状态不会立即改变,但BIND内部会开始倒计时,直到它可以开始将新密钥视为主要密钥。

此区域现在将在其父区域中有两个DS记录。信任链的你部分有平行的链接。如果你检查 https://DNSViz.net 你会看到从 .org 到我的域名的双链接。

【此处有图】

现在;我们等待。BIND跟踪根据各种策略设置计算的TTL,因此它可以告诉您新密钥何时无处不在(omnipresent)。

这是我们的旧密钥15296,现在标记为9月22日退役。然而,使用此密钥的记录和签名仍然被广泛使用。

新的密钥61372随处可见。BIND不会探测远程DNS服务器是否可以检索新记录;根据策略中的时间计算 omnipresent 状态。如果您有任何疑问,请再次检查政策时间。

新的、无处不在的KSK意味着我们可以取消发布我们正在退役的旧KSK。转到您的注册商并删除旧密钥的DS记录。完成后,告诉BIND您已提取密钥。

您的区域将包含此密钥和使用它创建的签名,直到退役日期。BIND将继续使用撤回的KSK来创建签名,只要客户端可以缓存它。撤回的ZSK将不会用于创建更多签名。删除密钥后,在日历上记下以检查区域。

最小化KSK翻转中的父区域交互

现在您已经掌握了密钥帧在其生命周期中的流动方式,可以优化滚动。

双重签名方法(Double-signature method)的优点是它最大限度地减少了与父区域的接触。如果您等待新的DNSKEY及其签名变得无处不在,则可以同时发布新的DS记录和删除旧的DS记录。由于您的区域中有两个DNSKEY记录,因此拥有旧DS记录或新DS记录的客户端将能够验证您的区域。

验证新DS记录在父区域中可用后,使用 rndc 提取旧密钥。

滚动 CSKs

滚动CSK与滚动KSK非常相似。您生成新密钥,等待这些密钥变得无处不在,然后换出旧密钥。这是我的主域名 mwl.io ,它使用CSK。

一个密钥,随处可用。让我们滚动它。使用 -rollover 选项。使用 -key 指定密钥标记。

再次检查区域状态以查看新密钥:

这是新的密钥,对世界可见,但尚未用于对密钥进行签名。旧钥匙仍然存在,但现在有一个退休日期。

一旦新密钥及其签名无处不在,请前往您的注册商,将旧的DS记录换成新的,就像您进行KSK轮转一样。一旦新的DS记录在父区域中可见,使用 rndc 提取旧密钥。

更改区域策略

在政策之间切换有很多原因。也许RSASHA256被破解了。也许你从CSK开始,但监管机构希望你使用两个密钥。也许老板读错了白皮书。无论出于什么原因,你都可以毫不费力地改变政策。

政策变化不会立即抛弃所有旧东西。相反,所有新记录都是按照新策略创建的。如果您更改密钥算法,BIND将创建新密钥,但保留旧密钥,以便您可以进行有序的翻转。

在紧急情况下,您可以使用 nsupdate 删除旧记录并重新加载区域,但这很难看,也容易出错。与DNS的许多事情一样,我建议耐心等待。

如果您想了解有关BIND策略行为的更多详细信息,该策略引擎基于Schaeffer、Overeinder和Mekking的论文“DNSSEC中灵活而稳健的密钥翻转”。还可以提供基于该论文的视频。

我们将通过执行最困难的策略更改(算法迁移)来演示。正如本章前面的“将旧配置迁移到策略”中所讨论的那样,我的专区 immortalclay.com 直接使用本书第一版中的RSASHA1 KSK和ZSK。让我们将其迁移到基于ECDSA的现代密钥策略,如“KSK策略”。

在更改任何内容之前,该区域看起来是这样的。

此区域使用 dm1 策略。

密钥38754是我们目前的ZSK。它无处不在,快乐无比。

密钥9318是老旧的ZSK。它不再使用,也不再在区域中,但BIND仍然有密钥文件。该政策在不再使用90天后才会删除它。为清楚起见,我将从进一步的输出中删除它。

密钥12107是我们目前无处不在的KSK。

对公共DNS服务器的检查表明,这反映了世界所看到的。

进入 named.conf ,更改策略,然后重新加载名称服务器。然后检查该区域的状态。

政策变了!随着这一变化,该区域又增加了两个密钥。

这是我们全新的ZSK。它目前用于签名。客户端尚未缓存此密钥,因此我们不能完全依赖它。等待密钥变得无处不在,然后再依赖它进行验证。

我们全新的KSK在该区域,但也不在任何客户的缓存中。

我们的RSASHA256 ZSK仍然存在,但它已经改变了。展期到期。政策知道这个密钥需要消失。

同样,RSASHA256 KSK仍存在于该区域中。政策也希望它消失。

算法迁移只不过是KSK翻转。您可以等待新密钥变得无处不在并交换掉DS记录,也可以立即发布新DS并稍后返回以删除旧DS。这次,我将立即发布新的DS记录,稍后返回以移除旧DS。

一旦您验证了新DS在父区域中可用,请通知BIND密钥已发布。

与任何其他KSK翻转一样,在删除旧的DS记录之前,等待新密钥变得无处不在。.com 中的DS记录当前的TTL为86400,因此我可以删除旧的DS记录。作为最后的检查,在删除旧DS之前,请验证BIND是否将新密钥显示为无所不在。

此密钥和与之相关的一切都是无处不在的。每个查询过此区域的递归服务器都应该在缓存中有新的密钥。我可以提取旧的RSASHA256密钥。

BIND将按照策略中的配置,倒计时客户端可能缓存此内容的时间,并将其从区域中删除。

按照这些示例,您可以通过多种方式滚动密钥。不过,这仍然给我们留下了保护客户端和递归服务器之间流量的问题。接下来,我们将深入探讨。