Digit

digit

Digit is a DNS client side tool that can be used to perform DNS queries via different protocols such as UDP, TCP, TLS. It tracks the current Specification for DNS over TLS, draft-ietf-dprive-dns-over-tls-09, enabling direct TLS on port 853 by default, with TCP, STARTTLS and other protocols as options. This tool was primarily built to evaluate the client side latency of DNS over TCP and TLS, as described in the paper Connection-Oriented DNS to Improve Privacy and Security. It is experimental and not suitable for production use. With some modifications it can be used as stub resolver which supports multiple protocols. A README in the package has detailed instructions about how to use this software.

Documentation

% digit(1) % Liang Zhu liangzhu@isi.edu, Zi Hu zihu@outlook.com % April 7, 2016

NAME

digit - a tool to perform DNS query with different protocols

SYNOPSIS

Digit is a DNS tool to perform DNS queries with different protocols such as UDP, TCP, TLS. It supports TCP/TLS connection reuse, query pipelining. For TLS, it supports both gnutls and OpenSSL. It also supports using TCP fast open (see Examples).

It uses port 853 for TLS, and port 53 for both TCP and UDP by default. If no protocol is given, all the queries are sent by TLS on port 853 without TLS negotiation (see Proposed Standard: Specification for DNS over TLS)

This tool was primarily built for testing the performance of DNS queries over TLS and TCP. It is experimental and not suitable for production use. It uses the default resolver library in glibc. Due to old version of the resolver library, some RR types (such as RRSIG) are not recognized and they will be printed as decimal number (46 for RRSIG).

Currently, it only supports servers with IPv4 addresses.

OPTIONS

-f FILE, --dnslist-file=FILE
Specify input file that contains a list of DNS names with one name per line.
-r RESOLVER, --dns-resolver=RESOLVER
Specify the resolver to send queries to. It could be a hostname or an IPv4 address. Currently IPv6 is not supported in this tool.
-p PORT, --port-number=PORT
Specify resolver port number, 853 for TLS and 53 for both TCP and UDP by default
-t PROTOCOL, --protocol=PROTOCOL
this could be tcp/udp/tls/ssl/ptcp/cudp/ptls/ptcpnp/ptlsnp/pssl
-i TIME, --interval=TIME
interval between queries
-n NUMBER, --num-queries=NUMBER
total number of queries to send
-e, --enable-starttls
send query over tls with negotiation (a dummy edns query)
-d, --disable-nagle
disable nagle
-v, --validate-ca
validate CA
-o, --enable-tcpfast
enable TCP fastopen
-P, -enable-padding
enable EDNS(0) Padding of queries
-V, --verbose
print details of responses (if not specified, we only print latency stats)
-h, --help
show this message

COMPILE

We build digit on Fedora where it requires these packages: openssl-devel

It should build on other Unixes with similar libraries.

If you build it from the source tree, bootstrap with:

aclocal && automake --add-missing && autoconf && ./configure
make

RUN

To run the code, you need to put all the DNS names that you want to query in a file, one domain per line. Digit performs DNS query for each domain name in the input file and output some stats information.

sample input data:

www.google.com
www.facebook.com

output fsdb schema:

#fsdb   index   t_complete  t_avg   t_individual    t_sum   t_mean  id  query_send_ts   response_receive_ts program_start_ts

index: query index

t_complete: time elapsed when all queries got responses.

t_avg: equals to t_complete/(# of queries)

t_individual: time used for each query ( equals to response_receive_ts - query_send_ts)

t_sum: sum(t_individual)

t_mean: equals to t_sum/(# of queries)

id: dns ID used in the query

query_send_ts: timestamp when the query is sent

response_receive_ts: timestamp when the response for this query is received.

program_start_ts: timestamp when the program is started

sample output:

#fsdb   index   t_complete  t_avg   t_individual    t_sum   t_mean  id  query_send_ts   response_receive_ts program_start_ts
1   0.096254    0.096254    0.096254    0.096254    0.096254    19383   1414541062.314742   1414541062.410995   1414541062.314741
2   0.254078    0.127039    0.157802    0.254056    0.127028    19384   1414541062.411016   1414541062.568818   1414541062.314741

use -V option to print detailed information in responses

EXAMPLES

Below are a few examples of using digit to perform DNS queries:

  1. send queries

    To query all DNS names in “names.txt”, run:

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port
    
  2. query with different protocols

    You can test the query with other protocols by setting the -t options. Available options for -t are “tcp/udp/tls/ssl/ptcp/cudp/ptls/ptcpnp/ptlsnp/pssl”

    query over TCP:

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port -t tcp
    

    query over TLS:

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port -t TLS
    

    The difference between “ssl” and “tls” options: when using “tls”, the session is built with gnutls, while the session is built with OpenSSl when using “ssl”

    “ptcp” makes the code to reuse tcp connection, all the queries are sent over the same tcp connection back to back.

    For example:

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port -t ptcp
    

    Both “ptcp” and “ptcpnp” reuse the tcp connection. The difference is: “ptcp” pipelines all the query back to back, but “ptcpnp” doesn’t do pipelining, it sends one query, then wait for response before sending the next query.

    Similarly, you should be able to guess the meaning of “pssl/psslnp” and “ptls/ptlsnp”.

  3. enable certificate validation

    you can set the “-v” option to turn on certificate validation.

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port -t TLS -v
    

    However, make sure you have CAFILE in the right place: Right now the location of CAFILE is hard-coded in the code (in the file dns_query.cc) #define CAFILE “/etc/ssl/certs/ca-bundle.trust.crt”

  4. enable TCP fastopen

    Use “-o” option to enable TCP fastopen.

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port -t tcp -o
    

    However, you must first have TCP fastopen enabled in the kernel on your machine refer to this for how to enable TCP fastopen in the kernel.

  5. enable TLS negotiation

    Enable starttls (send a dummy query with TO bit set for TLS negotiation). By default, it is disabled and all queries are sent over TLS directly.

     ./digit -f names.txt -r your_resolver_IP -p your_resolver_port -t ssl -e