diff src/syslogconfig.cpp @ 76:c6c8a2102a3e

add more logging when blocked addresses move to higher scale values
author Carl Byington <carl@five-ten-sg.com>
date Wed, 15 Jul 2020 13:38:43 -0700
parents 0e736950a117
children 831d0b46bbd2
line wrap: on
line diff
--- a/src/syslogconfig.cpp	Mon Dec 24 08:31:27 2018 -0800
+++ b/src/syslogconfig.cpp	Wed Jul 15 13:38:43 2020 -0700
@@ -30,7 +30,7 @@
 const char *token_slash;
 const char *token_threshold;
 string_set      all_strings;// owns all the strings, only modified by the config loader thread
-recorder_map    recorders;  // all the recorders are named
+recorder_map    recorders;  // all the recorders are named by their context
 const int maxlen = 1000;    // used for snprintf buffers
 const int scale_max = 500000;
 
@@ -65,6 +65,7 @@
 void IPR::add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message) {
     if (con.looking(ip)) {
         if (amount > 0) {
+            int original_amount = amount;
             ip_buckets::iterator j = repeat_offenders.find(ip);
             int scale = (j == repeat_offenders.end()) ? 1 : (*j).second.count;
             amount *= scale;
@@ -74,6 +75,7 @@
                 bucket b;
                 b.count = amount;
                 b.blocked = (con.get_threshold() <= b.count);
+                b.max_scale = 1;
                 violations[ip] = b;
                 if (b.blocked) {
                     update(ip, true, scale, file_name, pattern_index, message);
@@ -86,7 +88,25 @@
                     // good authentication (count<0) prevents blocking
                     // not much point in blocking for more than a month
                     b.count += amount;
-                    if ((!b.blocked) && (con.get_threshold() <= b.count)) {
+                    int threshold = con.get_threshold();
+                    if (b.blocked) {
+                        int effective_scale = 1;
+                        while (original_amount * effective_scale < b.count) {
+                            effective_scale = effective_scale * 3 / 2;
+                        }
+                        if (effective_scale > b.max_scale) {
+                            b.max_scale = effective_scale;
+                            if (debug_syslog > 2) {
+                                char buf[maxlen];
+                                in_addr ad;
+                                ad.s_addr = htonl(ip);
+                                if (message) snprintf(buf, maxlen, "upgrade dropping traffic from/to %s based on %s in %s, scale %d", inet_ntoa(ad), message, file_name, effective_scale);
+                                else         snprintf(buf, maxlen, "upgrade dropping traffic from/to %s based on pattern match %d in %s, scale %d", inet_ntoa(ad), pattern_index, file_name, effective_scale);
+                                my_syslog(buf);
+                            }
+                        }
+                    }
+                    if ((!b.blocked) && (threshold <= b.count)) {
                         b.blocked = true;
                         update(ip, true, scale, file_name, pattern_index, message);
                         changed(con, ip, true);
@@ -113,6 +133,7 @@
                 bucket b;
                 b.count = amount;
                 b.blocked = false;
+                b.max_scale = 1;
                 violations[ip] = b;
             }
             else {
@@ -193,18 +214,21 @@
 
 
 void IPR::update(int ip, bool added, int scale, const char *file_name, int pattern_index, const char *message) {
-    if (debug_syslog > 2) {
         char buf[maxlen];
         in_addr ad;
         ad.s_addr = htonl(ip);
         if (added) {
+        if (debug_syslog > 2) {
             if (message) snprintf(buf, maxlen, "dropping traffic from/to %s based on %s in %s, scale %d", inet_ntoa(ad), message, file_name, scale);
-            else         snprintf(buf, maxlen, "dropping traffic from/to %s based on pattern match %d in %s", inet_ntoa(ad), pattern_index, file_name);
+            else         snprintf(buf, maxlen, "dropping traffic from/to %s based on pattern match %d in %s, scale %d", inet_ntoa(ad), pattern_index, file_name, scale);
+            my_syslog(buf);
+        }
             ip_buckets::iterator j = repeat_offenders.find(ip);
             if (j == repeat_offenders.end()) {
                 bucket b;
                 b.count = 2;
                 b.blocked = true;   // unused
+            b.max_scale = 1;    // unused
                 repeat_offenders[ip] = b;
             }
             else {
@@ -212,10 +236,13 @@
                 if (b.count < scale_max) b.count = b.count * 3 / 2;
             }
         }
-        else snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad));
+    else {
+        if (debug_syslog > 2) {
+            snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad));
         my_syslog(buf);
     }
 }
+}
 
 
 void IPR::changed(CONTEXT &con, int ip, bool added) {