Skip to content

Commit

Permalink
Merge pull request #7726 from rgacogne/dnsdist-redoh
Browse files Browse the repository at this point in the history
dnsdist: Add DNS over HTTPS support based on libh2o
  • Loading branch information
rgacogne committed Apr 23, 2019
2 parents d97c5dd + 50f53f0 commit 07f217c
Show file tree
Hide file tree
Showing 32 changed files with 1,698 additions and 132 deletions.
2 changes: 1 addition & 1 deletion build-scripts/travis.sh
Expand Up @@ -658,7 +658,7 @@ test_recursor() {

test_dnsdist(){
run "cd regression-tests.dnsdist"
run "DNSDISTBIN=$HOME/dnsdist/bin/dnsdist ./runtests -v"
run "DNSDISTBIN=$HOME/dnsdist/bin/dnsdist ./runtests -v --ignore-files='(?:^\.|^_,|^setup\.py$|^test_DOH\.py$)'"
run "rm -f ./DNSCryptResolver.cert ./DNSCryptResolver.key"
run "cd .."
}
Expand Down
2 changes: 2 additions & 0 deletions builder-support/debian/dnsdist/debian-stretch/rules
Expand Up @@ -28,6 +28,7 @@ override_dh_auto_clean:
dh_auto_clean

override_dh_auto_configure:
PKG_CONFIG_PATH=/opt/lib/pkgconfig \
./configure \
--enable-option-checking=fatal \
--host=$(DEB_HOST_GNU_TYPE) \
Expand All @@ -38,6 +39,7 @@ override_dh_auto_configure:
--infodir=\$${prefix}/share/info \
--libdir='$${prefix}/lib/$(DEB_HOST_MULTIARCH)' \
--libexecdir='$${prefix}/lib' \
--enable-dns-over-https \
--enable-dns-over-tls \
--enable-dnscrypt \
--enable-dnstap \
Expand Down
9 changes: 9 additions & 0 deletions builder-support/dockerfiles/Dockerfile.debbuild-prepare
Expand Up @@ -24,5 +24,14 @@ RUN tar xvf /sdist/pdns-recursor-${BUILDER_VERSION}.tar.bz2
@ENDIF

@IF [ ! -z "$M_dnsdist" ]
RUN if grep 'VERSION="9 (stretch)"' /etc/os-release; then \
mkdir /libh2o && cd /libh2o && \
apt-get install -q -y curl libssl-dev zlib1g-dev cmake && \
curl -L https://github.com/h2o/h2o/archive/v2.2.5.tar.gz | tar xz && \
CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.5 && \
make install && \
cd /pdns; \
fi

RUN tar xvf /sdist/dnsdist-${BUILDER_VERSION}.tar.bz2
@ENDIF
11 changes: 11 additions & 0 deletions builder-support/dockerfiles/Dockerfile.rpmbuild
Expand Up @@ -38,6 +38,17 @@ RUN if $(grep -q 'release 6' /etc/redhat-release); then \
@ENDIF

@IF [ ! -z "$M_dnsdist$M_all" ]
RUN if $(grep -q 'release 6' /etc/redhat-release); then \
true ; \
else \
mkdir /libh2o && cd /libh2o && \
yum install -y curl openssl-devel cmake && \
curl -L https://github.com/h2o/h2o/archive/v2.2.5.tar.gz | tar xz && \
CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.5 && \
make install && \
cd /pdns; \
fi

RUN if $(grep -q 'release 6' /etc/redhat-release); then \
scl enable devtoolset-7 -- builder/helpers/build-specs.sh builder-support/specs/dnsdist.spec; \
else \
Expand Down
4 changes: 3 additions & 1 deletion builder-support/specs/dnsdist.spec
Expand Up @@ -104,9 +104,11 @@ sed -i '/^ExecStart/ s/dnsdist/dnsdist -u dnsdist -g dnsdist/' dnsdist.service.i
--with-libcap \
--with-libsodium \
--enable-dnscrypt \
--enable-dns-over-https \
--enable-systemd --with-systemd=/lib/systemd/system \
--with-re2 \
--with-net-snmp
--with-net-snmp \
PKG_CONFIG_PATH=/opt/lib64/pkgconfig
%endif

%if 0%{?el6}
Expand Down
1 change: 1 addition & 0 deletions pdns/Makefile.am
Expand Up @@ -1484,6 +1484,7 @@ fuzz_target_dnsdistcache_SOURCES = \
dnsname.cc dnsname.hh \
dnsparser.cc dnsparser.hh \
dnswriter.cc dnswriter.hh \
doh.hh \
ednsoptions.cc ednsoptions.hh \
ednssubnet.cc ednssubnet.hh \
iputils.cc iputils.hh \
Expand Down
33 changes: 33 additions & 0 deletions pdns/dnsdist-carbon.cc
Expand Up @@ -146,6 +146,39 @@ try
}
}

#ifdef HAVE_DNS_OVER_HTTPS
{
const string base = "dnsdist." + hostname + ".main.doh.";
for(const auto& doh : g_dohlocals) {
string name = doh->d_local.toStringWithPort();
boost::replace_all(name, ".", "_");
boost::replace_all(name, ":", "_");
boost::replace_all(name, "[", "_");
boost::replace_all(name, "]", "_");

vector<pair<const char*, const std::atomic<uint64_t>&>> v{
{"http-connects", doh->d_httpconnects},
{"http1-queries", doh->d_http1queries},
{"http2-queries", doh->d_http2queries},
{"tls10-queries", doh->d_tls10queries},
{"tls11-queries", doh->d_tls11queries},
{"tls12-queries", doh->d_tls12queries},
{"tls13-queries", doh->d_tls13queries},
{"tls-unknown-queries", doh->d_tlsUnknownqueries},
{"get-queries", doh->d_getqueries},
{"post-queries", doh->d_postqueries},
{"bad-requests", doh->d_badrequests},
{"error-responses", doh->d_errorresponses},
{"valid-responses", doh->d_validresponses}
};

for(const auto& item : v) {
str<<base<<name<<"."<<item.first << " " << item.second << " " << now <<"\r\n";
}
}
}
#endif /* HAVE_DNS_OVER_HTTPS */

{
WriteLock wl(&g_qcount.queryLock);
std::string qname;
Expand Down
3 changes: 3 additions & 0 deletions pdns/dnsdist-console.cc
Expand Up @@ -345,6 +345,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
{ "addAction", true, "DNS rule, DNS action [, {uuid=\"UUID\"}]", "add a rule" },
{ "addConsoleACL", true, "netmask", "add a netmask to the console ACL" },
{ "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/resolver.cert\", \"/path/to/resolver.key\", {reusePort=false, tcpFastOpenSize=0, interface=\"\", cpus={}}", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter is a table of parameters" },
{ "addDOHLocal", true, "addr, certFile, keyFile [, urls [, vars]]", "listen to incoming DNS over HTTPS queries on the specified address using the specified certificate and key. The last two parameters are tables" },
{ "addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" },
{ "addLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\", cpus={}}]", "add `addr` to the list of addresses we listen on" },
{ "addCacheHitResponseAction", true, "DNS rule, DNS response action [, {uuid=\"UUID\"}]", "add a cache hit response rule" },
Expand Down Expand Up @@ -387,6 +388,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
{ "generateDNSCryptProviderKeys", true, "\"/path/to/providerPublic.key\", \"/path/to/providerPrivate.key\"", "generate a new provider keypair" },
{ "getBind", true, "n", "returns the listener at index n" },
{ "getDNSCryptBind", true, "n", "return the `DNSCryptContext` object corresponding to the bind `n`" },
{ "getDOHFrontend", true, "n", "returns the DOH frontend with index n" },
{ "getPool", true, "name", "return the pool named `name`, or \"\" for the default pool" },
{ "getPoolServers", true, "pool", "return servers part of this pool" },
{ "getQueryCounters", true, "[max=10]", "show current buffer of query counters, limited by 'max' if provided" },
Expand Down Expand Up @@ -488,6 +490,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
{ "showCacheHitResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined cache hit response rules, optionally with their UUIDs and optionally truncated to a given width" },
{ "showConsoleACL", true, "", "show our current console ACL set" },
{ "showDNSCryptBinds", true, "", "display the currently configured DNSCrypt binds" },
{ "showDOHFrontends", true, "", "list all the available DOH frontends" },
{ "showDynBlocks", true, "", "show dynamic blocks in force" },
{ "showPools", true, "", "show the available pools" },
{ "showPoolServerPolicy", true, "pool", "show server selection policy for this pool" },
Expand Down
9 changes: 9 additions & 0 deletions pdns/dnsdist-lua-rules.cc
Expand Up @@ -280,6 +280,15 @@ void setupLuaRules()
return std::shared_ptr<DNSRule>(new RegexRule(str));
});

#ifdef HAVE_DNS_OVER_HTTPS
g_lua.writeFunction("HTTPHeaderRule", [](const std::string& header, const std::string& regex) {
return std::shared_ptr<DNSRule>(new HTTPHeaderRule(header, regex));
});
g_lua.writeFunction("HTTPPathRule", [](const std::string& path) {
return std::shared_ptr<DNSRule>(new HTTPPathRule(path));
});
#endif

#ifdef HAVE_RE2
g_lua.writeFunction("RE2Rule", [](const std::string& str) {
return std::shared_ptr<DNSRule>(new RE2Rule(str));
Expand Down

0 comments on commit 07f217c

Please sign in to comment.