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.
(2016-05-12); current release
- add EDNS(0) Padding patch contributed by Alexander Mayrhofer
- fix bug: starttls error and change command line option "-e"
- fix bug: RR format error when printing question section
- fix bug: error in gnutls handshake
- choose default port based on protocol (53 for UDP and TCP, 853 for TLS)
- update README for recent changes
- use TLS and port 853 by default
- STARTTLS and other protocols as options
- add EDNS0 patch contributed by Warren Kumari. Thanks!
- set DO (DNSSEC OK) bit for queries by default
- add support for MAC OS (now we support Fedora 20, Ubuntu, CentOS and MacOS).
- add verbose print (use -V to print out received DNS responses, in addition to the latency statistics)
- we check both the query name and TO bit when negotiate TLS (we recognize TLS negotiation when either query name is "STARTTLS" or TO bit is set).
- support using hostname (so you can specify the option -r with the resolver's hostname, we used to only support IP)
- add autoconf and automake.
- get rid of the BIND library, the code can be compiled and run without BIND.
- fix a few small bugs.
- add support for CentOS.
- this version includes proper configuration support and should build cleanly on Fedora 20 and Centos 6. Gnutls can be disabled with the configure option --without-gnutls.
initial "1.1" release
initial "0.1" release
% digit(1) % Liang Zhu email@example.com, Zi Hu firstname.lastname@example.org % April 7, 2016
digit - a tool to perform DNS query with different protocols
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.
- -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
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
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:
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_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
#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
Below are a few examples of using digit to perform DNS queries:
To query all DNS names in “names.txt”, run:
./digit -f names.txt -r your_resolver_IP -p your_resolver_port
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.
./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”.
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”
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.
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