Alert Source Discuss
🚧 Stagnant Standards Track: Networking

EIP-1459: 通过 DNS 进行节点发现

通过 DNS 实现经过身份验证的可更新的以太坊节点列表的方案。

Authors Felix Lange (@fjl), Péter Szilágyi (@karalabe)
Created 2018-09-26
Discussion Link https://github.com/ethereum/devp2p/issues/50
Requires EIP-778

摘要

本文档描述了一种通过 DNS 检索的、经过身份验证的、可更新的以太坊节点列表的方案。

动机

许多以太坊客户端包含硬编码的引导节点列表。 更新这些列表需要软件更新。 当前的列表很小,使得客户端在进入以太坊网络的初始入口点方面几乎没有选择。 我们希望维护包含数百个节点的大型节点列表,并定期更新它们。

这里描述的方案是用等效的安全性以及许多额外的好处来替代客户端引导节点列表。 由遍历节点发现 DHT 填充的大型列表可以作为由于限制性网络策略而无法加入 DHT 的节点的备用选项。 基于 DNS 的节点列表对于以太坊对等提供商也可能很有用,因为他们的客户可以将客户端配置为使用提供商的列表。

规范

‘节点列表’是任意长度的’节点记录’列表如 EIP-778 所定义。 列表可以使用链接引用其他列表。 整个列表使用 secp256k1 私钥签名。 要验证列表,客户端必须知道相应的公钥。

为了引用 DNS 节点列表,客户端使用带有 ‘enrtree’ 方案的 URL。 URL 包含可以在其上找到列表的 DNS 名称以及签署列表的公钥。 公钥包含在 URL 的用户名部分中,是压缩的 32 字节二进制公钥的 base32 编码 (RFC-4648)。

例子:

enrtree://AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@nodes.example.org

此 URL 引用 DNS 名称 ‘nodes.example.org’ 处的节点列表,并由公钥签名 0x049f88229042fef9200246f49f94d9b77c4e954721442714e85850cb6d9e5daf2d880ea0e53cb3ac1a75f9923c2726a4f941f7d326781baa6380754a360de5c2b6

DNS 记录结构

列表中的节点被编码为 merkle 树,以便通过 DNS 协议进行分发。 merkle 树的条目包含在 DNS TXT 记录中。 树的根是一个 TXT 记录,其内容如下:

enrtree-root:v1 e=<enr-root> l=<link-root> seq=<sequence-number> sig=<signature>

其中

  • enr-rootlink-root 指的是包含节点和链接子树的子树的根哈希。
  • sequence-number 是树的更新序列号,一个十进制整数。
  • signature 是对记录内容的 keccak256 哈希值的 65 字节 secp256k1 EC 签名,不包括 sig= 部分,编码为 URL 安全的 base64 (RFC-4648)。

子域上的进一步 TXT 记录将哈希映射到三种条目类型之一。 任何条目的子域名是其文本内容的(缩写)keccak256 哈希的 base32 编码。

  • enrtree-branch:<h₁>,<h₂>,...,<hₙ> 是一个中间树条目,包含子树条目的哈希。
  • enrtree://<key>@<fqdn> 是一个叶子,指向位于另一个完全限定域名的不同列表。 请注意,此格式与 URL 编码匹配。 此类型的条目可能仅出现在 link-root 指向的子树中。
  • enr:<node-record> 是一个叶子,包含节点记录。 节点记录被编码为 URL 安全的 base64 字符串。 请注意,此类型的条目与规范的 ENR 文本编码匹配。 它可能只出现在 enr-root 子树中。

没有为树定义特定的排序或结构。 每当树更新时,其序列号应增加。 任何 TXT 记录的内容都应足够小,以适应 UDP DNS 数据包的 512 字节限制。 这限制了可以放入 enrtree-branch 条目中的哈希数量。

区域文件格式示例:

; name                        ttl     class type  content
@                             60      IN    TXT   enrtree-root:v1 e=JWXYDBPXYWG6FX3GMDIBFA6CJ4 l=C7HRFPF3BLGF3YR4DY5KX3SMBE seq=1 sig=o908WmNp7LibOfPsr4btQwatZJ5URBr2ZAuxvK4UWHlsB9sUOTJQaGAlLPVAhM__XJesCHxLISo94z5Z2a463gA
C7HRFPF3BLGF3YR4DY5KX3SMBE    86900   IN    TXT   enrtree://AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@morenodes.example.org
JWXYDBPXYWG6FX3GMDIBFA6CJ4    86900   IN    TXT   enrtree-branch:2XS2367YHAXJFGLZHVAWLQD4ZY,H4FHT4B454P6UXFD7JCYQ5PWDY,MHTDO6TMUBRIA2XWG5LUDACK24
2XS2367YHAXJFGLZHVAWLQD4ZY    86900   IN    TXT   enr:-HW4QOFzoVLaFJnNhbgMoDXPnOvcdVuj7pDpqRvh6BRDO68aVi5ZcjB3vzQRZH2IcLBGHzo8uUN3snqmgTiE56CH3AMBgmlkgnY0iXNlY3AyNTZrMaECC2_24YYkYHEgdzxlSNKQEnHhuNAbNlMlWJxrJxbAFvA
H4FHT4B454P6UXFD7JCYQ5PWDY    86900   IN    TXT   enr:-HW4QAggRauloj2SDLtIHN1XBkvhFZ1vtf1raYQp9TBW2RD5EEawDzbtSmlXUfnaHcvwOizhVYLtr7e6vw7NAf6mTuoCgmlkgnY0iXNlY3AyNTZrMaECjrXI8TLNXU0f8cthpAMxEshUyQlK-AM0PW2wfrnacNI
MHTDO6TMUBRIA2XWG5LUDACK24    86900   IN    TXT   enr:-HW4QLAYqmrwllBEnzWWs7I5Ev2IAs7x_dZlbYdRdMUx5EyKHDXp7AV5CkuPGUPdvbv1_Ms1CPfhcGCvSElSosZmyoqAgmlkgnY0iXNlY3AyNTZrMaECriawHKWdDRk2xeZkrOXBQ0dfMFLHY4eENZwdufn1S1o

客户端协议

要在给定的 DNS 名称(例如 “mynodes.org”)处查找节点:

  1. 解析名称的 TXT 记录,并检查它是否包含有效的 “enrtree-root=v1” 条目。 假设条目中包含的 enr-root 哈希为 “CFZUWDU7JNQR4VTCZVOJZ5ROV4”。
  2. 根据已知的公钥验证根上的签名,并检查序列号是否大于或等于该名称的任何先前看到的数字。
  3. 解析哈希子域名的 TXT 记录,例如 “CFZUWDU7JNQR4VTCZVOJZ5ROV4.mynodes.org”,并验证内容是否与哈希匹配。
  4. 下一步取决于找到的条目类型:
    • 对于 enrtree-branch:解析哈希列表并继续解析它们(第 3 步)。
    • 对于 enr:解码,验证节点记录并将其导入到本地节点存储。

在遍历期间,客户端必须跟踪已解析的哈希和域名,以避免进入无限循环。 以随机顺序遍历树最符合客户端的利益。

客户端实现应避免在正常操作期间一次下载整个树。 最好在需要时通过 DNS 请求条目,即在客户端寻找对等方时。

理由

为什么选择 DNS?

我们选择 DNS 作为分发媒介,因为它始终可用,即使在限制性网络条件下也是如此。 该协议提供低延迟,并且 DNS 查询的答案可以由中间解析器缓存。 不需要自定义服务器软件。 可以使用各自的客户端库将节点列表部署到任何 DNS 提供商,例如 CloudFlare DNS、dnsimple、Amazon Route 53。

为什么这是一个 merkle 树?

作为一个 merkle 树,任何节点列表都可以通过根上的单个签名进行身份验证。 哈希子域名保护列表的完整性。 最坏的情况下,中间解析器可以阻止对列表的访问或不允许对其进行更新,但不能破坏其内容。 序列号可防止将根替换为旧版本。

客户端同步更新可以递增地完成,这对于大型列表很重要。 树的单个条目足够小,可以放入单个 UDP 数据包中,从而确保与仅提供基本 UDP DNS 的环境兼容。 树格式也适用于缓存解析器:只有树的根需要较短的 TTL。 中间条目和叶子可以缓存数天。

为什么存在链接子树?

列表之间的链接启用联合和信任网络功能。 大型列表的运营商可以将维护委托给其他列表提供商。 如果两个节点列表相互链接,则用户可以使用任一列表并从两者获取节点。

链接子树与包含 ENR 的树是分开的。 这样做是为了使客户端实现能够独立同步这些树。 想要获得尽可能多节点的客户端将首先同步链接树,并将所有链接的名称添加到同步范围。

安全注意事项

通过 DNS 进行发现的安全性低于通过 DHT 进行发现,因为它依赖于受信任的方定期发布记录。 该参与者可以轻松地通过仅发布其控制的节点记录来使引导节点黯然失色。

版权

CC0 下放弃版权及相关权利。

Citation

Please cite this document as:

Felix Lange (@fjl), Péter Szilágyi (@karalabe), "EIP-1459: 通过 DNS 进行节点发现 [DRAFT]," Ethereum Improvement Proposals, no. 1459, September 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1459.