comparison 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
comparison
equal deleted inserted replaced
75:ae5e6bcc5017 76:c6c8a2102a3e
28 const char *token_remove; 28 const char *token_remove;
29 const char *token_semi; 29 const char *token_semi;
30 const char *token_slash; 30 const char *token_slash;
31 const char *token_threshold; 31 const char *token_threshold;
32 string_set all_strings;// owns all the strings, only modified by the config loader thread 32 string_set all_strings;// owns all the strings, only modified by the config loader thread
33 recorder_map recorders; // all the recorders are named 33 recorder_map recorders; // all the recorders are named by their context
34 const int maxlen = 1000; // used for snprintf buffers 34 const int maxlen = 1000; // used for snprintf buffers
35 const int scale_max = 500000; 35 const int scale_max = 500000;
36 36
37 37
38 //////////////////////////////////////////////// 38 ////////////////////////////////////////////////
63 63
64 64
65 void IPR::add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message) { 65 void IPR::add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message) {
66 if (con.looking(ip)) { 66 if (con.looking(ip)) {
67 if (amount > 0) { 67 if (amount > 0) {
68 int original_amount = amount;
68 ip_buckets::iterator j = repeat_offenders.find(ip); 69 ip_buckets::iterator j = repeat_offenders.find(ip);
69 int scale = (j == repeat_offenders.end()) ? 1 : (*j).second.count; 70 int scale = (j == repeat_offenders.end()) ? 1 : (*j).second.count;
70 amount *= scale; 71 amount *= scale;
71 72
72 ip_buckets::iterator i = violations.find(ip); 73 ip_buckets::iterator i = violations.find(ip);
73 if (i == violations.end()) { 74 if (i == violations.end()) {
74 bucket b; 75 bucket b;
75 b.count = amount; 76 b.count = amount;
76 b.blocked = (con.get_threshold() <= b.count); 77 b.blocked = (con.get_threshold() <= b.count);
78 b.max_scale = 1;
77 violations[ip] = b; 79 violations[ip] = b;
78 if (b.blocked) { 80 if (b.blocked) {
79 update(ip, true, scale, file_name, pattern_index, message); 81 update(ip, true, scale, file_name, pattern_index, message);
80 changed(con, ip, true); 82 changed(con, ip, true);
81 } 83 }
84 bucket &b = (*i).second; 86 bucket &b = (*i).second;
85 if ((b.count >= 0) && (b.count < 2600000)) { 87 if ((b.count >= 0) && (b.count < 2600000)) {
86 // good authentication (count<0) prevents blocking 88 // good authentication (count<0) prevents blocking
87 // not much point in blocking for more than a month 89 // not much point in blocking for more than a month
88 b.count += amount; 90 b.count += amount;
89 if ((!b.blocked) && (con.get_threshold() <= b.count)) { 91 int threshold = con.get_threshold();
92 if (b.blocked) {
93 int effective_scale = 1;
94 while (original_amount * effective_scale < b.count) {
95 effective_scale = effective_scale * 3 / 2;
96 }
97 if (effective_scale > b.max_scale) {
98 b.max_scale = effective_scale;
99 if (debug_syslog > 2) {
100 char buf[maxlen];
101 in_addr ad;
102 ad.s_addr = htonl(ip);
103 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);
104 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);
105 my_syslog(buf);
106 }
107 }
108 }
109 if ((!b.blocked) && (threshold <= b.count)) {
90 b.blocked = true; 110 b.blocked = true;
91 update(ip, true, scale, file_name, pattern_index, message); 111 update(ip, true, scale, file_name, pattern_index, message);
92 changed(con, ip, true); 112 changed(con, ip, true);
93 } 113 }
94 } 114 }
109 my_syslog(buf); 129 my_syslog(buf);
110 } 130 }
111 ip_buckets::iterator i = violations.find(ip); 131 ip_buckets::iterator i = violations.find(ip);
112 if (i == violations.end()) { 132 if (i == violations.end()) {
113 bucket b; 133 bucket b;
114 b.count = amount; 134 b.count = amount;
115 b.blocked = false; 135 b.blocked = false;
136 b.max_scale = 1;
116 violations[ip] = b; 137 violations[ip] = b;
117 } 138 }
118 else { 139 else {
119 bucket &b = (*i).second; 140 bucket &b = (*i).second;
120 b.count = amount; 141 b.count = amount;
191 violations.clear(); 212 violations.clear();
192 } 213 }
193 214
194 215
195 void IPR::update(int ip, bool added, int scale, const char *file_name, int pattern_index, const char *message) { 216 void IPR::update(int ip, bool added, int scale, const char *file_name, int pattern_index, const char *message) {
196 if (debug_syslog > 2) { 217 char buf[maxlen];
197 char buf[maxlen]; 218 in_addr ad;
198 in_addr ad; 219 ad.s_addr = htonl(ip);
199 ad.s_addr = htonl(ip); 220 if (added) {
200 if (added) { 221 if (debug_syslog > 2) {
201 if (message) snprintf(buf, maxlen, "dropping traffic from/to %s based on %s in %s, scale %d", inet_ntoa(ad), message, file_name, scale); 222 if (message) snprintf(buf, maxlen, "dropping traffic from/to %s based on %s in %s, scale %d", inet_ntoa(ad), message, file_name, scale);
202 else snprintf(buf, maxlen, "dropping traffic from/to %s based on pattern match %d in %s", inet_ntoa(ad), pattern_index, file_name); 223 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);
203 ip_buckets::iterator j = repeat_offenders.find(ip); 224 my_syslog(buf);
204 if (j == repeat_offenders.end()) { 225 }
205 bucket b; 226 ip_buckets::iterator j = repeat_offenders.find(ip);
206 b.count = 2; 227 if (j == repeat_offenders.end()) {
207 b.blocked = true; // unused 228 bucket b;
208 repeat_offenders[ip] = b; 229 b.count = 2;
209 } 230 b.blocked = true; // unused
210 else { 231 b.max_scale = 1; // unused
211 bucket &b = (*j).second; 232 repeat_offenders[ip] = b;
212 if (b.count < scale_max) b.count = b.count * 3 / 2; 233 }
213 } 234 else {
214 } 235 bucket &b = (*j).second;
215 else snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad)); 236 if (b.count < scale_max) b.count = b.count * 3 / 2;
216 my_syslog(buf); 237 }
238 }
239 else {
240 if (debug_syslog > 2) {
241 snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad));
242 my_syslog(buf);
243 }
217 } 244 }
218 } 245 }
219 246
220 247
221 void IPR::changed(CONTEXT &con, int ip, bool added) { 248 void IPR::changed(CONTEXT &con, int ip, bool added) {