8000 GitHub - danstiner/rust-toy-dns
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

danstiner/rust-toy-dns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rust-toy-dns

A toy DNS server for learning about the Domain Name System and high performance networking in Rust.

If you are looking for a non-toy DNS server written in Rust, check out trust-dns.

Getting Started

cargo run

Testing

cargo run &
dig @127.0.0.1 -p 8080 +noedns google.com

Capturing traffic

netcat -ul 5300 > query.bin &
dig @127.0.0.1 -p 5300 example.com
# kill netcat
cat query.bin | nc -u 1.1.1.1 53 | tee response.bin

Security

Disclaimer: This is a personal project, I am not a security expert and make no guarantee of security.

The history of DNS security is a bit of a mess, I've made a best effort to navigate it and implement mitigations for known issues.

Cache Poisoning Attacks

With only a 16 bit transation ID and no cryptographic verification, DNS over UDP is vulnerable to an attacker injecting malicious responses. If no IP verification is done and the source port can be guessed, an attacker can simply send a query as normal and then inject a few thousand malicious response packets with guessed transaction IDs until a collision happens. See also [1] [2].

Mitigation:

  • UDP source port is randomized for each query, this adds 14-16 bits of entropy
  • Transaction ID is randomized for each query using a cryptographic generator
  • Responses must originate from the IP address the query was sent to

Cache Snooping Attacks

If multiple clients share a caching DNS server, they can both time responses for a domain and look at the returned TTL values to determine if a domain was previously queried and if so how long ago it was cached.

Mitigation:

  • Optionally zero out TTL values on responses
  • Ignore non-recursive queries to caching server

Other Attacks

Mitigation:

  • Separated DNS server and recursive resolver functionality (DNS servers and recursive resolvers should never run on the same IP address)
  • No TCP support for now, it is relatively easy to cache poison because only the first packet in multi-packet responses include the transaction ID
  • Only IN and ANY question classes are allowed for implementation simplicity

On DNSSEC

A set of security extensions introduced in 1997 that have failed to reach wide acceptance and have a number of critisims. Implementation would add substantial complexity. I am more interested in pursuing modern alternatives like DNSCrypt, DNS over TLS, or DNS over HTTPS.

TODO

  • Apply one week TTL limit to all responses
  • Cache negative responses
  • Truncate to-long responses (and set TC bit)
  • Support for extended UDP responses
  • Response compression & better packet cursor - https://datatracker.ietf.org/doc/html/rfc1035#section-4.1.4
  • Fuzz testing
  • Benchmarking
  • Initialize from from resolver.conf etc
  • Increase incoming UDP socket buffer size (similar to socket_tryreservein, something like 128KB is enough)
  • Recursive resolver (note http://cr.yp.to/djbdns/separation.html, though I never intend this to be an authoritative server)
  • DNSCrypt, DNS over TLS, or DNS over HTTPS support
  • TODO: Use cryptographic generator to select ports instead of relying on Linux's behavior of finding an open port when binding to port zero. There are two main issues with Linux's behavior. First, older kernels have a "trivially predictable" prandom_u32 implementation used to select a port. Newer kernels utilize SipHash which is a "PITA" to guess, but still not cryptographically secure. Second, Linux selects from a relatively small set of source ports. Specifically it prefers to use odd ports for outgoing connections, and only from the configured ephemeral port range (net.ipv4.ip_local_port_range) which is usually 32768-60999. That's effectively one quarter of the available ports, meaning instead of 16 bits of security against cache poisoning we get under 14 bits, a meaningful difference.

Notes

Inspired by https://github.com/EmilHernvall/dnsguide.

Written with reference to:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0