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