1 /* $Id: ssp_iptables.c,v 2.9 2008/12/17 22:16:23 fknobbe Exp $
2 *
3 *
4 * Copyright (c) 2003-2008 Fabizio Tivano <fabrizio@sad.it>
5 * Copyright (c) 2008 Modifications by Luis Marichal <luismarichal@gmail.com>
6 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 *
29 * ssp_iptables.c
30 *
31 * Purpose:
32 *
33 * This SnortSam plugin is meant for dynamic (un)blocking on iptables firewall,
34 * SnortSam will expire the blocks itself with automatic time-out functionality.
35 *
36 *
37 *
38 *
39 *
40 *
41 *
42 */
43
44
45 #ifdef Linux
46
47 #ifndef __SSP_IPT_C__
48 #define __SSP_IPT_C__
49
50 #include "snortsam.h"
51 #include "ssp_iptables.h"
52
53 #include <sys/types.h>
54 #include <stdio.h>
55 #include <string.h>
56 #include <time.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.h>
59
60
61 /* Set this if you want IP tables to save the tables after every (un)block. */
62
63 /* #define SAVETABLES */
64
65
66
67 /* This routine parses the ipf statements in the config file.
68 */
IPTParse(char * val,char * file,unsigned long line,DATALIST * plugindatalist)69 void IPTParse(char *val,char *file,unsigned long line,DATALIST *plugindatalist)
70 { IPTDATA *iptp=NULL;
71 char *p2, msg[STRBUFSIZE+2];
72
73 #ifdef FWSAMDEBUG
74 printf("Debug: [iptables] Plugin Parsing...\n");
75 #endif
76
77 if(*val)
78 { p2=val;
79 while(*p2 && !myisspace(*p2)) p2++;
80 if(*p2) *p2++ =0;
81 iptp=safemalloc(sizeof(IPTDATA),"IPTParse","iptp");
82 plugindatalist->data=iptp;
83 safecopy(iptp->iface,val); /* save interface */
84
85 if(*p2) /* if we have a loglevel defined */
86 { while(*p2 && myisspace(*p2)) p2++;
87 safecopy(iptp->loglv,p2); /* loglevel defined */
88 } else {
89 safecopy(iptp->loglv,IPTLOGLEVEL); /* use default loglevel */
90 }
91
92 #ifdef FWSAMDEBUG
93 printf("Debug: [iptables] Adding IPTABLES: interface \"%s\", loglevel \"%s\"\n", iptp->iface, iptp->loglv);
94 #endif
95
96 }
97 else
98 { snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] IPTABLES defined without parameters!",file,line);
99 logmessage(1,msg,"iptables",0);
100 }
101 }
102
103
104 /* This routine initiates the block.
105 */
IPTBlock(BLOCKINFO * bd,void * data,unsigned long qp)106 void IPTBlock(BLOCKINFO *bd,void *data,unsigned long qp)
107 { IPTDATA *iptp;
108 char iptcmd[255], iptcmd2[255], msg[STRBUFSIZE+2];
109 /*Nuevo*/
110 char iptcmd1[255],iptcmd4[255];
111 #ifdef SAVETABLES
112 const char savecmd[]="/sbin/iptables-save -c > /etc/sysconfig/iptables";
113 #endif
114
115 #ifdef FWSAMDEBUG
116 pthread_t threadid=pthread_self();
117 #endif
118
119 if(!data) return;
120 iptp=(IPTDATA *)data;
121
122 #ifdef FWSAMDEBUG
123 printf("Debug: [iptables][%lx] Plugin Blocking...\n",threadid);
124 #endif
125
126 if(bd->block)
127 { snprintf(msg,sizeof(msg)-1,"Info: Blocking ip %s", inettoa(bd->blockip));
128 logmessage(3,msg,"iptables",0);
129
130 switch(bd->mode&FWSAM_HOW)
131 { case FWSAM_HOW_IN:
132 /* Assemble command */
133 if (snprintf(iptcmd,sizeof(iptcmd)-1,
134 "/sbin/iptables -I FORWARD -i %s -s %s -j DROP",
135 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd)) {
136 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
137 logmessage(1,msg,"iptables",0);
138 return;
139 }
140 if (snprintf(iptcmd2,sizeof(iptcmd2)-1,
141 "/sbin/iptables -I INPUT -i %s -s %s -j DROP",
142 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd2)) {
143 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
144 logmessage(1,msg,"iptables",0);
145 return;
146 }
147 break;
148 case FWSAM_HOW_OUT:
149 /* Assemble command */
150 if (snprintf(iptcmd,sizeof(iptcmd)-1,
151 "/sbin/iptables -I FORWARD -i %s -d %s -j DROP",
152 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd)) {
153 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
154 logmessage(1,msg,"iptables",0);
155 return;
156 }
157 if (snprintf(iptcmd2,sizeof(iptcmd2)-1,
158 "/sbin/iptables -I INPUT -i %s -d %s -j DROP",
159 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd2)) {
160 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
161 logmessage(1,msg,"iptables",0);
162 return;
163 }
164 break;
165 case FWSAM_HOW_INOUT:
166 /* Assemble command - block src*/
167 if ((snprintf(iptcmd,sizeof(iptcmd)-1,
168 "/sbin/iptables -I FORWARD -i %s -s %s -j DROP",
169 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd)) || (snprintf(iptcmd1,sizeof(iptcmd1)-1,
170 "/sbin/iptables -I FORWARD -i %s -d %s -j DROP",
171 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd1))) {
172 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
173 logmessage(1,msg,"iptables",0);
174 return;
175 }
176 if ((snprintf(iptcmd2,sizeof(iptcmd2)-1,
177 "/sbin/iptables -I INPUT -i %s -s %s -j DROP",
178 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd2)) || (snprintf(iptcmd4,sizeof(iptcmd4)-1,
179 "/sbin/iptables -I INPUT -i %s -d %s -j DROP",
180 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd4))) {
181 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
182 logmessage(1,msg,"iptables",0);
183 return;
184 }
185 break;
186 case FWSAM_HOW_THIS:
187 /* Assemble command */
188 if (snprintf(iptcmd,sizeof(iptcmd)-1,
189 "/sbin/iptables -I FORWARD -i %s -s %s -d %s -p %d --dport %d -j DROP",
190 iptp->iface, inettoa(bd->blockip), inettoa(bd->peerip), bd->proto, bd->port) >= sizeof(iptcmd)) {
191 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
192 logmessage(1,msg,"iptables",0);
193 return;
194 }
195 if (snprintf(iptcmd2,sizeof(iptcmd2)-1,
196 "/sbin/iptables -I INPUT -i %s -s %s -d %s -p %d --dport %d -j DROP",
197 iptp->iface, inettoa(bd->blockip), inettoa(bd->peerip), bd->proto, bd->port) >= sizeof(iptcmd2)) {
198 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
199 logmessage(1,msg,"iptables",0);
200 return;
201 }
202 break;
203 }
204 }
205 else
206 {
207 snprintf(msg,sizeof(msg)-1,"Info: UnBlocking ip %s", inettoa(bd->blockip));
208 logmessage(1,msg,"iptables",0);
209 switch(bd->mode&FWSAM_HOW)
210 { case FWSAM_HOW_IN:
211 /* Assemble command */
212 if (snprintf(iptcmd,sizeof(iptcmd)-1,
213 "/sbin/iptables -D FORWARD -i %s -s %s -j DROP",
214 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd)) {
215 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
216 logmessage(1,msg,"iptables",0);
217 return;
218 }
219 if (snprintf(iptcmd2,sizeof(iptcmd2)-1,
220 "/sbin/iptables -D INPUT -i %s -s %s -j DROP",
221 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd2)) {
222 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
223 logmessage(1,msg,"iptables",0);
224 return;
225 }
226 break;
227 case FWSAM_HOW_OUT:
228 /* Assemble command */
229 if (snprintf(iptcmd,sizeof(iptcmd)-1,
230 "/sbin/iptables -D FORWARD -i %s -d %s -j DROP",
231 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd)) {
232 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
233 logmessage(1,msg,"iptables",0);
234 return;
235 }
236 if (snprintf(iptcmd2,sizeof(iptcmd2)-1,
237 "/sbin/iptables -D INPUT -i %s -d %s -j DROP",
238 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd2)) {
239 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
240 logmessage(1,msg,"iptables",0);
241 return;
242 }
243 break;
244 case FWSAM_HOW_INOUT:
245 /* Assemble command - block src*/
246 if ((snprintf(iptcmd,sizeof(iptcmd)-1,
247 "/sbin/iptables -D FORWARD -i %s -s %s -j DROP",
248 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd)) || (snprintf(iptcmd1,sizeof(iptcmd1)-1,
249 "/sbin/iptables -D FORWARD -i %s -d %s -j DROP",
250 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd1))) {
251 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
252 logmessage(1,msg,"iptables",0);
253 return;
254 }
255 if ((snprintf(iptcmd2,sizeof(iptcmd2)-1,
256 "/sbin/iptables -D INPUT -i %s -s %s -j DROP",
257 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd2)) || (snprintf(iptcmd4,sizeof(iptcmd4)-1,
258 "/sbin/iptables -D INPUT -i %s -d %s -j DROP",
259 iptp->iface, inettoa(bd->blockip)) >= sizeof(iptcmd4))) {
260 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
261 logmessage(1,msg,"iptables",0);
262 return;
263 }
264 break;
265 case FWSAM_HOW_THIS:
266 /* Assemble command */
267 if (snprintf(iptcmd,sizeof(iptcmd)-1,
268 "/sbin/iptables -D FORWARD -i %s -s %s -d %s -p %d --dport %d -j DROP",
269 iptp->iface, inettoa(bd->blockip), inettoa(bd->peerip), bd->proto, bd->port) >= sizeof(iptcmd)) {
270 snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", iptcmd);
271 logmessage(1,msg,"iptables",0);
272 return;
273 }
274 if (snprintf(iptcmd2,sizeof(iptcmd2)-1,
275 "/sbin/iptables -D INPUT -i %s -s %s -d %s -p %d --dport %d -j DROP",
276 iptp->iface, inettoa(bd->blockip), inettoa(bd->peerip), bd->proto, bd->port) >= sizeof(iptcmd)) {
277 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s is too long", iptcmd2);
278 logmessage(1,msg,"iptables",0);
279 return;
280 }
281 break;
282 }
283 }
284 #ifdef FWSAMDEBUG
285 printf("Debug: [iptables][%lx] command %s\n", threadid, iptcmd);
286 printf("Debug: [iptables][%lx] command2 %s\n", threadid, iptcmd2);
287 #endif
288 /* Run the command */
289 if (system(iptcmd) != 0) {
290 snprintf(msg,sizeof(msg)-1,"Error: Command %s Failed", iptcmd);
291 logmessage(3,msg,"iptables",0);
292 } else {
293 snprintf(msg,sizeof(msg)-1,"Info: Command %s Executed Successfully", iptcmd);
294 logmessage(3,msg,"iptables",0);
295 }
296 if (system(iptcmd2) != 0) {
297 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s Failed", iptcmd2);
298 logmessage(1,msg,"iptables",0);
299 } else {
300 snprintf(msg,sizeof(msg)-1,"Info: Command2 %s Executed Successfully", iptcmd2);
301 logmessage(3,msg,"iptables",0);
302 }
303
304 /*inventiva-recorte*/
305 if((bd->mode&FWSAM_HOW)==FWSAM_HOW_INOUT)
306 {
307 if (system(iptcmd1) != 0) {
308 snprintf(msg,sizeof(msg)-1,"Error: Command %s Failed", iptcmd1);
309 logmessage(3,msg,"iptables",0);
310 } else {
311 snprintf(msg,sizeof(msg)-1,"Info: Command %s Executed Successfully", iptcmd1);
312 logmessage(3,msg,"iptables",0);
313 }
314 if (system(iptcmd4) != 0) {
315 snprintf(msg,sizeof(msg)-1,"Error: Command2 %s Failed", iptcmd4);
316 logmessage(1,msg,"iptables",0);
317 } else {
318 snprintf(msg,sizeof(msg)-1,"Info: Command2 %s Executed Successfully", iptcmd4);
319 logmessage(3,msg,"iptables",0);
320 }
321 }
322
323
324 #ifdef SAVETABLES
325 /* Save command */
326 if (system(savecmd) != 0) {
327 snprintf(msg,sizeof(msg)-1,"Error: Save command %s Failed",savecmd);
328 logmessage(1,msg,"iptables",0);
329 } else {
330 snprintf(msg,sizeof(msg)-1,"Info: Save command %s Executed Successfully", savecmd);
331 logmessage(3,msg,"iptables",0);
332 }
333 #endif
334
335 return;
336 }
337
338 #endif /* __SSP_IPT_C__ */
339 #endif /* Linux */
340
341
342