Skip to content

Commit

Permalink
DNSTAP update, encryption indexer
Browse files Browse the repository at this point in the history
- `dnstap`: Fix #265:
  - Require dnswire v0.3.0+ for new protocol types and message types
  - Add support for DNSTAP's DOT, DOH and DNSCrypt socket protocols
  - Add support for `UPDATE_QUERY` and `UPDATE_RESPONSE` message types, interpret them as `AUTH_`
- Add indexer `encryption` to index encrypted DNS vid DNSTAP
- Add test for encrypted DNS via DNSTAP
- Fix other DNSTAP tests
- `transport_index`: Fix typo in code documentation
  • Loading branch information
jelu committed Jan 27, 2022
1 parent 3d4da96 commit 37df703
Show file tree
Hide file tree
Showing 21 changed files with 567 additions and 49 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ AC_ARG_ENABLE(threads,
use_dnstap=no
AC_ARG_ENABLE([dnstap], [AS_HELP_STRING([--enable-dnstap], [DNSTAP input support])], [
AC_DEFINE([USE_DNSTAP], [1], [Define to 1 if DNSTAP support is built in.])
PKG_CHECK_MODULES([libdnswire], [libdnswire])
PKG_CHECK_MODULES([libdnswire], [libdnswire >= 0.3.0])
PKG_CHECK_MODULES([libuv], [libuv])
use_dnstap=yes
])
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Priority: optional
Maintainer: Jerry Lundström <lundstrom.jerry@gmail.com>
Build-Depends: debhelper (>= 10), build-essential, automake, autoconf,
libpcap-dev, netbase, libgeoip-dev, pkg-config, libmaxminddb-dev,
libdnswire-dev, libuv1-dev, python3 (>= 3.5)
libdnswire-dev (>= 0.3.0), libuv1-dev, python3 (>= 3.5)
Standards-Version: 3.9.4
Homepage: https://www.dns-oarc.net/oarc/data/dsc
Vcs-Git: https://github.com/DNS-OARC/dsc.git
Expand Down
2 changes: 1 addition & 1 deletion rpm/dsc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
BuildRequires: pkgconfig
BuildRequires: dnswire-devel
BuildRequires: dnswire-devel >= 0.3.0
BuildRequires: libuv-devel
BuildRequires: python3
Requires: python3
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ dsc_SOURCES = asn_index.c certain_qnames_index.c client_index.c \
ext/base64.c ext/lookup3.c \
pcap_layers/pcap_layers.c \
pcap-thread/pcap_thread.c \
dnstap.c
dnstap.c encryption_index.c
dist_dsc_SOURCES = asn_index.h base64.h certain_qnames_index.h client_index.h \
client_subnet_index.h compat.h config_hooks.h country_index.h dataset_opt.h \
dns_ip_version_index.h dns_message.h dns_protocol.h dns_source_port_index.h \
Expand All @@ -43,7 +43,7 @@ dist_dsc_SOURCES = asn_index.h base64.h certain_qnames_index.h client_index.h \
tld_index.h transport_index.h xmalloc.h response_time_index.h tld_list.h \
pcap_layers/byteorder.h pcap_layers/pcap_layers.h \
pcap-thread/pcap_thread.h \
dnstap.h input_mode.h knowntlds.inc
dnstap.h input_mode.h knowntlds.inc encryption_index.h
dsc_LDADD = $(PTHREAD_LIBS) $(libmaxminddb_LIBS) \
$(libdnswire_LIBS) $(libuv_LIBS)
man1_MANS = dsc.1 dsc-psl-convert.1
Expand Down
2 changes: 2 additions & 0 deletions src/dns_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include "dns_ip_version_index.h"
#include "dns_source_port_index.h"
#include "response_time_index.h"
#include "encryption_index.h"

#include "ip_direction_index.h"
#include "ip_proto_index.h"
Expand Down Expand Up @@ -118,6 +119,7 @@ static indexer indexers[] = {
{ "ip_direction", 0, ip_direction_indexer, ip_direction_iterator },
{ "ip_proto", 0, ip_proto_indexer, ip_proto_iterator, ip_proto_reset },
{ "ip_version", 0, ip_version_indexer, ip_version_iterator, ip_version_reset },
{ "encryption", 0, encryption_indexer, encryption_iterator },
{ 0 }
};

Expand Down
22 changes: 15 additions & 7 deletions src/dns_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,22 @@ typedef struct dns_message dns_message;

#define MAX_QNAME_SZ 512

enum transport_encryption {
TRANSPORT_ENCRYPTION_UNENCRYPTED = 0,
TRANSPORT_ENCRYPTION_DOT = 1,
TRANSPORT_ENCRYPTION_DOH = 2,
TRANSPORT_ENCRYPTION_DNSCrypt = 3,
};

struct transport_message {
struct timeval ts;
inX_addr src_ip_addr;
inX_addr dst_ip_addr;
unsigned short src_port;
unsigned short dst_port;
unsigned char ip_version;
unsigned char proto;
struct timeval ts;
inX_addr src_ip_addr;
inX_addr dst_ip_addr;
unsigned short src_port;
unsigned short dst_port;
unsigned char ip_version;
unsigned char proto;
enum transport_encryption encryption;
};

struct dns_message {
Expand Down
18 changes: 18 additions & 0 deletions src/dnstap.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,22 @@ static int _set_proto(transport_message* tm, const struct dnstap* m)
case DNSTAP_SOCKET_PROTOCOL_TCP:
tm->proto = IPPROTO_TCP;
break;
case DNSTAP_SOCKET_PROTOCOL_DOT:
tm->proto = IPPROTO_TCP;
tm->encryption = TRANSPORT_ENCRYPTION_DOT;
break;
case DNSTAP_SOCKET_PROTOCOL_DOH:
tm->proto = IPPROTO_TCP;
tm->encryption = TRANSPORT_ENCRYPTION_DOH;
break;
case DNSTAP_SOCKET_PROTOCOL_DNSCryptUDP:
tm->proto = IPPROTO_UDP;
tm->encryption = TRANSPORT_ENCRYPTION_DNSCrypt;
break;
case DNSTAP_SOCKET_PROTOCOL_DNSCryptTCP:
tm->proto = IPPROTO_TCP;
tm->encryption = TRANSPORT_ENCRYPTION_DNSCrypt;
break;
default:
return -1;
}
Expand Down Expand Up @@ -518,6 +534,7 @@ static int dnstap_handler(const struct dnstap* m)

switch (dnstap_message_type(*m)) {
case DNSTAP_MESSAGE_TYPE_AUTH_QUERY:
case DNSTAP_MESSAGE_TYPE_UPDATE_QUERY:
if (!dnstap_message_has_query_message(*m) || !dnstap_message_has_query_address(*m)) {
dsyslogf(LOG_ERR, "DNSTAP: Missing parts of %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
break;
Expand Down Expand Up @@ -552,6 +569,7 @@ static int dnstap_handler(const struct dnstap* m)
break;

case DNSTAP_MESSAGE_TYPE_AUTH_RESPONSE:
case DNSTAP_MESSAGE_TYPE_UPDATE_RESPONSE:
if (!dnstap_message_has_response_message(*m) || !dnstap_message_has_query_address(*m)) {
dsyslogf(LOG_ERR, "DNSTAP: Missing parts of %s", DNSTAP_MESSAGE_TYPE_STRING[dnstap_message_type(*m)]);
break;
Expand Down
7 changes: 7 additions & 0 deletions src/dsc.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,12 @@ There are a few configuration options to control how response time statistics
are gathered and handled, please see CONFIGURATION.
NOTE: Only one instance of this indexer can be used in a dataset, this is due
to the state to stores and the design of DSC.
.TP
\fBencryption\fR
Indicates whether the DNS message is carried over an encrypted connection,
for example DNS-over-TLS (DOT) or DNS-over-HTTPS (DOH).
This information is only available via DNSTAP and if supported by the
software generating it.
.SH "DNS FILTERS"
You must specify one or more of the following filters (separated by commas)
on the \fBdataset\fR line.
Expand Down Expand Up @@ -952,6 +958,7 @@ dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
#dataset servfail_qname dns ALL:null Qname:qname servfail-only,replies-only;
#dataset ad_qname dns ALL:null Qname:qname authentic-data-only,replies-only;
#dataset label_count dns All:null LabelCount:label_count any;
#dataset encryption dns All:null Encryption:encryption queries-only;

#statistics_interval 60;
#no_wait_interval;
Expand Down
1 change: 1 addition & 0 deletions src/dsc.conf.sample.in
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
#dataset dns_ip_version_vs_qtype dns IPVersion:dns_ip_version Qtype:qtype queries-only;
#dataset response_time dns All:null ResponseTime:response_time;
#dataset label_count dns All:null LabelCount:label_count any;
#dataset encryption dns All:null Encryption:encryption queries-only;

# datasets for collecting data on priming queries at root nameservers
#dataset priming_queries dns Transport:transport EDNSBufSiz:edns_bufsiz priming-query,queries-only;
Expand Down
73 changes: 73 additions & 0 deletions src/encryption_index.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2008-2022, OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"

#include "encryption_index.h"

#include "md_array.h"

int encryption_indexer(const dns_message* m)
{
return m->tm->encryption;
}

static int next_iter = 0;

int encryption_iterator(const char** label)
{
if (NULL == label) {
next_iter = 0;
return TRANSPORT_ENCRYPTION_DNSCrypt + 1;
}
switch (next_iter) {
case TRANSPORT_ENCRYPTION_UNENCRYPTED:
*label = "unencrypted";
break;
case TRANSPORT_ENCRYPTION_DOT:
*label = "dot";
break;
case TRANSPORT_ENCRYPTION_DOH:
*label = "doh";
break;
case TRANSPORT_ENCRYPTION_DNSCrypt:
*label = "dnscrypt";
break;
default:
return -1;
}
return next_iter++;
}
45 changes: 45 additions & 0 deletions src/encryption_index.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2008-2022, OARC, Inc.
* Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
* Copyright (c) 2003-2007, The Measurement Factory, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef __dsc_encryption_index_h
#define __dsc_encryption_index_h

#include "dns_message.h"

int encryption_indexer(const dns_message*);
int encryption_iterator(const char** label);

#endif /* __dsc_encryption_index_h */
13 changes: 10 additions & 3 deletions src/test/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ CLEANFILES = test*.log test*.trs \
test11.out* test11.pid knowntlds.txt.dist \
test12.out \
1458044657.tld_list.dist \
tld_list.dat
tld_list.dat \
dotdoh.dnstap.dist 1643283234.dscdata.xml

EXTRA_DIST =

TESTS = test1.sh test2.sh test3.sh test4.sh test6.sh test7.sh test8.sh \
test9.sh test10.sh test11.sh test12.sh test_dnstap_unixsock.sh \
test_dnstap_tcp.sh test_pslconv.sh
test_dnstap_tcp.sh test_pslconv.sh test_encrypted.sh

if USE_DNSTAP
TESTS += test5.sh
Expand Down Expand Up @@ -70,6 +71,11 @@ test12.sh: knowntlds.txt.dist 1458044657.pcap.dist
knowntlds.txt.dist: knowntlds.txt
ln -s "$(srcdir)/knowntlds.txt" knowntlds.txt.dist

test_encrypted.sh: dotdoh.dnstap.dist

dotdoh.dnstap.dist: dotdoh.dnstap
ln -s "$(srcdir)/dotdoh.dnstap" dotdoh.dnstap.dist

EXTRA_DIST += $(TESTS) \
1458044657.conf 1458044657.pcap 1458044657.json_gold 1458044657.xml_gold \
pid.conf pid.pcap \
Expand All @@ -88,4 +94,5 @@ EXTRA_DIST += $(TESTS) \
test12.conf knowntlds.txt \
dnstap_unixsock.conf dnstap_tcp.conf \
1458044657.tld_list \
public_suffix_list.dat tld_list.dat.gold
public_suffix_list.dat tld_list.dat.gold \
dnstap_encrypted.conf dnstap_encrypted.gold dotdoh.dnstap
38 changes: 38 additions & 0 deletions src/test/dnstap_encrypted.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
local_address 127.0.0.1;
run_dir ".";
minfree_bytes 5000000;
dnstap_file ./dotdoh.dnstap.dist;
dataset qtype dns All:null Qtype:qtype queries-only;
dataset rcode dns All:null Rcode:rcode replies-only;
dataset opcode dns All:null Opcode:opcode queries-only;
dataset rcode_vs_replylen dns Rcode:rcode ReplyLen:msglen replies-only;
dataset client_subnet dns All:null ClientSubnet:client_subnet queries-only max-cells=200;
dataset qtype_vs_qnamelen dns Qtype:qtype QnameLen:qnamelen queries-only;
dataset qtype_vs_tld dns Qtype:qtype TLD:tld queries-only,popular-qtypes max-cells=200;
dataset certain_qnames_vs_qtype dns CertainQnames:certain_qnames Qtype:qtype queries-only;
dataset client_subnet2 dns Class:query_classification ClientSubnet:client_subnet queries-only max-cells=200;
dataset client_addr_vs_rcode dns Rcode:rcode ClientAddr:client replies-only max-cells=50;
dataset chaos_types_and_names dns Qtype:qtype Qname:qname chaos-class,queries-only;
dataset idn_qname dns All:null IDNQname:idn_qname queries-only;
dataset edns_version dns All:null EDNSVersion:edns_version queries-only;
dataset edns_bufsiz dns All:null EDNSBufSiz:edns_bufsiz queries-only;
dataset do_bit dns All:null D0:do_bit queries-only;
dataset rd_bit dns All:null RD:rd_bit queries-only;
dataset tc_bit dns All:null TC:tc_bit any;
dataset idn_vs_tld dns All:null TLD:tld queries-only,idn-only;
dataset ipv6_rsn_abusers dns All:null ClientAddr:client queries-only,aaaa-or-a6-only,root-servers-net-only max-cells=50;
dataset transport_vs_qtype dns Transport:transport Qtype:qtype queries-only;
dataset client_port_range dns All:null PortRange:dns_sport_range queries-only;
dataset direction_vs_ipproto ip Direction:ip_direction IPProto:ip_proto any;
dataset ip_version ip All:null Version:ip_version any;
dataset dns_ip_version dns All:null Version:dns_ip_version any;
dataset qclass dns All:null Class:qclass any;
dataset qname dns All:null Name:qname any;
dataset qr_aa_bits dns Direction:ip_direction QRAABits:qr_aa_bits any;
dataset server dns All:null IP:server any;
dataset second_ld_vs_rcode dns Rcode:rcode SecondLD:second_ld replies-only max-cells=50;
dataset third_ld_vs_rcode dns Rcode:rcode ThirdLD:third_ld replies-only max-cells=50;
dataset label_count dns All:null LabelCount:label_count any;
dataset encryption dns All:null Encryption:encryption queries-only;
dump_reports_on_exit;
no_wait_interval;
Loading

0 comments on commit 37df703

Please sign in to comment.