From: Kees Monshouwer Date: Mon, 4 Jun 2018 22:31:20 +0000 (+0200) Subject: rec: add bogus ringbuffer to make it more easy to detect high profile bogus domains X-Git-Tag: dnsdist-1.3.1~25^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66f2e6ad8d76675a36b01a11fb6d29bf453eb1cd;p=thirdparty%2Fpdns.git rec: add bogus ringbuffer to make it more easy to detect high profile bogus domains --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 9ffab649ff..09cbd181d5 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -113,8 +113,8 @@ thread_local std::unique_ptr MT; // the big MTasker thread_local std::unique_ptr t_RC; thread_local std::unique_ptr t_packetCache; thread_local FDMultiplexer* t_fdm{nullptr}; -thread_local std::unique_ptr t_remotes, t_servfailremotes, t_largeanswerremotes; -thread_local std::unique_ptr > > t_queryring, t_servfailqueryring; +thread_local std::unique_ptr t_remotes, t_servfailremotes, t_largeanswerremotes, t_bogusremotes; +thread_local std::unique_ptr > > t_queryring, t_servfailqueryring, t_bogusqueryring; thread_local std::shared_ptr t_allowFrom; #ifdef HAVE_PROTOBUF thread_local std::unique_ptr t_uuidGenerator; @@ -1238,6 +1238,10 @@ static void startDoResolve(void *p) pw.getHeader()->ad=0; } else if(state == Bogus) { + if(t_bogusremotes) + t_bogusremotes->push_back(dc->d_source); + if(t_bogusqueryring) + t_bogusqueryring->push_back(make_pair(dc->d_mdp.d_qname, dc->d_mdp.d_qtype)); if(g_dnssecLogBogus || sr.doLog() || g_dnssecmode == DNSSECMode::ValidateForLog) { g_log<d_mdp.d_qname<<"|"<d_mdp.d_qtype).getName()<<" for "<getRemote()<<" validates as Bogus"<set_capacity(ringsize); t_servfailremotes = std::unique_ptr(new addrringbuf_t()); t_servfailremotes->set_capacity(ringsize); + t_bogusremotes = std::unique_ptr(new addrringbuf_t()); + t_bogusremotes->set_capacity(ringsize); t_largeanswerremotes = std::unique_ptr(new addrringbuf_t()); t_largeanswerremotes->set_capacity(ringsize); @@ -3487,6 +3493,8 @@ try t_queryring->set_capacity(ringsize); t_servfailqueryring = std::unique_ptr > >(new boost::circular_buffer >()); t_servfailqueryring->set_capacity(ringsize); + t_bogusqueryring = std::unique_ptr > >(new boost::circular_buffer >()); + t_bogusqueryring->set_capacity(ringsize); } MT=std::unique_ptr >(new MTasker(::arg().asNum("stack-size"))); diff --git a/pdns/rec_channel.hh b/pdns/rec_channel.hh index 4e2ce451ec..526faa6a3f 100644 --- a/pdns/rec_channel.hh +++ b/pdns/rec_channel.hh @@ -68,8 +68,10 @@ extern pthread_mutex_t g_carbon_config_lock; void sortPublicSuffixList(); std::vector >* pleaseGetQueryRing(); std::vector >* pleaseGetServfailQueryRing(); +std::vector >* pleaseGetBogusQueryRing(); std::vector* pleaseGetRemotes(); std::vector* pleaseGetServfailRemotes(); +std::vector* pleaseGetBogusRemotes(); std::vector* pleaseGetLargeAnswerRemotes(); DNSName getRegisteredName(const DNSName& dom); std::atomic* getDynMetric(const std::string& str); diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index 3215c497bb..daef31319b 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -1032,6 +1032,18 @@ vector >* pleaseGetServfailQueryRing() } return ret; } +vector >* pleaseGetBogusQueryRing() +{ + typedef pair query_t; + vector* ret = new vector(); + if(!t_bogusqueryring) + return ret; + ret->reserve(t_bogusqueryring->size()); + for(const query_t& q : *t_bogusqueryring) { + ret->push_back(q); + } + return ret; +} @@ -1063,6 +1075,18 @@ vector* pleaseGetServfailRemotes() return ret; } +vector* pleaseGetBogusRemotes() +{ + vector* ret = new vector(); + if(!t_bogusremotes) + return ret; + ret->reserve(t_bogusremotes->size()); + for(const ComboAddress& ca : *t_bogusremotes) { + ret->push_back(ca); + } + return ret; +} + vector* pleaseGetLargeAnswerRemotes() { vector* ret = new vector(); @@ -1251,8 +1275,11 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP "top-pub-queries show top queries grouped by public suffix list\n" "top-remotes show top remotes\n" "top-servfail-queries show top queries receiving servfail answers\n" +"top-bogus-queries show top queries validating as bogus\n" "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n" +"top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n" "top-servfail-remotes show top remotes receiving servfail answers\n" +"top-bogus-remotes show top remotes receiving bogus answers\n" "unload-lua-script unload Lua script\n" "version return Recursor version number\n" "wipe-cache domain0 [domain1] .. wipe domain data from cache\n"; @@ -1366,10 +1393,19 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP if(cmd=="top-pub-servfail-queries") return doGenericTopQueries(pleaseGetServfailQueryRing, getRegisteredName); + if(cmd=="top-bogus-queries") + return doGenericTopQueries(pleaseGetBogusQueryRing); + + if(cmd=="top-pub-bogus-queries") + return doGenericTopQueries(pleaseGetBogusQueryRing, getRegisteredName); + if(cmd=="top-servfail-remotes") return doGenericTopRemotes(pleaseGetServfailRemotes); + if(cmd=="top-bogus-remotes") + return doGenericTopRemotes(pleaseGetBogusRemotes); + if(cmd=="top-largeanswer-remotes") return doGenericTopRemotes(pleaseGetLargeAnswerRemotes); diff --git a/pdns/recursordist/docs/manpages/rec_control.1.rst b/pdns/recursordist/docs/manpages/rec_control.1.rst index 3692416fd5..a94d8a79fe 100644 --- a/pdns/recursordist/docs/manpages/rec_control.1.rst +++ b/pdns/recursordist/docs/manpages/rec_control.1.rst @@ -183,15 +183,28 @@ top-servfail-queries Shows the top-20 queries causing servfail responses. Statistics are over the last 'stats-ringbuffer-entries' queries. +top-bogus-queries + Shows the top-20 queries causing bogus responses. Statistics are over + the last 'stats-ringbuffer-entries' queries. + top-pub-servfail-queries Shows the top-20 queries causing servfail responses grouped by public suffix list. Statistics are over the last 'stats-ringbuffer-entries' queries. +top-pub-bogus-queries + Shows the top-20 queries causing bogus responses grouped by public + suffix list. Statistics are over the last 'stats-ringbuffer-entries' + queries. + top-servfail-remotes Shows the top-20 most active remote hosts causing servfail responses. Statistics are over the last 'stats-ringbuffer-entries' queries. +top-bogus-remotes + Shows the top-20 most active remote hosts causing bogus responses. + Statistics are over the last 'stats-ringbuffer-entries' queries. + trace-regex *REGEX* Emit resolution trace for matching queries. Empty regex to disable trace. diff --git a/pdns/recursordist/html/index.html b/pdns/recursordist/html/index.html index 61b6b0fc59..9ae0f622bd 100644 --- a/pdns/recursordist/html/index.html +++ b/pdns/recursordist/html/index.html @@ -57,6 +57,7 @@
+
@@ -64,6 +65,7 @@
+
@@ -114,6 +116,23 @@ + + + + diff --git a/pdns/recursordist/html/local.js b/pdns/recursordist/html/local.js index 087ce6894f..c11b0b23ef 100644 --- a/pdns/recursordist/html/local.js +++ b/pdns/recursordist/html/local.js @@ -114,6 +114,12 @@ $(document).ready(function () { render('servfailqueryring', {rows: rows}); }); + $.getJSON('jsonstat', jsonstatParams('get-query-ring', 'bogus-queries', $("#filter1").is(':checked')), + function (data) { + var rows = makeRingRows(data); + render('bogusqueryring', {rows: rows}); + }); + $.getJSON('jsonstat', jsonstatParams('get-remote-ring', 'remotes', false), function (data) { var rows = makeRingRows(data); @@ -125,6 +131,12 @@ $(document).ready(function () { var rows = makeRingRows(data); render('servfailremotering', {rows: rows}); }); + + $.getJSON('jsonstat', jsonstatParams('get-remote-ring', 'bogus-remotes', false), + function (data) { + var rows = makeRingRows(data); + render('bogusremotering', {rows: rows}); + }); } var connectionOK = function (ok, o) { diff --git a/pdns/syncres.hh b/pdns/syncres.hh index d912e95949..0cf30ccd3b 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -961,9 +961,9 @@ public: }; typedef boost::circular_buffer addrringbuf_t; -extern thread_local std::unique_ptr t_servfailremotes, t_largeanswerremotes, t_remotes; +extern thread_local std::unique_ptr t_servfailremotes, t_largeanswerremotes, t_remotes, t_bogusremotes; -extern thread_local std::unique_ptr > > t_queryring, t_servfailqueryring; +extern thread_local std::unique_ptr > > t_queryring, t_servfailqueryring, t_bogusqueryring; extern thread_local std::shared_ptr t_allowFrom; string doQueueReloadLuaScript(vector::const_iterator begin, vector::const_iterator end); string doTraceRegex(vector::const_iterator begin, vector::const_iterator end); diff --git a/pdns/ws-recursor.cc b/pdns/ws-recursor.cc index d3e357e76f..4cea7898d9 100644 --- a/pdns/ws-recursor.cc +++ b/pdns/ws-recursor.cc @@ -490,6 +490,8 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) if(req->getvars["name"]=="servfail-queries") queries=broadcastAccFunction >(pleaseGetServfailQueryRing); + if(req->getvars["name"]=="bogus-queries") + queries=broadcastAccFunction >(pleaseGetBogusQueryRing); else if(req->getvars["name"]=="queries") queries=broadcastAccFunction >(pleaseGetQueryRing); @@ -534,6 +536,8 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) queries=broadcastAccFunction >(pleaseGetRemotes); else if(req->getvars["name"]=="servfail-remotes") queries=broadcastAccFunction >(pleaseGetServfailRemotes); + else if(req->getvars["name"]=="bogus-remotes") + queries=broadcastAccFunction >(pleaseGetBogusRemotes); else if(req->getvars["name"]=="large-answer-remotes") queries=broadcastAccFunction >(pleaseGetLargeAnswerRemotes);