Skip to content

Commit

Permalink
Allow ip ranges as trusted-notification-proxy
Browse files Browse the repository at this point in the history
This also stops us from doing string comparison for that setting.

Fixes #9711
  • Loading branch information
pieterlexis committed Nov 12, 2020
1 parent 5efe73f commit 1886a4b
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 4 deletions.
7 changes: 5 additions & 2 deletions docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1723,9 +1723,12 @@ Enable the Linux-only traceback handler.
``trusted-notification-proxy``
------------------------------

- String
.. versionchanged:: 4.4.0
This option now accepts a comma-separated list of IP ranges. This was a single IP address as a string before

- IP ranges, separated by commas

IP address of incoming notification proxy
IP ranges of incoming notification proxies.

.. _setting-udp-truncation-threshold:

Expand Down
3 changes: 3 additions & 0 deletions pdns/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ pdns_server_SOURCES = \
tcpreceiver.cc tcpreceiver.hh \
threadname.hh threadname.cc \
tkey.cc \
trusted-notification-proxy.hh trusted-notification-proxy.cc \
tsigutils.hh tsigutils.cc \
tsigverifier.cc tsigverifier.hh \
ueberbackend.cc ueberbackend.hh \
Expand Down Expand Up @@ -1358,11 +1359,13 @@ testrunner_SOURCES = \
test-signers.cc \
test-statbag_cc.cc \
test-svc_records_cc.cc \
test-trusted-notification-proxy_cc.cc \
test-tsig.cc \
test-ueberbackend_cc.cc \
test-zoneparser_tng_cc.cc \
testrunner.cc \
threadname.hh threadname.cc \
trusted-notification-proxy.cc \
tsigverifier.cc tsigverifier.hh \
ueberbackend.cc ueberbackend.hh \
unix_utility.cc \
Expand Down
3 changes: 3 additions & 0 deletions pdns/common_startup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "threadname.hh"
#include "misc.hh"
#include "query-local-address.hh"
#include "trusted-notification-proxy.hh"

#include <thread>

Expand Down Expand Up @@ -641,6 +642,8 @@ void mainthread()
pdns::parseQueryLocalAddress(::arg()["query-local-address6"]);
}

pdns::parseTrustedNotificationProxy(::arg()["trusted-notification-proxy"]);

// NOW SAFE TO CREATE THREADS!
dl->go();

Expand Down
5 changes: 3 additions & 2 deletions pdns/packethandler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "dnsproxy.hh"
#include "version.hh"
#include "common_startup.hh"
#include "trusted-notification-proxy.hh"

#if 0
#undef DLOG
Expand Down Expand Up @@ -864,7 +865,7 @@ int PacketHandler::trySuperMaster(const DNSPacket& p, const DNSName& tsigkeyname
int PacketHandler::trySuperMasterSynchronous(const DNSPacket& p, const DNSName& tsigkeyname)
{
ComboAddress remote = p.getRemote();
if(p.hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote.toString())) {
if(p.hasEDNSSubnet() && pdns::isAddressTrustedNotificationProxy(remote)) {
remote = p.getRealRemote().getNetwork();
}
remote.setPort(53);
Expand Down Expand Up @@ -980,7 +981,7 @@ int PacketHandler::processNotify(const DNSPacket& p)
return RCode::Refused;
}

if(::arg().contains("trusted-notification-proxy", p.getRemote().toString())) {
if(pdns::isAddressTrustedNotificationProxy(p.getRemote())) {
g_log<<Logger::Error<<"Received NOTIFY for "<<p.qdomain<<" from trusted-notification-proxy "<< p.getRemote()<<endl;
if(di.masters.empty()) {
g_log<<Logger::Error<<"However, "<<p.qdomain<<" does not have any masters defined (Refused)"<<endl;
Expand Down
88 changes: 88 additions & 0 deletions pdns/test-trusted-notification-proxy_cc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_NO_MAIN
#include <boost/test/unit_test.hpp>
#include "trusted-notification-proxy.hh"

using namespace boost;

BOOST_AUTO_TEST_SUITE(test_trusted_notification_proxy_cc)

BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_bad_addrs) {
string addrs = "127.0.0.1111";
BOOST_CHECK_THROW(pdns::parseTrustedNotificationProxy(addrs), PDNSException);
addrs = "127.0.0.1,:::2";
BOOST_CHECK_THROW(pdns::parseTrustedNotificationProxy(addrs), PDNSException);
}

BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_addresses_only) {
string addrs = "127.0.0.1";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.2")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));

addrs = "::1";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));

addrs = "::1,192.0.2.4";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.4")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
}

BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_with_netmasks) {
string addrs = "127.0.0.0/8";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.2")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("128.0.0.2")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));

addrs = "192.0.2.0/25";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.2")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("128.0.0.2")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.128")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));

addrs = "2001:db8:15::/64";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:15::fee:1:2")));

addrs = "192.0.2.0/24,2001:db8:16::/64";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:15::fee:1:2")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:16::5353")));
}

BOOST_AUTO_TEST_CASE(test_trusted_notification_proxy_with_netmasks_and_addresses) {
string addrs = "192.0.2.1,2001:db8:16::/64";
BOOST_CHECK_NO_THROW(pdns::parseTrustedNotificationProxy(addrs));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("127.0.0.1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8::1")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:15::fee:1:2")));
BOOST_CHECK(!pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.2")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("192.0.2.1")));
BOOST_CHECK(pdns::isAddressTrustedNotificationProxy(ComboAddress("2001:db8:16::5353")));
}

BOOST_AUTO_TEST_SUITE_END()
46 changes: 46 additions & 0 deletions pdns/trusted-notification-proxy.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* This file is part of PowerDNS or dnsdist.
* Copyright -- PowerDNS.COM B.V. and its contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* In addition, for the avoidance of any doubt, permission is granted to
* link this program with OpenSSL and to (re)distribute the binaries
* produced as the result of such linking.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <vector>
#include "trusted-notification-proxy.hh"

namespace pdns {
static NetmaskGroup g_trustedNotificationProxies;

void parseTrustedNotificationProxy(const std::string &addresses) {
g_trustedNotificationProxies.clear();
std::vector<std::string> parts;
stringtok(parts, addresses, ",\t ");
for (auto const &a : parts) {
try {
g_trustedNotificationProxies.addMask(Netmask(a));
} catch (const PDNSException &e) {
throw PDNSException("Unable to add address " + a + " as a trusted-notification-proxy: " + e.reason);
} catch (const std::exception &e) {
throw PDNSException("Unable to add address " + a + " as a trusted-notification-proxy: " + e.what());
}
}
}

bool isAddressTrustedNotificationProxy(const ComboAddress &address) {
return g_trustedNotificationProxies.match(address);
}
} // namespace pdns
39 changes: 39 additions & 0 deletions pdns/trusted-notification-proxy.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* This file is part of PowerDNS or dnsdist.
* Copyright -- PowerDNS.COM B.V. and its contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* In addition, for the avoidance of any doubt, permission is granted to
* link this program with OpenSSL and to (re)distribute the binaries
* produced as the result of such linking.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once

#include <string>
#include "iputils.hh"

namespace pdns {
/*! Parses the provided string into the trusted-notification variable
*
* Replaces any existing masks
*
* Throws on error.
*
* @param addresses String of addresses, separated by comma's
*/
void parseTrustedNotificationProxy(const std::string &addresses);

bool isAddressTrustedNotificationProxy(const ComboAddress &address);
} // namespace pdns

0 comments on commit 1886a4b

Please sign in to comment.