X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=active-response%2Ffirewalld-drop.sh;fp=active-response%2Ffirewalld-drop.sh;h=8ce30974063f653590a41ece893dafa763636b24;hp=0000000000000000000000000000000000000000;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/active-response/firewalld-drop.sh b/active-response/firewalld-drop.sh new file mode 100755 index 0000000..8ce3097 --- /dev/null +++ b/active-response/firewalld-drop.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# Adds an IP to the firewalld drop list +# Requirements: Linux with firewalld +# Expect: srcip +# Author: Daniel B. Cid (iptables) +# Author: cgzones +# Author: ChristianBeer +# Last modified: Apr 10, 2015 + +UNAME=`uname` +ECHO="/bin/echo" +GREP="/bin/grep" +FWDCMD="/bin/firewall-cmd" +RULE="" +ARG1="" +# ARG2 can be used to specify the zone where the rich rule should be added otherwise it adds it to the default zone +ARG2="" +#ARG2="--zone=external" +RULEID="" +ACTION=$1 +USER=$2 +IP=$3 +PWD=`pwd` +LOCK="${PWD}/fw-drop" +LOCK_PID="${PWD}/fw-drop/pid" + + +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: " + exit 1; +fi + +case "${IP}" in + *:* ) RULE="rule family='ipv6' source address='${IP}' drop";; + *.* ) RULE="rule family='ipv4' source address='${IP}' drop";; + * ) 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="--add-rich-rule=" + else + ARG1="--remove-rich-rule=" + fi + + # Checking if firewall-cmd is present + if [ ! -x ${FWDCMD} ]; then + FWDCMD="/usr"${FWDCMD} + if [ ! -x ${FWDCMD} ]; then + echo "$0: can not find firewall-cmd" + exit 1; + fi + fi + + # Executing and exiting + COUNT=0; + lock; + while [ 1 ]; do + ${FWDCMD} ${ARG1}"${RULE}" ${ARG2} >/dev/null + RES=$? + if [ $RES = 0 ]; then + break; + else + COUNT=`expr $COUNT + 1`; + echo "`date` Unable to run (firewall-cmd 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; +else + exit 0; +fi