1 个不稳定版本
0.1.0-alpha.5 | 2021年1月28日 |
---|
#6 in #others
44KB
853 行
Crabby DNS
一个简单的 Rust DNS 服务器,有助于加深我团队办公时间讨论的理解。
在构建此项目时,我参考了以下项目或文档:
如何构建
- 使用 rustup 在本地机器上安装 Rust 工具链。
- 导航到您的已检出存储库,并运行
cargo build
如何熟悉 crate
- 使用
cargo doc --open
生成 crate 文档并查看。
如何运行它
- 可以使用
cargo test
运行单元测试套件。 - 为了实际运行它,请查看
cargo run -- --help
以及下面的部分。
DNS Stub 解析器
目前,Crabby DNS Stub 解析器实现了 IETF RFC 1035 中一些最基本的相关部分,可能甚至还不够正确。目前仅支持类 IN
的 A
RRs。
通过 CLI 指定查询域名,可选地指定查询类型和查询类。Stub 解析器将把 UDP 套接字的接口地址绑定和端口选择委托给操作系统。您的查询将被序列化为具有头部和问题部分的查询类型 DNS 协议消息,并发送到配置的 DNS 服务器。然后监听响应(阻塞)并将其反序列化为响应类型的 DNS 协议消息,其中包含服务器响应的任何部分和数据。
- 通过
cargo run -- stub --help
调用特定子命令的帮助
示例
$ cargo run -- stub -@ 8.8.8.8 -d google.com
Connected to 8.8.8.8:53 from 10.0.2.15:43506
Working on the DNS transaction now...
#################################################
# DNS QUESTION MESSAGE #
#################################################
Header {
id: 0,
message_type: Query,
op_code: Query,
authoritative_answer: false,
truncation: false,
recursion_desired: true,
recursion_available: false,
authentic_data: false,
checking_disabled: false,
response_code: NoError,
question_count: 1,
answer_count: 0,
authority_count: 0,
additional_count: 0,
}
Question {
domain_name: DomainName(
"google.com",
),
qtype: RRType(
A,
),
qclass: RRClass(
IN,
),
}
#################################################
# DNS RESPONSE MESSAGE #
#################################################
Header {
id: 0,
message_type: Response,
op_code: Query,
authoritative_answer: false,
truncation: false,
recursion_desired: true,
recursion_available: true,
authentic_data: false,
checking_disabled: false,
response_code: NoError,
question_count: 1,
answer_count: 1,
authority_count: 0,
additional_count: 0,
}
Question {
domain_name: DomainName(
"google.com",
),
qtype: RRType(
A,
),
qclass: RRClass(
IN,
),
}
ResourceRecord {
domain_name: DomainName(
"google.com",
),
rrtype: A,
rrclass: IN,
ttl: 102,
rrdata_len: 4,
rrdata: A(
172.217.3.110,
),
}
DNS数据报反序列化器
- 通过以下命令调用特定子命令的帮助:
cargo run -- deserialize --help
- 您需要一个DNS数据报来输入到程序中。在
/data
文件夹中提供了原始形式的查询及其响应的示例。 - 您可以通过使用netcat监听没有DNS服务器监听的端口,然后在该端口上使用dig来生成自己的查询。
- 在一个终端中运行以下命令:
nc -u -l 1053 > query.pkt
- 在另一个终端中运行以下命令:
dig +retry=0 -p 1053 @127.0.0.1 +noedns google.com
- 在一个终端中运行以下命令:
- 您可以通过使用netcat将查询UDP数据报作为输入重定向到DNS解析器(如Google的8.8.8.8)并将响应重定向到捕获文件来生成此查询的响应。
nc-u8.8.8.8 53 <query.pkt>response.pkt
- 如果需要,您可以将数据包捕获以十六进制形式查看
hexdump-C响应.pkt
- 将所有这些结合起来,您就可以调用Crabby DNS了
cargorun --deserialize -f ./response.pkt
示例
$ nc -u -l 1053 > query.pkt &
[2] 28112
$ dig +retry=0 -p 1053 @127.0.0.1 +noedns google.com
; <<>> DiG 9.16.1-Ubuntu <<>> +retry -p 1053 @127.0.0.1 +noedns google.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
$ kill 28112
[2]- Terminated nc -u -l 1053 > query.pkt
$ nc -u 8.8.8.8 53 < query.pkt > response.pkt
^C
$ hexdump -C response.pkt
00000000 6e 04 81 80 00 01 00 01 00 00 00 00 06 67 6f 6f |n............goo|
00000010 67 6c 65 03 63 6f 6d 00 00 01 00 01 c0 0c 00 01 |gle.com.........|
00000020 00 01 00 00 00 15 00 04 ac d9 0c ae |............|
0000002c
$ cargo run -- deserialize -f ./response.pkt
#########################################
# DNS MESSAGE #
#########################################
Header {
id: 28164,
message_type: Response,
op_code: Query,
authoritative_answer: false,
truncation: false,
recursion_desired: true,
recursion_available: true,
authentic_data: false,
checking_disabled: false,
response_code: NoError,
question_count: 1,
answer_count: 1,
authority_count: 0,
additional_count: 0,
}
Question {
domain_name: DomainName(
"google.com",
),
qtype: RRType(
A,
),
qclass: RRClass(
IN,
),
}
ResourceRecord {
domain_name: DomainName(
"google.com",
),
rrtype: A,
rrclass: IN,
ttl: 21,
rrdata_len: 4,
rrdata: A(
172.217.12.174,
),
}
依赖项
~1MB
~11K SLoC