Rust 语言打造的安全 DNS 解决方案:Hickory DNS
在这个互联网高速发展的时代,DNS 作为网络世界的“电话簿”,其安全性和稳定性显得尤为重要。Hickory DNS 正是为了应对这一挑战而生。
项目起源
Hickory DNS 原本名为 Trust-DNS,后经过品牌重塑,加入了 hickory-dns 组织。它不仅继承了 Trust-DNS 的优秀基因,更在安全性和性能上进行了全面升级。
核心特性
-
安全性:从底层代码开始,Hickory DNS 就注重安全性,避免使用可能导致程序崩溃的代码。 -
稳定性:使用稳定的 Rust 语言,确保服务的稳定运行。 -
易用性:简化操作流程,让 DNS 服务更容易管理和维护。
模块组成
Hickory DNS 由多个模块组成,每个模块都有其独特的功能和用途:
-
Hickory DNS:提供 DNS 权威服务器的运行工具。 -
Proto:底层 DNS 库,为其他 Hickory DNS 库提供支持。 -
Client:用于向 DNS 服务器发送查询、更新和通知消息。 -
Server:托管 DNS 记录,支持守护进程形式运行。 -
Resolver:执行 DNS 解析,可替代操作系统的默认解析服务。
功能亮点
Hickory DNS 支持多种高级功能,包括 DNSSEC 验证、原子记录创建、记录比较和交换等。服务器端还支持 DNS-over-TLS 和 DNS-over-HTTPS,为数据传输提供加密保护。
使用方法
这假定你已经安装了 Rust[1] 稳定版。这些假定 hickory-dns 代码库已经被同步到本地系统:
git clone https://github.com/hickory-dns/hickory-dns.git
cd hickory-dns
前提条件
最低 Rust 版本
-
该项目当前的最低 rustc 版本为 1.67
-
OpenSSL 开发库(客户端和解析器中可选,最低版本 1.0.2)
Mac OS X: 使用 homebrew
brew install openssl
export OPENSSL_INCLUDE_DIR=`brew --prefix openssl`/include
export OPENSSL_LIB_DIR=`brew --prefix openssl`/lib
基于 Debian 的系统(包括 Ubuntu & Raspbian): 使用 apt-get
# 注意对于 openssl,TLS 需要至少 1.0.2 版本,
# 如果这是问题,可以禁用 TLS(在客户端),见下文。
$ apt-get install openssl
$ apt-get install libssl-dev pkg-config
测试
Hickory DNS 使用 just
进行构建工作流管理。尽管在项目根目录运行 cargo test
可以工作,但这并不全面。使用 cargo install just
安装 just
。
-
默认测试
这些适合在本地系统上运行。它们将为本地测试创建套接字,但不会尝试访问远程系统。测试也可以从 crate 目录运行,例如
client
或server
和cargo test
just default
-
默认特性测试
Hickory DNS 有许多特性,可以快速测试启用它们或不启用它们,支持三个目标,
default
,no-default-features
,all-features
:
just all-features
-
单独特性测试
Hickory DNS 有许多特性,每个单独的特性都可以独立测试,查看各个 crates 了解它们所有的特性,这里是一个不一定最新的列表:
dns-over-rustls
,dns-over-https-rustls
,dns-over-native-tls
,dns-over-openssl
,dns-dnssec-openssl
,dns-dnssec-openssl
,dns-dnssec-ring
,mdns
。每个特性都可以使用它自己作为just
的任务目标进行测试:
just dns-over-https-rustls
-
基准测试
等待 Rust 中的基准测试稳定。
构建
-
生产构建,从 hickory-dns
基础目录开始,要获取所有特性,只需传递--all-features
标志。
cargo build --release -p hickory-dns
运行
警告:Hickory DNS 仍在开发中,不建议在生产中运行。服务器目前仅是单线程的,它是非阻塞的,所以这应该允许它能够处理大多数内部负载。
-
验证版本
./target/release/hickory-dns --version
-
获取帮助
./target/release/hickory-dns --help
-
使用测试配置启动 hickory-dns
服务器
你可能不希望传递 -p
参数将在默认 DNS 端口上运行。对于 tls 特性,也有那些端口选项,见 hickory-dns --help
./target/release/hickory-dns -c ./tests/test-data/test_configs/example.toml -z ./tests/test-data/test_configs/ -p 24141
-
使用 dig
查询刚刚启动的服务器
dig @127.0.0.1 -p 24141 www.example.com
使用 hickory-resolver CLI
在 0.20
中可用
cargo install --bin resolve hickory-util
或从源代码,在 hickory-dns 目录中
cargo install --bin resolve --path util
示例:
$ resolve www.example.com.
Querying for www.example
.com. A from udp:8.8.8.8:53, tcp:8.8.8.8:53, udp:8.8.4.4:53, tcp:8.8.4.4:53, udp:[2001:4860:4860::8888]:53, tcp:[2001:4860:4860::8888]:53, udp:[2001:4860:4860::8844]:53, tcp:[2001:4860:4860::8844]:53
Success for query name: www.example.com. type: A class: IN
www.example.com. 21063 IN A 93.184.215.14
作为依赖项和自定义特性使用
客户端有一些特性,出于不同的原因,在嵌入其他软件时可以禁用。
-
dnssec-openssl
它是一个默认特性,所以需要将 default-features 设置为 false(这将禁用 hickory-dns 中所有其他默认特性)。在有其他加密库支持之前,这也会禁用 DNSSEC 验证。函数仍然存在,但在验证时总是返回错误。下面的例子将禁用所有默认特性并启用 OpenSSL,去掉"openssl"
以去掉对 OpenSSL 的依赖。 -
dnssec-ring
Ring 支持可以用于 RSA 和 ED25519 DNSSEC 验证。 -
dns-over-native-tls
使用native-tls
实现 DNS-over-TLS,仅在客户端和解析器中支持,不在服务器中。 -
dns-over-openssl
使用openssl
实现 DNS-over-TLS,在服务器和客户端中支持,解析器没有默认的 CA 链。 -
dns-over-rustls
使用rustls
实现 DNS-over-TLS,仅在客户端和解析器中支持,不在服务器中。如果你希望使用纯 Rust 工具链,这是最佳选择。在客户端、解析器和服务器中支持。 -
dns-over-https-rustls
使用rustls
实现 DNS-over-HTTPS(并将启用 DNS-over-TLS),仅在客户端、解析器和服务器中支持。如果你希望使用纯 Rust 工具链,这是最佳选择。 -
mdns
实验性启用实验性的 mDNS 特性以及 DNS-SD。目前已知存在问题。
在依赖项中使用自定义特性:
[dependencies]
...
hickory-dns = { version = "*", default-features = false, features = ["dnssec-openssl"] }
在构建期间使用自定义特性:
$> cargo build --release --features dns-over-rustls
...
常见问题解答
-
为什么你要再建一个 DNS 服务器?
因为有 BIND 的所有安全通告。
使用 Rust 语义,应该可以开发出一个高性能且安全的 DNS 服务器,更能抵御攻击。
-
什么是 MSRV(最低稳定 Rust 版本)政策?
Hickory DNS 将努力支持与三个 Rust 版本向后兼容。
例如,如果
1.50
是当前版本,那么 MSRV 将是1.47
。版本只有在必要时才会增加,所以 MSRV 可能比这个政策所说的要旧。此外,MSRV 只支持no-default-features
构建,因为试图在依赖项上执行此政策是一个棘手的问题。
Hickory DNS
Hickory DNS 是一个基于 Rust 语言构建的 DNS 客户端、服务器和解析器,从底层设计上就注重安全性和可靠性。
这个代码仓库包含多个不同的组件:
库名称 | 描述 |
---|---|
Hickory DNS | 用于运行 DNS 权威服务器的二进制文件。 |
Proto | 原始 DNS 库,公开了不稳定的 API,仅供其他 Hickory DNS 库使用,不打算供最终用户使用。 |
Client | 用于直接向 DNS 服务器发送 查询 、更新 和 通知 消息。 |
Server | 用于托管 DNS 记录,也有一个 hickory-dns 二进制文件用于以守护进程形式运行。 |
Resolver | 利用客户端库执行 DNS 解析。可以替代标准操作系统解析功能。 |
注意 这个项目从 Trust-DNS 重新品牌为 Hickory DNS,并且已经转移到了 https://github.com/hickory-dns/hickory-dns 组织和代码仓库。
目标
-
构建一个具有现代特性的安全 DNS 服务器和客户端。 -
无恐慌(panics),所有代码都有保护。 -
仅使用安全的 Rust,并以适当的错误处理避免所有恐慌。 -
仅使用稳定的 Rust。 -
防御一定程度的 DDOS 攻击。 -
支持全局负载均衡功能选项。 -
使其操作简单。
状态
解析器
Hickory DNS 解析器是 Rust 应用程序中的本地 Rust 实现的存根解析器。解析器支持许多常见的查询模式,所有这些都可以配置在创建解析器时。它能够使用 Unix 和 Windows 上的系统配置。在 Windows 上有一个已知的问题,与注册大量接口有关,因此可能需要忽略系统配置。
解析器将正确跟随 CNAME 链以及 SRV 记录查找。有一个长期计划使解析器能够完全递归查询,但目前还不可能。
客户端
Hickory DNS 客户端旨在直接用于操作 DNS 服务器。它可以用于验证记录或更新支持 SIG0 和动态更新的服务器上的记录。客户端还能够验证 DNSSEC。到目前为止,NSEC3 验证尚未支持,但 NSEC 是支持的。有两种接口可以使用,一种是兼容 async/await 的 AsyncClient,另一种是易于使用的阻塞 Client。今天,Tokio 是执行 Runtime 所必需的。
客户端唯一实现
这些是 DNS 协议支持的标准。客户端将它们作为高级接口实现,这比较少见。
特性 | 描述 |
---|---|
SyncDnssecClient[2] | DNSSEC 验证 |
create[3] | 记录的原子创建,带有认证请求 |
append[4] | 验证记录的存在并向其追加 |
compare_and_swap[5] | 原子(取决于服务器)比较和交换 |
delete_by_rdata[6] | 删除特定记录 |
delete_rrset[7] | 删除整个记录集 |
delete_all[8] | 删除具有给定名称的所有记录集 |
notify[9] | 通知服务器重新加载区域 |
服务器
服务器代码已完成,守护进程支持 IPv4 和 IPv6,UDP 和 TCP。
目前没有办法限制 TCP 和 AXFR 操作,所以仍然不建议将其投入生产使用,因为 TCP 可以被用来 DOS 服务。
区域文件解析已完成并得到支持。目前没有分叉选项,服务器还没有线程化(尽管它使用异步 IO 实现,所以线程化可能没有太大好处)。在服务器可以被信任用于外部之前,还有很多工作要做。在私有网络的防火墙后面运行将是安全的。
区域签名支持已完成,要插入一个密钥存储,将带有 .key
后缀的 pem 编码 rsa 文件存储在初始区域文件所在的同一目录中。_注意_:这必须只能由当前用户读取。如果不存在,将会创建一个并写入到正确的位置。这也作为动态更新 SIG(0) 验证的初始密钥。要获取公钥,可以查询区域的 DNSKEY
记录。这需要提供给其他上游服务器以创建 DS
密钥。动态 DNS 也已完成,如果启用,将与区域文件一起存储带有 jrnl
后缀的日志文件。_注意_:如果密钥更改或更新,当前是操作员的责任从区域中删除唯一的公钥,这允许 DNSKEY
在密钥轮换期间存在一段不确定的时间。当前没有在线轮换密钥的选项,需要重启服务器进程。
服务器上的 DNS-over-TLS 和 DNS-over-HTTPS
服务器上的 TLS 支持是通过 pkcs12 der 文件管理的。文档在示例测试配置文件中捕获,example.toml[10]。服务器可以注册证书并使用 add_ca()
方法将其固定到客户端。或者,由于客户端使用 rust-native-tls 库,它应该可以与任何标准 CA 签名的证书一起使用。
DNS-over-TLS 和 DNS-over-HTTPS
DoT 和 DoH 都得到支持。这是通过使用 native-tls
、openssl
或 rustls
(目前只有 rustls
支持 DoH)中的一个来实现的。解析器需要注册有效的 DoT 或 DoH 解析器才能使用。
要与 Client
一起使用,应该使用 TlsClientConnection
或 HttpsClientConnection
。类似地,要与 tokio AsyncClient
一起使用,应该使用 TlsClientStream
或 HttpsClientStream
。目前不支持客户端认证,mTLS,还有一些问题正在解决中。TLS 对于服务器认证和连接隐私很有用。
要启用 DoT,必须启用 dns-over-native-tls
、dns-over-openssl
或 dns-over-rustls
中的一个功能,dns-over-https-rustls
用于 DoH。
DNSSEC 状态
目前,根密钥硬编码到系统中。这提供了 DNSKEY 和 DS 记录验证回根的能力。NSEC 已实现,但不是 NSEC3。
由于缓存尚未启用,已经注意到一些 DNS 服务器似乎限制了连接,验证 RRSIG 记录回根可能需要大量的额外查询来获取这些记录。
区域将在任何通过动态 DNS 的记录更新时自动重新签名。要启用 DNSSEC,必须启用 dnssec-openssl
或 dnssec-ring
中的一个功能。
实现的 RFC
-
RFC 8499[11]: 没有更多的主/从关系,以纪念 六月节[12]
基本操作
-
RFC 1035[13]: DNS 基础规范(查看解析器的缓存) -
RFC 2308[14]: DNS 查询的负缓存(查看解析器) -
RFC 2782[15]: 服务定位 -
RFC 3596[16]: IPv6 -
RFC 6891[17]: DNS 的扩展机制 -
RFC 6761[18]: 特殊用途域名(解析器) -
RFC 6762[19]: mDNS 多播 DNS(实验功能: mdns
) -
RFC 6763[20]: DNS-SD 服务发现(实验功能: mdns
) -
RFC ANAME[21]: 特定地址的 DNS 别名( ANAME
)
更新操作
-
RFC 2136[22]: 动态更新 -
RFC 7477[23]: DNS 中的父子同步
安全 DNS 操作
-
RFC 2931[24]: SIG(0) -
RFC 3007[25]: 安全动态更新 -
RFC 4034[26]: DNSSEC 资源记录 -
RFC 4035[27]: DNSSEC 的协议修改 -
RFC 4509[28]: DNSSEC 委托签名中的 SHA-256 -
RFC 5702[29]: DNSKEY 和 RRSIG 中用于 DNSSEC 的 SHA-2 算法与 RSA -
RFC 6844[30]: DNS 认证机构授权(CAA)资源记录 -
RFC 6698[31]: 基于 DNS 的命名实体认证(DANE)传输层安全(TLS)协议:TLSA -
RFC 6840[32]: DNSSEC 的澄清和实现说明 -
RFC 6944[33]: DNSKEY 算法实现状态 -
RFC 6975[34]: 信号加密算法理解 -
RFC 7858[35]: TLS 上的 DNS(特性: dns-over-rustls
,dns-over-native-tls
,或dns-over-openssl
) -
RFC DoH[36]: HTTPS 上的 DNS,DoH(特性: dns-over-https-rustls
)
正在进行或尚未实现的 RFC
基本操作
-
RFC 2317[37]: 无类 IN-ADDR.ARPA 委派
更新操作
-
RFC 1995[38]: 增量区域传输 -
RFC 1996[39]: 通知辅助服务器更新 -
Update Leases[40]: 动态 DNS 更新租约 -
Long-Lived Queries[41]: 带有通知的铃声
安全 DNS 操作
-
RFC 5155[42]: DNSSEC 哈希认证拒绝存在 -
DNSCrypt[43]: 受信任的 DNS 查询 -
S/MIME[44]: S/MIME 的域名
结语
Hickory DNS 是一个充满活力的开源项目,它不仅为 DNS 领域带来了新的选择,更为我们提供了一个更安全、更可靠的网络环境。
参考资料
Rust: https://www.rust-lang.org
[2]
SyncDnssecClient: https://docs.rs/hickory-client/latest/hickory_client/client/struct.SyncDnssecClient.html
[3]
create: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.create
[4]
append: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.append
[5]
compare_and_swap: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.compare_and_swap
[6]
delete_by_rdata: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.delete_by_rdata
[7]
delete_rrset: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.delete_rrset
[8]
delete_all: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.delete_all
[9]
notify: https://docs.rs/hickory-client/latest/hickory_client/client/trait.Client.html#method.notify
[10]
example.toml: https://github.com/hickory-dns/hickory-dns/blob/main/tests/test-data/test_configs/example.toml
[11]
RFC 8499: https://tools.ietf.org/html/rfc8499
[12]
六月节: https://en.wikipedia.org/wiki/Juneteenth
[13]
RFC 1035: https://tools.ietf.org/html/rfc1035
[14]
RFC 2308: https://tools.ietf.org/html/rfc2308
[15]
RFC 2782: https://tools.ietf.org/html/rfc2782
[16]
RFC 3596: https://tools.ietf.org/html/rfc3596
[17]
RFC 6891: https://tools.ietf.org/html/rfc6891
[18]
RFC 6761: https://tools.ietf.org/html/rfc6761
[19]
RFC 6762: https://tools.ietf.org/html/rfc6762
[20]
RFC 6763: https://tools.ietf.org/html/rfc6763
[21]
RFC ANAME: https://tools.ietf.org/html/draft-ietf-dnsop-aname-02
[22]
RFC 2136: https://tools.ietf.org/html/rfc2136
[23]
RFC 7477: https://tools.ietf.org/html/rfc7477
[24]
RFC 2931: https://datatracker.ietf.org/doc/html/rfc2931
[25]
RFC 3007: https://tools.ietf.org/html/rfc3007
[26]
RFC 4034: https://tools.ietf.org/html/rfc4034
[27]
RFC 4035: https://tools.ietf.org/html/rfc4035
[28]
RFC 4509: https://tools.ietf.org/html/rfc4509
[29]
RFC 5702: https://tools.ietf.org/html/rfc5702
[30]
RFC 6844: https://tools.ietf.org/html/rfc6844
[31]
RFC 6698: https://tools.ietf.org/html/rfc6698
[32]
RFC 6840: https://tools.ietf.org/html/rfc6840
[33]
RFC 6944: https://tools.ietf.org/html/rfc6944
[34]
RFC 6975: https://tools.ietf.org/html/rfc6975
[35]
RFC 7858: https://tools.ietf.org/html/rfc7858
[36]
RFC DoH: https://tools.ietf.org/html/draft-ietf-doh-dns-over-https-14
[37]
RFC 2317: https://tools.ietf.org/html/rfc2317
[38]
RFC 1995: https://tools.ietf.org/html/rfc1995
[39]
RFC 1996: https://tools.ietf.org/html/rfc1996
[40]
Update Leases: https://tools.ietf.org/html/draft-sekar-dns-ul-01
[41]
Long-Lived Queries: https://tools.ietf.org/html/draft-sekar-dns-llq-01
[42]
RFC 5155: https://tools.ietf.org/html/rfc5155
[43]
DNSCrypt: https://dnscrypt.org
原创文章,作者:速盾高防cdn,如若转载,请注明出处:https://www.sudun.com/ask/87592.html