Mercurial > syslog2iptables
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) { |