]> granicus.if.org Git - pdns/commitdiff
rec: add bogus ringbuffer to make it more easy to detect high profile bogus domains
authorKees Monshouwer <mind04@monshouwer.org>
Mon, 4 Jun 2018 22:31:20 +0000 (00:31 +0200)
committermind04 <mind04@monshouwer.org>
Mon, 4 Jun 2018 22:50:34 +0000 (00:50 +0200)
pdns/pdns_recursor.cc
pdns/rec_channel.hh
pdns/rec_channel_rec.cc
pdns/recursordist/docs/manpages/rec_control.1.rst
pdns/recursordist/html/index.html
pdns/recursordist/html/local.js
pdns/syncres.hh
pdns/ws-recursor.cc

index 9ffab649ff52d4f40eb499d5b10d994493311f7f..09cbd181d5995fb0104faef8927f3e7bdedfac8d 100644 (file)
@@ -113,8 +113,8 @@ thread_local std::unique_ptr<MT_t> MT; // the big MTasker
 thread_local std::unique_ptr<MemRecursorCache> t_RC;
 thread_local std::unique_ptr<RecursorPacketCache> t_packetCache;
 thread_local FDMultiplexer* t_fdm{nullptr};
-thread_local std::unique_ptr<addrringbuf_t> t_remotes, t_servfailremotes, t_largeanswerremotes;
-thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName, uint16_t> > > t_queryring, t_servfailqueryring;
+thread_local std::unique_ptr<addrringbuf_t> t_remotes, t_servfailremotes, t_largeanswerremotes, t_bogusremotes;
+thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName, uint16_t> > > t_queryring, t_servfailqueryring, t_bogusqueryring;
 thread_local std::shared_ptr<NetmaskGroup> t_allowFrom;
 #ifdef HAVE_PROTOBUF
 thread_local std::unique_ptr<boost::uuids::random_generator> 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<<Logger::Warning<<"Answer to "<<dc->d_mdp.d_qname<<"|"<<QType(dc->d_mdp.d_qtype).getName()<<" for "<<dc->getRemote()<<" validates as Bogus"<<endl;
             }
@@ -3480,6 +3484,8 @@ try
       t_remotes->set_capacity(ringsize);
     t_servfailremotes = std::unique_ptr<addrringbuf_t>(new addrringbuf_t());
     t_servfailremotes->set_capacity(ringsize);
+    t_bogusremotes = std::unique_ptr<addrringbuf_t>(new addrringbuf_t());
+    t_bogusremotes->set_capacity(ringsize);
     t_largeanswerremotes = std::unique_ptr<addrringbuf_t>(new addrringbuf_t());
     t_largeanswerremotes->set_capacity(ringsize);
 
@@ -3487,6 +3493,8 @@ try
     t_queryring->set_capacity(ringsize);
     t_servfailqueryring = std::unique_ptr<boost::circular_buffer<pair<DNSName, uint16_t> > >(new boost::circular_buffer<pair<DNSName, uint16_t> >());
     t_servfailqueryring->set_capacity(ringsize);
+    t_bogusqueryring = std::unique_ptr<boost::circular_buffer<pair<DNSName, uint16_t> > >(new boost::circular_buffer<pair<DNSName, uint16_t> >());
+    t_bogusqueryring->set_capacity(ringsize);
   }
 
   MT=std::unique_ptr<MTasker<PacketID,string> >(new MTasker<PacketID,string>(::arg().asNum("stack-size")));
index 4e2ce451ec19f0ed2f4805592fc8395f917f3f9b..526faa6a3f93169a33fc361a542a25953d24b9d9 100644 (file)
@@ -68,8 +68,10 @@ extern pthread_mutex_t g_carbon_config_lock;
 void sortPublicSuffixList();
 std::vector<std::pair<DNSName, uint16_t> >* pleaseGetQueryRing();
 std::vector<std::pair<DNSName, uint16_t> >* pleaseGetServfailQueryRing();
+std::vector<std::pair<DNSName, uint16_t> >* pleaseGetBogusQueryRing();
 std::vector<ComboAddress>* pleaseGetRemotes();
 std::vector<ComboAddress>* pleaseGetServfailRemotes();
+std::vector<ComboAddress>* pleaseGetBogusRemotes();
 std::vector<ComboAddress>* pleaseGetLargeAnswerRemotes();
 DNSName getRegisteredName(const DNSName& dom);
 std::atomic<unsigned long>* getDynMetric(const std::string& str);
index 3215c497bb16d424ffa35b5c81d4c4cf172b742e..daef31319b1c007eaf6be63c3d59606f16e5e51b 100644 (file)
@@ -1032,6 +1032,18 @@ vector<pair<DNSName,uint16_t> >* pleaseGetServfailQueryRing()
   }
   return ret;
 }
+vector<pair<DNSName,uint16_t> >* pleaseGetBogusQueryRing()
+{
+  typedef pair<DNSName,uint16_t> query_t;
+  vector<query_t>* ret = new vector<query_t>();
+  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<ComboAddress>* pleaseGetServfailRemotes()
   return ret;
 }
 
+vector<ComboAddress>* pleaseGetBogusRemotes()
+{
+  vector<ComboAddress>* ret = new vector<ComboAddress>();
+  if(!t_bogusremotes)
+    return ret;
+  ret->reserve(t_bogusremotes->size());
+  for(const ComboAddress& ca :  *t_bogusremotes) {
+    ret->push_back(ca);
+  }
+  return ret;
+}
+
 vector<ComboAddress>* pleaseGetLargeAnswerRemotes()
 {
   vector<ComboAddress>* ret = new vector<ComboAddress>();
@@ -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);
 
index 3692416fd508e0d35615daf2b71e8003d3c7e83d..a94d8a79fe0a89596caa3aad5decf8f918e0ea30 100644 (file)
@@ -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.
 
index 61b6b0fc5925f2561051ff16010b2e2124572b27..9ae0f622bd6f9f49ebf1fd2a151cd64c964b5a77 100644 (file)
@@ -57,6 +57,7 @@
             </div>
             <div class="stats-table" id="queryring"></div>
             <div class="stats-table" id="servfailqueryring"></div>
+            <div class="stats-table" id="bogusqueryring"></div>
         </div>
 
         <div class="table-container">
@@ -64,6 +65,7 @@
             <div class="filter"></div>
             <div class="stats-table" id="remotering"></div>
             <div class="stats-table" id="servfailremotering"></div>
+            <div class="stats-table" id="bogusremotering"></div>
         </div>
     </div>
 
     </table>
 </script>
 
+<script id="bogusqueryring-template" type="text/x-handlebars-template">
+    <table class="three-col">
+        <tr>
+            <th>Number</th>
+            <th>Bogus domain</th>
+            <th>Type</th>
+        </tr>
+        {{#each rows}}
+        <tr>
+            <td>{{0}}</td>
+            <td>{{1}}</td>
+            <td>{{2}}</td>
+        </tr>
+        {{/each}}
+    </table>
+</script>
+
 <script id="remotering-template" type="text/x-handlebars-template">
     <table class="two-col">
         <tr>
     </table>
 </script>
 
+<script id="bogusremotering-template" type="text/x-handlebars-template">
+    <table class="two-col">
+        <tr>
+            <th>Number</th>
+            <th>Bogus remote</th>
+        </tr>
+        {{#each rows}}
+        <tr>
+            <td>{{0}}</td>
+            <td>{{1}}</td>
+        </tr>
+        {{/each}}
+    </table>
+</script>
+
 </body>
 </html>
index 087ce6894ffd1f1d1c7da3863d976904860576c0..c11b0b23efd1d730ade4ac96c4a228486fa83625 100644 (file)
@@ -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) {
index d912e95949a06d20bbd7dfd83ec8f12a275630d4..0cf30ccd3b0a88fbd8ebd58937b1af22281e8d49 100644 (file)
@@ -961,9 +961,9 @@ public:
 };
 
 typedef boost::circular_buffer<ComboAddress> addrringbuf_t;
-extern thread_local std::unique_ptr<addrringbuf_t> t_servfailremotes, t_largeanswerremotes, t_remotes;
+extern thread_local std::unique_ptr<addrringbuf_t> t_servfailremotes, t_largeanswerremotes, t_remotes, t_bogusremotes;
 
-extern thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName,uint16_t> > > t_queryring, t_servfailqueryring;
+extern thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName,uint16_t> > > t_queryring, t_servfailqueryring, t_bogusqueryring;
 extern thread_local std::shared_ptr<NetmaskGroup> t_allowFrom;
 string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
 string doTraceRegex(vector<string>::const_iterator begin, vector<string>::const_iterator end);
index d3e357e76f685524db58e66acde801b254dcde4a..4cea7898d99580658f34cd993173b24c9b8cdd64 100644 (file)
@@ -490,6 +490,8 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp)
 
     if(req->getvars["name"]=="servfail-queries")
       queries=broadcastAccFunction<vector<query_t> >(pleaseGetServfailQueryRing);
+    if(req->getvars["name"]=="bogus-queries")
+      queries=broadcastAccFunction<vector<query_t> >(pleaseGetBogusQueryRing);
     else if(req->getvars["name"]=="queries")
       queries=broadcastAccFunction<vector<query_t> >(pleaseGetQueryRing);
 
@@ -534,6 +536,8 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp)
       queries=broadcastAccFunction<vector<ComboAddress> >(pleaseGetRemotes);
     else if(req->getvars["name"]=="servfail-remotes")
       queries=broadcastAccFunction<vector<ComboAddress> >(pleaseGetServfailRemotes);
+    else if(req->getvars["name"]=="bogus-remotes")
+      queries=broadcastAccFunction<vector<ComboAddress> >(pleaseGetBogusRemotes);
     else if(req->getvars["name"]=="large-answer-remotes")
       queries=broadcastAccFunction<vector<ComboAddress> >(pleaseGetLargeAnswerRemotes);