DNS Spoofing

Submission Deadline:

The goals of this assignment are to:

  1. Create a prototype DNS stub resolver that is resilient to DNS poisoning
  2. Gain first-hand insight into trade-offs between two popular DNS security protocols

Stub Resolver

Using any networking and DNS message serialization libraries of your choice, implement a simple DNS stub resolver. Your resolver must export the following C99-compatible API:

/**
 * DNS security protocol.
 */
enum dns_security_t {
    DNS_SECURITY_NONE,
    DNS_SECURITY_DNSSEC,
    DNS_SECURITY_DNSCRYPT,
};

/**
 * Resolve a hostname, returning an array of IPv4 addresses.
 *
 * The caller is responsible for freeing any returned addresses.
 *
 * @param security Security protocol to use.
 * @param forwarder Forwarder address, or NULL.
 * @param hostname Hostname.
 * @return List of resolved IPv4 addresses, terminated by NULL.
 */
struct in_addr** resolve_hostname(const dns_security_t security,
                                  const struct in_addr* forwarder,
                                  const char* hostname);

Your implementation of resolve_hostname must be thread-safe. It must also implement mitigations against an off-path network adversary that seeks to poison the stub resolver cache.

DNSSEC

Using any cryptographic library of your choice, add DNSSEC support to your implementation of resolve_hostname. The forwarder provided to the function when security == DNS_SECURITY_DNSSEC must be NULL. You should embed a root server key and address into your library.

DNSCrypt

Add DNSCrypt support to your implementation of resolve_hostname. You may limit your implementation to the TCP variant of DNSCrypt. The forwarder provided to the function when security == DNS_SECURITY_DNSCRYPT must be NULL. You should embed a public DNSCrypt server and address into your library.

Evaluation Criteria

Your library will be evaluated using a number of test cases for both correctness and resilience to various DNS attacks. In particular, you should ensure that your implementation defends against relevant cache poisoning attacks and privacy leakage.

Submission Instructions

Commit and push the source code for your library to GitLab in the repository ${your_gitlab_user}/dns_spoofing. The latest commit on master will be considered your submitted solution. Your repository root must also contain a Dockerfile that will build an image that places your library at /usr/lib/libnetsec_dns.so.

Finally, commit a README.md that describes your implementation, the design choices you made, and justifications for those choices.