forked from ossec/ossec-hids
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfirewall-drop.sh
executable file
·300 lines (256 loc) · 7.1 KB
/
firewall-drop.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#!/bin/sh
# Adds an IP to the iptables drop list (if linux)
# Adds an IP to the ipfilter drop list (if solaris, freebsd or netbsd)
# Adds an IP to the ipsec drop list (if aix)
# Requirements: Linux with iptables, Solaris/FreeBSD/NetBSD with ipfilter or AIX with IPSec
# Expect: srcip
# Author: Ahmet Ozturk (ipfilter and IPSec)
# Author: Daniel B. Cid (iptables)
# Author: cgzones
# Last modified: Oct 04, 2012
UNAME=`uname`
ECHO="/bin/echo"
GREP="/bin/grep"
IPTABLES=""
IP4TABLES="/sbin/iptables"
IP6TABLES="/sbin/ip6tables"
IPFILTER="/sbin/ipf"
if [ "X$UNAME" = "XSunOS" ]; then
IPFILTER="/usr/sbin/ipf"
fi
GENFILT="/usr/sbin/genfilt"
LSFILT="/usr/sbin/lsfilt"
MKFILT="/usr/sbin/mkfilt"
RMFILT="/usr/sbin/rmfilt"
ARG1=""
ARG2=""
RULEID=""
ACTION=$1
USER=$2
IP=$3
PWD=`pwd`
LOCK="${PWD}/fw-drop"
LOCK_PID="${PWD}/fw-drop/pid"
IPV4F="/proc/sys/net/ipv4/ip_forward"
IPV6F="/proc/sys/net/ipv6/conf/all/forwarding"
LOCAL=`dirname $0`;
cd $LOCAL
cd ../
filename=$(basename "$0")
LOG_FILE="${PWD}/../logs/active-responses.log"
echo "`date` $0 $1 $2 $3 $4 $5" >> ${LOG_FILE}
# Checking for an IP
if [ "x${IP}" = "x" ]; then
echo "$0: <action> <username> <ip>"
exit 1;
fi
case "${IP}" in
*:* ) IPTABLES=$IP6TABLES;;
*.* ) IPTABLES=$IP4TABLES;;
* ) echo "`date` Unable to run active response (invalid IP: '${IP}')." >> ${LOG_FILE} && exit 1;;
esac
# This number should be more than enough (even if a hundred
# instances of this script is ran together). If you have
# a really loaded env, you can increase it to 75 or 100.
MAX_ITERATION="50"
# Lock function
lock()
{
i=0;
# Providing a lock.
while [ 1 ]; do
mkdir ${LOCK} > /dev/null 2>&1
MSL=$?
if [ "${MSL}" = "0" ]; then
# Lock acquired (setting the pid)
echo "$$" > ${LOCK_PID}
return;
fi
# Getting currently/saved PID locking the file
C_PID=`cat ${LOCK_PID} 2>/dev/null`
if [ "x" = "x${S_PID}" ]; then
S_PID=${C_PID}
fi
# Breaking out of the loop after X attempts
if [ "x${C_PID}" = "x${S_PID}" ]; then
i=`expr $i + 1`;
fi
sleep $i;
i=`expr $i + 1`;
# So i increments 2 by 2 if the pid does not change.
# If the pid keeps changing, we will increments one
# by one and fail after MAX_ITERACTION
if [ "$i" = "${MAX_ITERATION}" ]; then
kill="false"
for pid in `pgrep -f "${filename}"`; do
if [ "x${pid}" = "x${C_PID}" ]; then
# Unlocking and exiting
kill -9 ${C_PID}
echo "`date` Killed process ${C_PID} holding lock." >> ${LOG_FILE}
kill="true"
unlock;
i=0;
S_PID="";
break;
fi
done
if [ "x${kill}" = "xfalse" ]; then
echo "`date` Unable kill process ${C_PID} holding lock." >> ${LOG_FILE}
# Unlocking and exiting
unlock;
exit 1;
fi
fi
done
}
# Unlock function
unlock()
{
rm -rf ${LOCK}
}
# Blocking IP
if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then
echo "$0: invalid action: ${ACTION}"
exit 1;
fi
# We should run on linux
if [ "X${UNAME}" = "XLinux" ]; then
if [ "x${ACTION}" = "xadd" ]; then
ARG1="-I INPUT -s ${IP} -j DROP"
ARG2="-I FORWARD -s ${IP} -j DROP"
else
ARG1="-D INPUT -s ${IP} -j DROP"
ARG2="-D FORWARD -s ${IP} -j DROP"
fi
# Checking if iptables is present
if [ ! -x ${IPTABLES} ]; then
IPTABLES="/usr"${IPTABLES}
if [ ! -x ${IPTABLES} ]; then
echo "$0: can not find iptables"
exit 0;
fi
fi
# Executing and exiting
COUNT=0;
lock;
while [ 1 ]; do
${IPTABLES} ${ARG1}
RES=$?
if [ $RES = 0 ]; then
break;
else
COUNT=`expr $COUNT + 1`;
echo "`date` Unable to run (iptables returning != $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE}
sleep $COUNT;
if [ $COUNT -gt 4 ]; then
break;
fi
fi
done
COUNT=0;
while [ 1 ]; do
#
# Looking for IPV4 and IPV6 FORWARD
#
if [ -e "$IPV4F" ]
then
IPV4KEY="$(cat "$IPV4F")"
else
IPV4KEY="0"
fi
if [ -e "$IPV6F" ]
then
IPV6KEY="$(cat "$IPV6F")"
else
IPV6KEY="0"
fi
if [ "$IPV4KEY" = "0" ] && [ "$IPV6KEY" = "0" ]
then
break
fi
${IPTABLES} ${ARG2}
RES=$?
if [ $RES = 0 ]; then
break;
else
COUNT=`expr $COUNT + 1`;
echo "`date` Unable to run (iptables returning != $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE}
sleep $COUNT;
if [ $COUNT -gt 4 ]; then
break;
fi
fi
done
unlock;
exit 0;
# FreeBSD, SunOS or NetBSD with ipfilter
elif [ "X${UNAME}" = "XFreeBSD" -o "X${UNAME}" = "XSunOS" -o "X${UNAME}" = "XNetBSD" ]; then
# Checking if ipfilter is present
ls ${IPFILTER} >> /dev/null 2>&1
if [ $? != 0 ]; then
exit 0;
fi
# Checking if echo is present
ls ${ECHO} >> /dev/null 2>&1
if [ $? != 0 ]; then
exit 0;
fi
if [ "x${ACTION}" = "xadd" ]; then
ARG1="\"@1 block out quick from any to ${IP}\""
ARG2="\"@1 block in quick from ${IP} to any\""
IPFARG="${IPFILTER} -f -"
else
ARG1="\"@1 block out quick from any to ${IP}\""
ARG2="\"@1 block in quick from ${IP} to any\""
IPFARG="${IPFILTER} -rf -"
fi
# Executing it
eval ${ECHO} ${ARG1}| ${IPFARG}
eval ${ECHO} ${ARG2}| ${IPFARG}
exit 0;
# AIX with ipsec
elif [ "X${UNAME}" = "XAIX" ]; then
# Checking if genfilt is present
ls ${GENFILT} >> /dev/null 2>&1
if [ $? != 0 ]; then
exit 0;
fi
# Checking if lsfilt is present
ls ${LSFILT} >> /dev/null 2>&1
if [ $? != 0 ]; then
exit 0;
fi
# Checking if mkfilt is present
ls ${MKFILT} >> /dev/null 2>&1
if [ $? != 0 ]; then
exit 0;
fi
# Checking if rmfilt is present
ls ${RMFILT} >> /dev/null 2>&1
if [ $? != 0 ]; then
exit 0;
fi
if [ "x${ACTION}" = "xadd" ]; then
ARG1=" -v 4 -a D -s ${IP} -m 255.255.255.255 -d 0.0.0.0 -M 0.0.0.0 -w B -D \"Access Denied by OSSEC-HIDS\""
#Add filter to rule table
eval ${GENFILT} ${ARG1}
#Deactivate and activate the filter rules.
eval ${MKFILT} -v 4 -d
eval ${MKFILT} -v 4 -u
else
# removing a specific rule is not so easy :(
eval ${LSFILT} -v 4 -O | ${GREP} ${IP} |
while read -r LINE
do
RULEID=`${ECHO} ${LINE} | cut -f 1 -d "|"`
let RULEID=${RULEID}+1
ARG1=" -v 4 -n ${RULEID}"
eval ${RMFILT} ${ARG1}
done
#Deactivate and activate the filter rules.
eval ${MKFILT} -v 4 -d
eval ${MKFILT} -v 4 -u
fi
else
exit 0;
fi