From a4aba2cad0a1ef7fa9b369b4e0d8e760c301275e Mon Sep 17 00:00:00 2001 From: Ignace Date: Mon, 24 Mar 2025 21:28:20 +0000 Subject: [PATCH] first --- .gitignore | 1 + createGraphs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ createRRDs | 17 ++++++++++++++++ disable | 28 +++++++++++++++++++++++++ getCloudFails | 26 ++++++++++++++++++++++++ getFlowerFails | 19 +++++++++++++++++ getGitFails | 15 ++++++++++++++ getOthers | 20 ++++++++++++++++++ getSSHfails | 24 ++++++++++++++++++++++ getWalled | 21 +++++++++++++++++++ last10 | 16 +++++++++++++++ last10mins | 19 +++++++++++++++++ reset | 30 +++++++++++++++++++++++++++ run10 | 5 +++++ updateRRDs | 31 ++++++++++++++++++++++++++++ 15 files changed, 327 insertions(+) create mode 100644 .gitignore create mode 100755 createGraphs create mode 100644 createRRDs create mode 100755 disable create mode 100755 getCloudFails create mode 100755 getFlowerFails create mode 100755 getGitFails create mode 100755 getOthers create mode 100755 getSSHfails create mode 100755 getWalled create mode 100755 last10 create mode 100755 last10mins create mode 100755 reset create mode 100755 run10 create mode 100755 updateRRDs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..09173cc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.rrd diff --git a/createGraphs b/createGraphs new file mode 100755 index 0000000..74e14b4 --- /dev/null +++ b/createGraphs @@ -0,0 +1,55 @@ +#!/bin/bash + +# this script is started: +# - manual, from the monitor folder +# - cronwise, from the project-HOME folder +# usage: +# ./createGraphs 1d # or 1h or 2w or 1y + +cd /opt/Monitor/fw + +# the output of this script can only be visualized under a webserver +FOLDER='/var/www/suy.nl/m' + +function makegraphs { + P=${1} + + rrdtool graph ${FOLDER}/${P}/ssh-auth.png \ + --title "SSH attacks, last ${P}" \ + --width 640 \ + --height 240 \ + --start -${P} \ + --watermark "$(date)" \ + --vertical-label 'Count' \ + DEF:r0=auth.rrd:walled:AVERAGE \ + AREA:r0#EB984E:"FW-walled" \ + DEF:r1=auth.rrd:ssh:AVERAGE \ + AREA:r1#F7DC6F:”SSH-walled” \ + DEF:r3=auth.rrd:denied:AVERAGE \ + LINE2:r3#FF0000:”FW-denied” + + rrdtool graph ${FOLDER}/${P}/services-auth.png \ + --title "Service attacks, last ${P}" \ + --width 640 \ + --height 240 \ + --upper-limit 5 \ + --lower-limit 0 \ + --start -${P} \ + --vertical-label 'Count' \ + --watermark "$(date)" \ + DEF:r3=auth.rrd:other:AVERAGE \ + AREA:r3#AAAAAA:”Others” \ + DEF:r0=auth.rrd:flowers:AVERAGE \ + AREA:r0#FFA500:"Flowers" \ + DEF:r1=auth.rrd:gitea:AVERAGE \ + STACK:r1#0000FF:”Gitea” \ + DEF:r2=auth.rrd:cloud:AVERAGE \ + STACK:r2#FF0000:”Cloud” + +} + +for var in "$@" +do + makegraphs "$var" +done + diff --git a/createRRDs b/createRRDs new file mode 100644 index 0000000..a0cad17 --- /dev/null +++ b/createRRDs @@ -0,0 +1,17 @@ +rrdtool create auth.rrd \ + --step 600 \ + DS:ssh:GAUGE:1200:U:U \ + DS:blocked:GAUGE:1200:U:U \ + DS:denied:GAUGE:1200:U:U \ + DS:flowers:GAUGE:1200:U:U \ + DS:gitea:GAUGE:1200:U:U \ + DS:plex:GAUGE:1200:U:U \ + DS:cloud:GAUGE:1200:U:U \ + DS:other:GAUGE:1200:U:U \ + DS:walled:GAUGE:1200:U:U \ + RRA:AVERAGE:0.5:1:288 \ + RRA:AVERAGE:0.5:6:192 \ + RRA:AVERAGE:0.5:18:256 \ + RRA:AVERAGE:0.5:144:750 + + diff --git a/disable b/disable new file mode 100755 index 0000000..b2872b1 --- /dev/null +++ b/disable @@ -0,0 +1,28 @@ +#!/bin/bash +# run this every 10 mins +# if string is found in apache2 log, last 10 minutes, then disable the ufw +RDT=$(grep 93048r7203498v093840r2934870r29380h4fr239nh840r27840ndr489 /var/log/apache2/access.log | tail -1 | awk '$0=$2' FS=[ RS=] |sed -e 's,/,-,g' -e 's,:, ,') +if [[ ${RDT} > '' ]]; then + DT=$(date --date="${RDT}" +"%s") + NOW=$(date +"%s") + (( SECS = NOW - DT )) + # echo "$RDT, $DT, $NOW, $SECS" + if [[ ${SECS} -lt 700 ]] ; then + echo "will stop the FW" + addEvent.sh "ERROR,ufw,0,0,Firewall has been stopped by apache-log (ignace code)" + ufw disable + fi +fi + +RDT=$(grep 648934852480922541718468161210828654060355211868993811248702 /var/log/apache2/access.log | tail -1 | awk '$0=$2' FS=[ RS=] |sed -e 's,/,-,g' -e 's,:, ,') +if [[ ${RDT} > '' ]]; then + DT=$(date --date="${RDT}" +"%s") + NOW=$(date +"%s") + (( SECS = NOW - DT )) + # echo "$RDT, $DT, $NOW, $SECS" + if [[ ${SECS} -lt 700 ]] ; then + echo "will reset the FW" + addEvent.sh "ERROR,ufw,0,0,Firewall has been reset by apache-log (severines code)" + /opt/Monitor/fw/reset + fi +fi diff --git a/getCloudFails b/getCloudFails new file mode 100755 index 0000000..744fd61 --- /dev/null +++ b/getCloudFails @@ -0,0 +1,26 @@ +#!/bin/bash + +# pick the last 10 mins of the owncloud.log (2000 lines should cover that) and count the auth failures +# format logfile: +# {"reqId":"O2znvT7UAsoLNo7X7O7W","level":2,"time":"2020-12-29T15:36:37+00:00","remoteAddr":"213.46.222.164","user":"--","app":"core","method":"POST","url":"\/cloud\/index.php\/login","message":"Login failed: 'Ignace. h' (Remote IP: '213.46.222.164')"} + +ERRORFILE='/tmp/cloud_error.log' +rm -f ${ERRORFILE} +touch ${ERRORFILE} + +NOW=$(date +"%s") +tail -2000 /var/www/owncloud/data/owncloud.log | grep 'Login failed' | while read -r LINE; do + RDT=$( echo ${LINE} | awk -F'"' '{print $10}') + D="${RDT:0:10}" + D=$( echo ${D} | awk -F'-' '{print $2 "/" $3 "/" $1}') + DT="${D} ${RDT:11:14}" + DT=$(date --date="${DT}" +"%s") + (( SECS = NOW - DT )) + if [[ ${SECS} -lt 601 ]] ; then + echo $LINE} >>${ERRORFILE} + IP=$(echo ${LINE} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b") + addEvent.sh "BLOCK,${IP},3,5,Unauthorized authorization attempt in ownCloud" + fi +done + +cat ${ERRORFILE} | wc -l diff --git a/getFlowerFails b/getFlowerFails new file mode 100755 index 0000000..42cec8b --- /dev/null +++ b/getFlowerFails @@ -0,0 +1,19 @@ +#!/bin/bash + +ERRORFILE='/tmp/flowers_apache2.log' +rm -f ${ERRORFILE} +touch ${ERRORFILE} + +NOW=$(date +"%s") +grep 'Flowers - authorization failed' /var/log/apache2/error.log | while read -r LINE; do + RDT="${LINE:1:31}" + DT=$(date --date="${RDT}" +"%s") + (( SECS = NOW - DT )) + # echo "$RDT, $DT, $NOW, $SECS" + if [[ ${SECS} -lt 601 ]] ; then + echo $LINE >>${ERRORFILE} + IP=$(echo ${LINE} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b") + addEvent.sh "BLOCK,${IP},5,5,Unauthorized authorization attempt in Flowers" + fi +done +cat ${ERRORFILE} | wc -l diff --git a/getGitFails b/getGitFails new file mode 100755 index 0000000..5d83b6f --- /dev/null +++ b/getGitFails @@ -0,0 +1,15 @@ +#!/bin/bash + +# pick the last 10 mins of the git.log (2000 lines should cover that) and count the auth failures +# format logfile: +# 2020/12/29 15:41:45 ...xorm/session_find.go:199......... + +ERRORFILE='/tmp/gitea_error.log' + +tail -2000 /var/lib/gitea/log/gitea.log | grep 'Failed authentication' | ./last10mins gitea >${ERRORFILE} +cat ${ERRORFILE} | while read -r LINE; do + IP=$(echo ${LINE} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b") + addEvent.sh "BLOCK,${IP},3,5,Unauthorized authorization attempt in Gitea" +done + +cat ${ERRORFILE} | wc -l diff --git a/getOthers b/getOthers new file mode 100755 index 0000000..8cf8b87 --- /dev/null +++ b/getOthers @@ -0,0 +1,20 @@ +#!/bin/bash +# run this every 10 mins +# if someone knocks at the apache server for a non-existing url, 3 times - then block + +ERRORFILE='/tmp/badurls_apache2.log' +rm -f ${ERRORFILE} +touch ${ERRORFILE} + +awk -vDate=`date -d'now-10 minutes' +[%d/%b/%Y:%H:%M:%S` '$4 > Date {print Date, $0}' /var/log/apache2/access.log | while read -r LINE; do + STATUZ=$( echo ${LINE} | awk -F' ' '{print $10;}') + + if [[ "${STATUZ}" == '"-"' ]] || [[ ${STATUZ} -gt 399 ]]; then + echo ${LINE} >>${ERRORFILE} + # echo ${LINE} + IP=$(echo ${LINE} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b") + addEvent.sh "BLOCK,${IP},10,30,Fishing for URL in apache2" + fi +done + +cat ${ERRORFILE} | wc -l diff --git a/getSSHfails b/getSSHfails new file mode 100755 index 0000000..4f394fd --- /dev/null +++ b/getSSHfails @@ -0,0 +1,24 @@ +#!/bin/bash + +IPSFILE="/tmp/lastIPs.txt" + +if [[ $1 == 'count' ]] ; then + # pick the last 10 mins of the auth.log (2000 lines should cover that) and count the auth failures for ssh + rm -f ${IPSFILE} + NOW=$(date +"%s") + tail -2000 /var/log/auth.log | grep sshd | grep -e "failure" -e "invalid" | ./last10mins | while read LINE; do + # send the ip-address to a temp file + echo "$LINE" | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" >>${IPSFILE} + done + # count the number of lines found + cat ${IPSFILE} | wc -l +fi + +if [[ $1 == 'block' ]] ; then + cat ${IPSFILE} | sort -u | while read LINE; do + IP=$(echo ${LINE} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b") + addEvent.sh "BLOCK,${IP},0,0,Unauthorized authorization attempt in SSH" + # ufw deny from $LINE + done + cat ${IPSFILE} | sort -u | wc -l +fi diff --git a/getWalled b/getWalled new file mode 100755 index 0000000..b387314 --- /dev/null +++ b/getWalled @@ -0,0 +1,21 @@ +#!/bin/bash + +# picks up iptables/ufw message from the kernel log +# you need to enable the following line in /etc/rsyslog.conf +# module(load="imklog" permitnonkernelfacility="on") +# and enable ufw logging: +# ufw logging on + +# pick the last 10 mins of the kern.log (2000 lines should cover that) and count the auth failures for ssh +if [[ ${1} == '+22' ]]; then + tail -2000 /var/log/kern.log | grep '\[UFW BL' | grep 'DPT=22 ' |./last10mins | wc -l +elif [[ ${1} == '-22' ]]; then + tail -2000 /var/log/kern.log | grep '\[UFW BL' | grep -v 'DPT=22 ' |./last10mins | wc -l +else + # tail -2000 /var/log/kern.log | grep '\[UFW BL' | ./last10mins | wc -l + tail -2000 /var/log/kern.log | grep '\[UFW BL' | ./last10mins | sed "s/^.*SRC=\([0-9.]*\) .*$/\1/" >/tmp/scanning.tmp + cat /tmp/scanning.tmp | while read IP; do + addEvent.sh "BLOCK,${IP},5,5,Portscanning attempt" + done + cat /tmp/scanning.tmp | wc -l +fi diff --git a/last10 b/last10 new file mode 100755 index 0000000..a12c28c --- /dev/null +++ b/last10 @@ -0,0 +1,16 @@ +#!/bin/bash +# read from STDIN, lines coming from rsyslog files. Pass to STDOUT any line with timestamp younger than 10 mins +while read -r LINE; do + D="${LINE:0:10}" + echo $D + D=$( echo $D | awk -F/ '{print $2 "/" $3 "/" $1}') + echo $D + DT="${D} ${LINE:11:8}" + echo $DT + DT=$(date --date="${DT}" +"%s") + (( SECS = NOW - DT )) + if [[ ${SECS} -lt 601 ]] ; then + echo "$LINE" + fi +done + diff --git a/last10mins b/last10mins new file mode 100755 index 0000000..8232052 --- /dev/null +++ b/last10mins @@ -0,0 +1,19 @@ +#!/bin/bash +# read from STDIN, lines coming from rsyslog files. Pass to STDOUT any line with timestamp younger than 10 mins +MODE=$1 # supported: or "gitea" +NOW=$(date +"%s") +while read -r LINE; do + if [[ ${MODE} == 'gitea' ]]; then + D="${LINE:0:10}" + D=$( echo $D | awk -F/ '{print $2 "/" $3 "/" $1}') + DT="${D} ${LINE:11:8}" + else + DT=${LINE:0:15} + fi + DT=$(date --date="${DT}" +"%s") + (( SECS = NOW - DT )) + if [[ ${SECS} -lt 601 ]] ; then + echo "$LINE" + fi +done + diff --git a/reset b/reset new file mode 100755 index 0000000..38aaba9 --- /dev/null +++ b/reset @@ -0,0 +1,30 @@ +#!/bin/bash + +ufw --force reset + +# allow all from V20 +V20='85.144.254.63' +ufw allow ssh rom ${V20} +# ufw allow ftp rom ${V20} + +while read -r ip +do + ufw allow from ${ip} +done < "/root/SAVEIPS" + +# apache +ufw allow http +ufw allow https + +# gitea +ufw allow 3000 + +# plex: +ufw allow 32400 +# ufw allow 34444 +# optional plex for iternal networkl discovery +# ufw allow 32410:32414/udp +# ufw allow 19000/udp + +ufw logging low +ufw enable diff --git a/run10 b/run10 new file mode 100755 index 0000000..188ea35 --- /dev/null +++ b/run10 @@ -0,0 +1,5 @@ +#!/bin/bash + +echo "run10" +echo $(date) + diff --git a/updateRRDs b/updateRRDs new file mode 100755 index 0000000..46d676e --- /dev/null +++ b/updateRRDs @@ -0,0 +1,31 @@ +#!/bin/bash + +echo $(date) +cd /opt/Monitor/fw + +SSH=0 +BLOCKED=0 +DENIED=0 +FLOWERS=0 +GITEA=0 +PLEX=0 +CLOUD=0 +OTHER=0 +WALLED=0 + +SSH=$(./getWalled '+22') + +DENIED=$(ufw status | grep -c DENY) +FLOWERS=$(./getFlowerFails) +# GITEA=$(./getGitFails) +GITEA=0 + +CLOUD=$(./getCloudFails) +OTHER=$(./getOthers) +WALLED=$(./getWalled '-22') + + +echo " N:${SSH}:${BLOCKED}:${DENIED}:${FLOWERS}:${GITEA}:${PLEX}:${CLOUD}:${OTHER}:${WALLED}" +rrdtool update auth.rrd N:${SSH}:${BLOCKED}:${DENIED}:${FLOWERS}:${GITEA}:${PLEX}:${CLOUD}:${OTHER}:${WALLED} +echo " done" +/opt/Monitor/fw/createGraphs 3h 1d 2w 1y