8ce30974063f653590a41ece893dafa763636b24
[ossec-hids.git] / debian / ossec-hids / var / ossec / active-response / bin / firewalld-drop.sh
1 #!/bin/sh
2 # Adds an IP to the firewalld drop list
3 # Requirements: Linux with firewalld
4 # Expect: srcip
5 # Author: Daniel B. Cid (iptables)
6 # Author: cgzones
7 # Author: ChristianBeer
8 # Last modified: Apr 10, 2015
9
10 UNAME=`uname`
11 ECHO="/bin/echo"
12 GREP="/bin/grep"
13 FWDCMD="/bin/firewall-cmd"
14 RULE=""
15 ARG1=""
16 # ARG2 can be used to specify the zone where the rich rule should be added otherwise it adds it to the default zone
17 ARG2=""
18 #ARG2="--zone=external"
19 RULEID=""
20 ACTION=$1
21 USER=$2
22 IP=$3
23 PWD=`pwd`
24 LOCK="${PWD}/fw-drop"
25 LOCK_PID="${PWD}/fw-drop/pid"
26
27
28 LOCAL=`dirname $0`;
29 cd $LOCAL
30 cd ../
31 filename=$(basename "$0")
32
33 LOG_FILE="${PWD}/../logs/active-responses.log"
34
35 echo "`date` $0 $1 $2 $3 $4 $5" >> ${LOG_FILE}
36
37
38 # Checking for an IP
39 if [ "x${IP}" = "x" ]; then
40    echo "$0: <action> <username> <ip>"
41    exit 1;
42 fi
43
44 case "${IP}" in
45     *:* ) RULE="rule family='ipv6' source address='${IP}' drop";;
46     *.* ) RULE="rule family='ipv4' source address='${IP}' drop";;
47     * ) echo "`date` Unable to run active response (invalid IP: '${IP}')." >> ${LOG_FILE} && exit 1;;
48 esac
49
50 # This number should be more than enough (even if a hundred
51 # instances of this script is ran together). If you have
52 # a really loaded env, you can increase it to 75 or 100.
53 MAX_ITERATION="50"
54
55 # Lock function
56 lock()
57 {
58     i=0;
59     # Providing a lock.
60     while [ 1 ]; do
61         mkdir ${LOCK} > /dev/null 2>&1
62         MSL=$?
63         if [ "${MSL}" = "0" ]; then
64             # Lock acquired (setting the pid)
65             echo "$$" > ${LOCK_PID}
66             return;
67         fi
68
69         # Getting currently/saved PID locking the file
70         C_PID=`cat ${LOCK_PID} 2>/dev/null`
71         if [ "x" = "x${S_PID}" ]; then
72             S_PID=${C_PID}
73         fi
74
75         # Breaking out of the loop after X attempts
76         if [ "x${C_PID}" = "x${S_PID}" ]; then
77             i=`expr $i + 1`;
78         fi
79
80         sleep $i;
81
82         i=`expr $i + 1`;
83
84         # So i increments 2 by 2 if the pid does not change.
85         # If the pid keeps changing, we will increments one
86         # by one and fail after MAX_ITERACTION
87
88         if [ "$i" = "${MAX_ITERATION}" ]; then
89             kill="false"
90             for pid in `pgrep -f "${filename}"`; do
91                 if [ "x${pid}" = "x${C_PID}" ]; then
92                     # Unlocking and exiting
93                     kill -9 ${C_PID}
94                     echo "`date` Killed process ${C_PID} holding lock." >> ${LOG_FILE}
95                     kill="true"
96                     unlock;
97                     i=0;
98                     S_PID="";
99                     break;
100                 fi
101             done
102
103             if [ "x${kill}" = "xfalse" ]; then
104                 echo "`date` Unable kill process ${C_PID} holding lock." >> ${LOG_FILE}
105                 # Unlocking and exiting
106                 unlock;
107                 exit 1;
108             fi
109         fi
110     done
111 }
112
113 # Unlock function
114 unlock()
115 {
116    rm -rf ${LOCK}
117 }
118
119
120
121 # Blocking IP
122 if [ "x${ACTION}" != "xadd" -a "x${ACTION}" != "xdelete" ]; then
123    echo "$0: invalid action: ${ACTION}"
124    exit 1;
125 fi
126
127
128
129 # We should run on linux
130 if [ "X${UNAME}" = "XLinux" ]; then
131    if [ "x${ACTION}" = "xadd" ]; then
132       ARG1="--add-rich-rule="
133    else
134       ARG1="--remove-rich-rule="
135    fi
136
137    # Checking if firewall-cmd is present
138    if [ ! -x ${FWDCMD} ]; then
139       FWDCMD="/usr"${FWDCMD}
140       if [ ! -x ${FWDCMD} ]; then
141         echo "$0: can not find firewall-cmd"
142         exit 1;
143       fi
144    fi
145
146    # Executing and exiting
147    COUNT=0;
148    lock;
149    while [ 1 ]; do
150         ${FWDCMD} ${ARG1}"${RULE}" ${ARG2} >/dev/null
151         RES=$?
152         if [ $RES = 0 ]; then
153             break;
154         else
155             COUNT=`expr $COUNT + 1`;
156             echo "`date` Unable to run (firewall-cmd returning != $RES): $COUNT - $0 $1 $2 $3 $4 $5" >> ${LOG_FILE}
157             sleep $COUNT;
158
159             if [ $COUNT -gt 4 ]; then
160                 break;
161             fi
162         fi
163    done
164    unlock;
165
166    exit 0;
167 else
168    exit 0;
169 fi