Mercurial > syslog2iptables
diff src/syslogconfig.cpp @ 58:b45dddebe8fc
Add exponential increase in penalty for repeat offenders
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 10 Jun 2014 08:48:53 -0700 |
parents | 206448c00b55 |
children | f133196b8591 |
line wrap: on
line diff
--- a/src/syslogconfig.cpp Wed Aug 17 10:16:17 2011 -0700 +++ b/src/syslogconfig.cpp Tue Jun 10 08:48:53 2014 -0700 @@ -32,6 +32,7 @@ string_set all_strings;// owns all the strings, only modified by the config loader thread recorder_map recorders; // all the recorders are named const int maxlen = 1000; // used for snprintf buffers +const int scale_max = 500000; //////////////////////////////////////////////// @@ -39,6 +40,7 @@ IPR::IPR() { reference_count = 0; + daily_timer = 86400; } IPR* IPR::find(const char* name) { @@ -62,26 +64,28 @@ void IPR::add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message) { if (con.looking(ip)) { + ip_buckets::iterator j = repeat_offenders.find(ip); + int scale = (j == repeat_offenders.end()) ? 1 : (*j).second.count; + amount *= scale; + ip_buckets::iterator i = violations.find(ip); if (i == violations.end()) { bucket b; b.count = amount; - b.latch = (con.get_threshold() <= b.count); + b.blocked = (con.get_threshold() <= b.count); violations[ip] = b; - if (b.latch) { - update(ip, true, file_name, pattern_index, message); + if (b.blocked) { + update(ip, true, scale, file_name, pattern_index, message); changed(con, ip, true); } } else { bucket &b = (*i).second; if (b.count < (INT_MAX-amount)) { - int t = con.get_threshold(); - int c = b.count; b.count += amount; - if ((!b.latch) && (c < t) && (t <= b.count)) { - b.latch = true; - update(ip, true, file_name, pattern_index, message); + if ((!b.blocked) && (con.get_threshold() <= b.count)) { + b.blocked = true; + update(ip, true, scale, file_name, pattern_index, message); changed(con, ip, true); } } @@ -95,8 +99,8 @@ int ip = (*i).first; bucket &b = (*i).second; if (b.count <= amount) { - if (b.latch) { - update(ip, false, NULL, 0, NULL); + if (b.blocked) { + update(ip, false, 0, NULL, 0, NULL); changed(con, ip, false); } violations.erase(i++); @@ -106,6 +110,26 @@ i++; } } + daily_timer -= amount; + if (daily_timer < 0) { + daily_timer = 86400; + for (ip_buckets::iterator j=repeat_offenders.begin(); j!=repeat_offenders.end(); ) { + int ip = (*j).first; + bucket &b = (*j).second; + b.count = b.count * 2 / 3; + if (b.count <= 2) { + repeat_offenders.erase(j++); + char buf[maxlen]; + in_addr ad; + ad.s_addr = htonl(ip); + snprintf(buf, maxlen, "removing %s from repeat offenders", inet_ntoa(ad)); + my_syslog(buf); + } + else { + j++; + } + } + } } @@ -116,8 +140,8 @@ for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); i++) { int ip = (*i).first; bucket &b = (*i).second; - if (b.latch) { - update(ip, false, NULL, 0, NULL); + if (b.blocked) { + update(ip, false, 0, NULL, 0, NULL); changed(con, ip, false); } } @@ -125,14 +149,25 @@ } -void IPR::update(int ip, bool added, const char *file_name, int pattern_index, const char *message) { +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 (message) snprintf(buf, maxlen, "dropping traffic from/to %s based on %s in %s", inet_ntoa(ad), message, file_name); + 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); + ip_buckets::iterator j = repeat_offenders.find(ip); + if (j == repeat_offenders.end()) { + bucket b; + b.count = 2; + b.blocked = true; // unused + repeat_offenders[ip] = b; + } + else { + bucket &b = (*j).second; + if (b.count < scale_max) b.count = b.count * 3 / 2; + } } else snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad)); my_syslog(buf);