comparison src/syslogconfig.cpp @ 20:0d65c3de34fd

add better logging
author carl
date Sun, 08 Jan 2006 12:36:57 -0800
parents c2a2e35a85ac
children ec051169fdfd
comparison
equal deleted inserted replaced
19:13b2e663b553 20:0d65c3de34fd
59 typedef map<int, bucket, ltint> ip_buckets; 59 typedef map<int, bucket, ltint> ip_buckets;
60 60
61 class IPR { 61 class IPR {
62 ip_buckets violations; 62 ip_buckets violations;
63 public: 63 public:
64 void add(int ip, int amount, CONFIG &con); 64 void add(int ip, int amount, CONFIG &con, char *file_name, int pattern_index);
65 void changed(CONFIG &con);
66 void leak(int amount, CONFIG &con); 65 void leak(int amount, CONFIG &con);
66 void update(int ip, bool added, char *file_name, int pattern_index);
67 void changed(CONFIG &con, int ip, bool added);
67 }; 68 };
68 69
69 IPR recorder; 70 IPR recorder;
70 71
71 72
72 //////////////////////////////////////////////// 73 ////////////////////////////////////////////////
73 // 74 //
74 void IPR::add(int ip, int amount, CONFIG &con) { 75 void IPR::add(int ip, int amount, CONFIG &con, char *file_name, int pattern_index) {
75 if (con.looking(ip)) { 76 if (con.looking(ip)) {
76 ip_buckets::iterator i = violations.find(ip); 77 ip_buckets::iterator i = violations.find(ip);
77 if (i == violations.end()) { 78 if (i == violations.end()) {
78 bucket b; 79 bucket b;
79 b.count = amount; 80 b.count = amount;
80 b.latch = false; 81 b.latch = (con.get_threshold() <= b.count);
81 violations[ip] = b; 82 violations[ip] = b;
83 if (b.latch) {
84 update(ip, true, file_name, pattern_index);
85 changed(con, ip, true);
86 }
82 } 87 }
83 else { 88 else {
84 bucket &b = (*i).second; 89 bucket &b = (*i).second;
85 if (b.count < (INT_MAX-amount)) { 90 if (b.count < (INT_MAX-amount)) {
86 int t = con.get_threshold(); 91 int t = con.get_threshold();
87 int c = b.count; 92 int c = b.count;
88 b.count += amount; 93 b.count += amount;
89 if ((!b.latch) && (c < t) && (t <= b.count)) { 94 if ((!b.latch) && (c < t) && (t <= b.count)) {
90 b.latch = true; 95 b.latch = true;
91 changed(con); 96 update(ip, true, file_name, pattern_index);
97 changed(con, ip, true);
92 } 98 }
93 } 99 }
94 } 100 }
95 } 101 }
96 } 102 }
100 bool ch = false; 106 bool ch = false;
101 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); ) { 107 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); ) {
102 int ip = (*i).first; 108 int ip = (*i).first;
103 bucket &b = (*i).second; 109 bucket &b = (*i).second;
104 if (b.count <= amount) { 110 if (b.count <= amount) {
105 ch |= b.latch; 111 if (b.latch) {
112 update(ip, false, NULL, 0);
113 ch = true;
114 }
106 violations.erase(i++); 115 violations.erase(i++);
107 } 116 }
108 else { 117 else {
109 b.count -= amount; 118 b.count -= amount;
110 i++; 119 i++;
111 } 120 }
112 } 121 }
113 if (ch) changed(con); 122 if (ch) changed(con, 0, false);
114 } 123 }
115 124
116 125
117 void IPR::changed(CONFIG &con) { 126 void IPR::update(int ip, bool added, char *file_name, int pattern_index) {
127 if (debug_syslog > 2) {
128 char buf[maxlen];
129 in_addr ad;
130 ad.s_addr = htonl(ip);
131 if (added) snprintf(buf, maxlen, "dropping traffic from/to %s based on pattern match %d in %s", inet_ntoa(ad), pattern_index, file_name);
132 else snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad));
133 my_syslog(buf);
134 }
135 }
136
137
138 void IPR::changed(CONFIG &con, int ip, bool added) {
139 int t = con.get_threshold();
118 char buf[maxlen]; 140 char buf[maxlen];
119 snprintf(buf, maxlen, "%s -F INPUT", iptables); 141 if (added) {
120 if (debug_syslog > 2) { 142 bucket &b = violations[ip];
121 my_syslog(" "); 143 if (con.looking(ip) && (b.count > t)) {
122 my_syslog(buf);
123 }
124 system(buf);
125 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); i++) {
126 int ip = (*i).first;
127 bucket &b = (*i).second;
128 if (b.count > con.get_threshold()) {
129 in_addr ad; 144 in_addr ad;
130 ad.s_addr = htonl(ip); 145 ad.s_addr = htonl(ip);
131 snprintf(buf, maxlen, "count=%d %s -A INPUT --src %s --jump DROP", b.count, iptables, inet_ntoa(ad)); 146 snprintf(buf, maxlen, "count=%d %s -A INPUT --src %s --jump DROP", b.count, iptables, inet_ntoa(ad));
132 if (debug_syslog > 2) my_syslog(buf);
133 system(buf); 147 system(buf);
148 }
149 }
150 else {
151 // releasing some ip, redo the table
152 snprintf(buf, maxlen, "%s -F INPUT", iptables);
153 system(buf);
154 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); i++) {
155 int ip = (*i).first;
156 bucket &b = (*i).second;
157 if (con.looking(ip) && (b.count > t)) {
158 in_addr ad;
159 ad.s_addr = htonl(ip);
160 snprintf(buf, maxlen, "count=%d %s -A INPUT --src %s --jump DROP", b.count, iptables, inet_ntoa(ad));
161 system(buf);
162 }
134 } 163 }
135 } 164 }
136 } 165 }
137 166
138 167
174 PATTERN::~PATTERN() { 203 PATTERN::~PATTERN() {
175 regfree(&re); 204 regfree(&re);
176 } 205 }
177 206
178 207
179 bool PATTERN::process(char *buf, CONFIG &con) { 208 bool PATTERN::process(char *buf, CONFIG &con, char *file_name, int pattern_index) {
180 if (pattern) { 209 if (pattern) {
181 const int nmatch = index+1; 210 const int nmatch = index+1;
182 regmatch_t match[nmatch]; 211 regmatch_t match[nmatch];
183 if (0 == regexec(&re, buf, nmatch, match, 0)) { 212 if (0 == regexec(&re, buf, nmatch, match, 0)) {
184 int s = match[index].rm_so; 213 int s = match[index].rm_so;
188 my_syslog(buf); // show lines with matches 217 my_syslog(buf); // show lines with matches
189 } 218 }
190 buf[e] = '\0'; 219 buf[e] = '\0';
191 int ip = ip_address(buf+s); 220 int ip = ip_address(buf+s);
192 if (ip) { 221 if (ip) {
193 recorder.add(ip, amount, con); 222 recorder.add(ip, amount, con, file_name, pattern_index);
194 } 223 }
195 return true; 224 return true;
196 } 225 }
197 } 226 }
198 } 227 }
383 patterns.push_back(pat); 412 patterns.push_back(pat);
384 } 413 }
385 414
386 415
387 void SYSLOGCONFIG::process(CONFIG &con) { 416 void SYSLOGCONFIG::process(CONFIG &con) {
417 int pi=0;
388 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) { 418 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) {
389 PATTERN *p = *i; 419 PATTERN *p = *i;
390 if (p->process(buf, con)) break; 420 if (p->process(buf, con, file_name, pi)) break;
421 pi++;
391 } 422 }
392 } 423 }
393 424
394 425
395 void SYSLOGCONFIG::dump(int level) { 426 void SYSLOGCONFIG::dump(int level) {