From 79ee8ff9e9118d121e066931e10e3dd94d57a5d4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 17 Oct 2018 11:14:47 +0200 Subject: [PATCH] dnsdist: Support the NXDomain action with dynamic blocks --- pdns/dnsdist-lua.cc | 6 +++--- pdns/dnsdist.cc | 18 +++++++++++++++++- pdns/dnsdistdist/docs/reference/config.rst | 5 ++++- regression-tests.dnsdist/test_DynBlocks.py | 21 +++++++++++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index ce7e6dafe..755e9e309 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -984,12 +984,12 @@ void setupLuaConfig(bool client) g_lua.writeFunction("setDynBlocksAction", [](DNSAction::Action action) { if (!g_configurationDone) { - if (action == DNSAction::Action::Drop || action == DNSAction::Action::NoOp || action == DNSAction::Action::Refused || action == DNSAction::Action::Truncate) { + if (action == DNSAction::Action::Drop || action == DNSAction::Action::NoOp || action == DNSAction::Action::Nxdomain || action == DNSAction::Action::Refused || action == DNSAction::Action::Truncate) { g_dynBlockAction = action; } else { - errlog("Dynamic blocks action can only be Drop, NoOp, Refused or Truncate!"); - g_outputBuffer="Dynamic blocks action can only be Drop, NoOp, Refused or Truncate!\n"; + errlog("Dynamic blocks action can only be Drop, NoOp, NXDomain, Refused or Truncate!"); + g_outputBuffer="Dynamic blocks action can only be Drop, NoOp, NXDomain, Refused or Truncate!\n"; } } else { g_outputBuffer="Dynamic blocks action cannot be altered at runtime!\n"; diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 780e36994..f5e9f088c 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -976,12 +976,21 @@ bool processQuery(LocalHolders& holders, DNSQuestion& dq, string& poolname, int* case DNSAction::Action::NoOp: /* do nothing */ break; + + case DNSAction::Action::Nxdomain: + vinfolog("Query from %s turned into NXDomain because of dynamic block", dq.remote->toStringWithPort()); + updateBlockStats(); + + dq.dh->rcode = RCode::NXDomain; + dq.dh->qr=true; + return true; + case DNSAction::Action::Refused: vinfolog("Query from %s refused because of dynamic block", dq.remote->toStringWithPort()); updateBlockStats(); dq.dh->rcode = RCode::Refused; - dq.dh->qr=true; + dq.dh->qr = true; return true; case DNSAction::Action::Truncate: @@ -1019,6 +1028,13 @@ bool processQuery(LocalHolders& holders, DNSQuestion& dq, string& poolname, int* case DNSAction::Action::NoOp: /* do nothing */ break; + case DNSAction::Action::Nxdomain: + vinfolog("Query from %s for %s turned into NXDomain because of dynamic block", dq.remote->toStringWithPort(), dq.qname->toString()); + updateBlockStats(); + + dq.dh->rcode = RCode::NXDomain; + dq.dh->qr=true; + return true; case DNSAction::Action::Refused: vinfolog("Query from %s for %s refused because of dynamic block", dq.remote->toStringWithPort(), dq.qname->toString()); updateBlockStats(); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 0889ebe58..9af91dbd4 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -761,8 +761,11 @@ Dynamic Blocks .. function:: setDynBlocksAction(action) + .. versionchanged:: 1.3.3 + ``DNSAction.NXDomain`` action added. + Set which action is performed when a query is blocked. - Only DNSAction.Drop (the default), DNSAction.NoOp, DNSAction.Refused and DNSAction.Truncate are supported. + Only DNSAction.Drop (the default), DNSAction.NoOp, DNSAction.NXDomain, DNSAction.Refused and DNSAction.Truncate are supported. .. _exceedfuncs: diff --git a/regression-tests.dnsdist/test_DynBlocks.py b/regression-tests.dnsdist/test_DynBlocks.py index 5cd01e46a..09a588793 100644 --- a/regression-tests.dnsdist/test_DynBlocks.py +++ b/regression-tests.dnsdist/test_DynBlocks.py @@ -552,6 +552,27 @@ class TestDynBlockQPSActionRefused(DynBlocksTest): name = 'qrateactionrefused.dynblocks.tests.powerdns.com.' self.doTestQRateRCode(name, dns.rcode.REFUSED) +class TestDynBlockQPSActionNXD(DynBlocksTest): + + _dynBlockQPS = 10 + _dynBlockPeriod = 2 + _dynBlockDuration = 5 + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + _config_template = """ + function maintenance() + addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Nxdomain) + end + setDynBlocksAction(DNSAction.Drop) + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksQRate(self): + """ + Dyn Blocks: QRate NXD (action) + """ + name = 'qrateactionnxd.dynblocks.tests.powerdns.com.' + self.doTestQRateRCode(name, dns.rcode.NXDOMAIN) + class TestDynBlockGroupQPSActionRefused(DynBlocksTest): _dynBlockQPS = 10 -- 2.40.0