Crates.io | crabby_dns |
lib.rs | crabby_dns |
version | 0.1.0-alpha.5 |
source | src |
created_at | 2021-01-28 23:49:14.368922 |
updated_at | 2021-01-28 23:49:14.368922 |
description | A DNS nameserver system intended to be a learning project both for myself and as an aide in teaching others more about DNS. |
homepage | |
repository | |
max_upload_size | |
id | 347823 |
size | 50,413 |
A simple DNS server in Rust to help contribute further understanding to my team's office hours discussions.
I made significant reference to the following projects and/or documents in building this:
cargo build
cargo doc --open
to generate crate documentation and view it.cargo test
cargo run -- --help
as well as the sections below.Right now the Crabby DNS stub resolver implements some of the most basic relevant pieces of
IETF RFC 1035, and probably not even that correctly.
Only A
RRs of class IN
are currently supported.
Via the CLI, you specify a query domain name, and optionally a query type and query class. The stub resolver will delegate interface address binding and port selection for the UDP socket to the OS. Your query will be serialized into a DNS protocol message of query type with a header and question section and sent to the configured DNS server. The response will then be listened for (blocking) and deserialized into a DNS protocol message of response type with whatever sections + data the server responded with.
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,
),
}
cargo run -- deserialize --help
/data
foldernc -u -l 1053 > query.pkt
in one terminaldig +retry=0 -p 1053 @127.0.0.1 +noedns google.com
in anothernc -u 8.8.8.8 53 < query.pkt > response.pkt
hexdump -C response.pkt
cargo run -- 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,
),
}