mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-31 07:25:13 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
97c049ed0a
commit
0acff03804
14253 files changed
+3893239
No files matched your search
@@ -0,0 +1,18 @@
|
||||
config beardropper
|
||||
option attemptCount '5'
|
||||
option attemptPeriod '12h'
|
||||
option banLength '1w'
|
||||
option logFacility 'authpriv.notice'
|
||||
option fileStateType 'bddb'
|
||||
option fileStateTempPrefix '/tmp/beardropper'
|
||||
option fileStatePersistPrefix '/etc/beardropper'
|
||||
list firewallHookChain 'input_wan_rule:1'
|
||||
list firewallHookChain 'forwarding_wan_rule:1'
|
||||
option firewallTarget 'DROP'
|
||||
list logRegex 's/[`$"\'\'']//g'
|
||||
list logRegex '/has invalid shell, rejected$/d'
|
||||
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p'
|
||||
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p'
|
||||
option defaultMode 'follow'
|
||||
option enabled '1'
|
||||
option logLevel '2'
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=98
|
||||
|
||||
PROG=/usr/sbin/beardropper
|
||||
SERVICE_DAEMONIZE=1
|
||||
SERVICE_WRITE_PID=1
|
||||
|
||||
getKids() {
|
||||
egrep "^PPid: *$1$" /proc/[0-9]*/s*s 2>/dev/null | cut -f3 -d/ | xargs echo
|
||||
}
|
||||
|
||||
start() {
|
||||
service_start ${PROG} -m follow
|
||||
echo "beardropper started!"
|
||||
}
|
||||
|
||||
stop() {
|
||||
#PID=`cat /var/run/bearDropper.pid`
|
||||
#kill `getKids $PID`
|
||||
kill -9 `pgrep -f /usr/sbin/beardropper`
|
||||
sleep 1
|
||||
service_stop ${PROG}
|
||||
echo "beardropper exit...."
|
||||
}
|
||||
|
||||
restart() {
|
||||
enabled=$(uci get beardropper.@beardropper[0].enabled)
|
||||
pgrep -f ${PROG} >/dev/null
|
||||
if [ $? -eq 0 ];then #running
|
||||
if [ $enabled -eq 1 ]; then
|
||||
stop
|
||||
sleep 1
|
||||
echo "beardropper is restarting..."
|
||||
start
|
||||
else
|
||||
stop
|
||||
fi
|
||||
else
|
||||
if [ $enabled -eq 1 ]; then
|
||||
start
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
[ ! -f "/usr/share/ucitrack/luci-app-beardropper.json" ] && {
|
||||
cat > /usr/share/ucitrack/luci-app-beardropper.json << EEOF
|
||||
{
|
||||
"config": "beardropper",
|
||||
"init": "beardropper"
|
||||
}
|
||||
EEOF
|
||||
}
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@beardropper[-1]
|
||||
add ucitrack beardropper
|
||||
set ucitrack.@beardropper[-1].init=beardropper
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
||||
+517
@@ -0,0 +1,517 @@
|
||||
#!/bin/ash
|
||||
#
|
||||
# beardropper - dropbear log parsing ban agent for OpenWRT (Chaos Calmer rewrite of dropBrute.sh)
|
||||
# http://github.com/robzr/bearDropper -- Rob Zwissler 11/2015
|
||||
#
|
||||
# - lightweight, no dependencies, busybox ash + native OpenWRT commands
|
||||
# - uses uci for configuration, overrideable via command line arguments
|
||||
# - runs continuously in background (via init script) or periodically (via cron)
|
||||
# - uses BIND time shorthand, ex: 1w5d3h1m8s is 1 week, 5 days, 3 hours, 1 minute, 8 seconds
|
||||
# - Whitelist IP or CIDR entries (TBD) in uci config file
|
||||
# - Records state file to tmpfs and intelligently syncs to persistent storage (can disable)
|
||||
# - Persistent sync routines are optimized to avoid excessive writes (persistentStateWritePeriod)
|
||||
# - Every run occurs in one of the following modes. If not specified, interval mode (24 hours) is
|
||||
# the default when not specified (the init script specifies follow mode via command line)
|
||||
#
|
||||
# "follow" mode follows syslog to process entries as they happen; generally launched via init
|
||||
# script. Responds the fastest, runs the most efficiently, but is always in memory.
|
||||
# "interval" mode only processes entries going back the specified interval; requires
|
||||
# more processing than today mode, but responds more accurately. Use with cron.
|
||||
# "today" mode looks at log entries from the day it is being run, simple and lightweight,
|
||||
# generally run from cron periodically (same simplistic behavior as dropBrute.sh)
|
||||
# "entire" mode runs through entire contents of the syslog ring buffer
|
||||
# "wipe" mode tears down the firewall rules and removes the state files
|
||||
|
||||
# Load UCI config variable, or use default if not set
|
||||
# Args: $1 = variable name (also uci option name), $2 = default_value
|
||||
uciSection='beardropper.@[0]'
|
||||
uciLoadVar () {
|
||||
local getUci
|
||||
getUci=`uci -q get ${uciSection}."$1"` || getUci="$2"
|
||||
eval $1=\'$getUci\';
|
||||
}
|
||||
uciLoad() {
|
||||
local tFile=`mktemp` delim="
|
||||
"
|
||||
[ "$1" = -d ] && { delim="$2"; shift 2; }
|
||||
uci -q -d"$delim" get "$uciSection.$1" 2>/dev/null >$tFile
|
||||
if [ $? = 0 ] ; then
|
||||
sed -e s/^\'// -e s/\'$// <$tFile
|
||||
else
|
||||
while [ -n "$2" ]; do echo $2; shift; done
|
||||
fi
|
||||
rm -f $tFile
|
||||
}
|
||||
|
||||
# Common config variables - edit these in /etc/config/beardropper
|
||||
# or they can be overridden at runtime with command line options
|
||||
#
|
||||
uciLoadVar defaultMode entire
|
||||
uciLoadVar enabled 0
|
||||
uciLoadVar attemptCount 10
|
||||
uciLoadVar attemptPeriod 12h
|
||||
uciLoadVar banLength 1w
|
||||
uciLoadVar logLevel 1
|
||||
uciLoadVar logFacility authpriv.notice
|
||||
uciLoadVar persistentStateWritePeriod -1
|
||||
uciLoadVar fileStateType bddb
|
||||
uciLoadVar fileStateTempPrefix /tmp/beardropper
|
||||
uciLoadVar fileStatePersistPrefix /etc/beardropper
|
||||
firewallHookChains="`uciLoad -d \ firewallHookChain input_wan_rule:1 forwarding_wan_rule:1`"
|
||||
uciLoadVar firewallTarget DROP
|
||||
|
||||
# Not commonly changed, but changeable via uci or cmdline (primarily
|
||||
# to enable multiple parallel runs with different parameters)
|
||||
uciLoadVar firewallChain beardropper
|
||||
|
||||
# Advanced variables, changeable via uci only (no cmdline), it is
|
||||
# unlikely that these will need to be changed, but just in case...
|
||||
#
|
||||
uciLoadVar syslogTag "beardropper[$$]"
|
||||
# how often to attempt to expire bans when in follow mode
|
||||
uciLoadVar followModeCheckInterval 30m
|
||||
uciLoadVar cmdLogread 'logread' # for tuning, ex: "logread -l250"
|
||||
uciLoadVar cmdLogreadEba 'logread' # for "Exit before auth:" backscanning
|
||||
uciLoadVar formatLogDate '%b %e %H:%M:%S %Y' # used to convert syslog dates
|
||||
uciLoadVar formatTodayLogDateRegex '^%a %b %e ..:..:.. %Y' # filter for today mode
|
||||
|
||||
# Begin functions
|
||||
#
|
||||
# Clear bddb entries from environment
|
||||
bddbClear () {
|
||||
local bddbVar
|
||||
for bddbVar in `set | egrep '^bddb_[0-9_]*=' | cut -f1 -d= | xargs echo -n` ; do eval unset $bddbVar ; done
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Returns count of unique IP entries in environment
|
||||
bddbCount () { set | egrep '^bddb_[0-9_]*=' | wc -l ; }
|
||||
|
||||
# Loads existing bddb file into environment
|
||||
# Arg: $1 = file, $2 = type (bddb/bddbz), $3 =
|
||||
bddbLoad () {
|
||||
local loadFile="$1.$2" fileType="$2"
|
||||
if [ "$fileType" = bddb -a -f "$loadFile" ] ; then
|
||||
. "$loadFile"
|
||||
elif [ "$fileType" = bddbz -a -f "$loadFile" ] ; then
|
||||
local tmpFile="`mktemp`"
|
||||
zcat $loadFile > "$tmpFile"
|
||||
. "$tmpFile"
|
||||
rm -f "$tmpFile"
|
||||
fi
|
||||
bddbStateChange=0
|
||||
}
|
||||
|
||||
# Saves environment bddb entries to file, Arg: $1 = file to save in
|
||||
bddbSave () {
|
||||
local saveFile="$1.$2" fileType="$2"
|
||||
if [ "$fileType" = bddb ] ; then
|
||||
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g > "$saveFile"
|
||||
elif [ "$fileType" = bddbz ] ; then
|
||||
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g | gzip -c > "$saveFile"
|
||||
fi
|
||||
bddbStateChange=0
|
||||
}
|
||||
|
||||
# Set bddb record status=1, update ban time flag with newest
|
||||
# Args: $1=IP Address $2=timeFlag
|
||||
bddbEnableStatus () {
|
||||
local record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
|
||||
local newestTime=`bddbGetTimes $1 | sed 's/.* //' | xargs echo $2 | tr \ '\n' | sort -n | tail -1 `
|
||||
eval $record="1,$newestTime"
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Args: $1=IP Address
|
||||
bddbGetStatus () {
|
||||
bddbGetRecord $1 | cut -d, -f1
|
||||
}
|
||||
|
||||
# Args: $1=IP Address
|
||||
bddbGetTimes () {
|
||||
bddbGetRecord $1 | cut -d, -f2-
|
||||
}
|
||||
|
||||
# Args: $1 = IP address, $2 [$3 ...] = timestamp (seconds since epoch)
|
||||
bddbAddRecord () {
|
||||
local ip="`echo "$1" | tr . _`" ; shift
|
||||
local newEpochList="$@" status="`eval echo \\\$bddb_$ip | cut -f1 -d,`"
|
||||
local oldEpochList="`eval echo \\\$bddb_$ip | cut -f2- -d, | tr , \ `"
|
||||
local epochList=`echo $oldEpochList $newEpochList | xargs -n 1 echo | sort -un | xargs echo -n | tr \ ,`
|
||||
[ -z "$status" ] && status=0
|
||||
eval "bddb_$ip"\=\"$status,$epochList\"
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Args: $1 = IP address
|
||||
bddbRemoveRecord () {
|
||||
local ip="`echo "$1" | tr . _`"
|
||||
eval unset bddb_$ip
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Returns all IPs (not CIDR) present in records
|
||||
bddbGetAllIPs () {
|
||||
local ipRaw record
|
||||
set | egrep '^bddb_[0-9_]*=' | tr \' \ | while read record ; do
|
||||
ipRaw=`echo $record | cut -f1 -d= | sed 's/^bddb_//'`
|
||||
if [ `echo $ipRaw | tr _ \ | wc -w` -eq 4 ] ; then
|
||||
echo $ipRaw | tr _ .
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# retrieve single IP record, Args: $1=IP
|
||||
bddbGetRecord () {
|
||||
local record
|
||||
record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
|
||||
eval echo \$$record
|
||||
}
|
||||
|
||||
isValidBindTime () { echo "$1" | egrep -q '^[0-9]+$|^([0-9]+[wdhms]?)+$' ; }
|
||||
|
||||
# expands Bind time syntax into seconds (ex: 3w6d23h59m59s), Arg: $1=time string
|
||||
expandBindTime () {
|
||||
isValidBindTime "$1" || { logLine 0 "Error: Invalid time specified ($1)" >&2 ; exit 254 ; }
|
||||
echo $((`echo "$1" | sed -e 's/w+*/*7d+/g' -e 's/d+*/*24h+/g' -e 's/h+*/*60m+/g' -e 's/m+*/*60+/g' \
|
||||
-e s/s//g -e s/+\$//`))
|
||||
}
|
||||
|
||||
# Args: $1 = loglevel, $2 = info to log
|
||||
logLine () {
|
||||
[ $1 -gt $logLevel ] && return
|
||||
shift
|
||||
if [ "$logFacility" = "stdout" ] ; then echo "$@"
|
||||
elif [ "$logFacility" = "stderr" ] ; then echo "$@" >&2
|
||||
else logger -t "$syslogTag" -p "$logFacility" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# extra validation, fails safe. Args: $1=log line
|
||||
getLogTime () {
|
||||
local logDateString=`echo "$1" | sed -n \
|
||||
's/^[A-Z][a-z]* \([A-Z][a-z]* *[0-9][0-9]* *[0-9][0-9]*:[0-9][0-9]:[0-9][0-9] [0-9][0-9]*\) .*$/\1/p'`
|
||||
date -d"$logDateString" -D"$formatLogDate" +%s || logLine 1 \
|
||||
"Error: logDateString($logDateString) malformed line ($1)"
|
||||
}
|
||||
|
||||
# extra validation, fails safe. Args: $1=log line
|
||||
getLogIP () {
|
||||
local logLine="$1"
|
||||
local ebaPID=`echo "$logLine" | sed -n 's/^.*authpriv.info \(dropbear\[[0-9]*\]:\) Exit before auth:.*/\1/p'`
|
||||
[ -n "$ebaPID" ] && logLine=`$cmdLogreadEba | fgrep "${ebaPID} Child connection from "`
|
||||
echo "$logLine" | sed -n 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'
|
||||
}
|
||||
|
||||
# Args: $1=IP
|
||||
unBanIP () {
|
||||
if iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
|
||||
logLine 1 "Removing ban rule for IP $ip from iptables"
|
||||
iptables -D $firewallChain -s $ip -j "$firewallTarget"
|
||||
else
|
||||
logLine 3 "unBanIP() Ban rule for $ip not present in iptables"
|
||||
fi
|
||||
}
|
||||
|
||||
# Args: $1=IP
|
||||
banIP () {
|
||||
local ip="$1" x chain position
|
||||
if ! iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
|
||||
logLine 1 "Creating iptables chain $firewallChain"
|
||||
iptables -N $firewallChain
|
||||
fi
|
||||
for x in $firewallHookChains ; do
|
||||
chain="${x%:*}" ; position="${x#*:}"
|
||||
if [ $position -ge 0 ] && ! iptables -C $chain -j $firewallChain 2>/dev/null ; then
|
||||
logLine 1 "Inserting hook into iptables chain $chain"
|
||||
if [ $position = 0 ] ; then
|
||||
iptables -A $chain -j $firewallChain
|
||||
else
|
||||
iptables -I $chain $position -j $firewallChain
|
||||
fi ; fi
|
||||
done
|
||||
if ! iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
|
||||
logLine 1 "Inserting ban rule for IP $ip into iptables chain $firewallChain"
|
||||
iptables -A $firewallChain -s $ip -j "$firewallTarget"
|
||||
else
|
||||
logLine 3 "banIP() rule for $ip already present in iptables chain"
|
||||
fi
|
||||
}
|
||||
|
||||
wipeFirewall () {
|
||||
local x chain position
|
||||
for x in $firewallHookChains ; do
|
||||
chain="${x%:*}" ; position="${x#*:}"
|
||||
if [ $position -ge 0 ] ; then
|
||||
if iptables -C $chain -j $firewallChain 2>/dev/null ; then
|
||||
logLine 1 "Removing hook from iptables chain $chain"
|
||||
iptables -D $chain -j $firewallChain
|
||||
fi ; fi
|
||||
done
|
||||
if iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
|
||||
logLine 1 "Flushing and removing iptables chain $firewallChain"
|
||||
iptables -F $firewallChain 2>/dev/null
|
||||
iptables -X $firewallChain 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# review state file for expired records - we could add the bantime to
|
||||
# the rule via --comment but I can't think of a reason why that would
|
||||
# be necessary unless there is a bug in the expiration logic. The
|
||||
# state db should be more resiliant than the firewall in practice.
|
||||
#
|
||||
bddbCheckStatusAll () {
|
||||
local now=`date +%s`
|
||||
bddbGetAllIPs | while read ip ; do
|
||||
if [ `bddbGetStatus $ip` -eq 1 ] ; then
|
||||
logLine 3 "bddbCheckStatusAll($ip) testing banLength:$banLength + bddbGetTimes:`bddbGetTimes $ip` vs. now:$now"
|
||||
if [ $((banLength + `bddbGetTimes $ip`)) -lt $now ] ; then
|
||||
logLine 1 "Ban expired for $ip, removing from iptables"
|
||||
unBanIP $ip
|
||||
bddbRemoveRecord $ip
|
||||
else
|
||||
logLine 3 "bddbCheckStatusAll($ip) not expired yet"
|
||||
banIP $ip
|
||||
fi
|
||||
elif [ `bddbGetStatus $ip` -eq 0 ] ; then
|
||||
local times=`bddbGetTimes $ip | tr , \ `
|
||||
local timeCount=`echo $times | wc -w`
|
||||
local lastTime=`echo $times | cut -d\ -f$timeCount`
|
||||
if [ $((lastTime + attemptPeriod)) -lt $now ] ; then
|
||||
bddbRemoveRecord $ip
|
||||
fi ; fi
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
}
|
||||
|
||||
# Only used when status is already 0 and possibly going to 1, Args: $1=IP
|
||||
bddbEvaluateRecord () {
|
||||
local ip=$1 firstTime lastTime
|
||||
local times=`bddbGetRecord $1 | cut -d, -f2- | tr , \ `
|
||||
local timeCount=`echo $times | wc -w`
|
||||
local didBan=0
|
||||
|
||||
# 1: not enough attempts => do nothing and exit
|
||||
# 2: attempts exceed threshold in time period => ban
|
||||
# 3: attempts exceed threshold but time period is too long => trim oldest time, recalculate
|
||||
while [ $timeCount -ge $attemptCount ] ; do
|
||||
firstTime=`echo $times | cut -d\ -f1`
|
||||
lastTime=`echo $times | cut -d\ -f$timeCount`
|
||||
timeDiff=$((lastTime - firstTime))
|
||||
logLine 3 "bddbEvaluateRecord($ip) count=$timeCount timeDiff=$timeDiff/$attemptPeriod"
|
||||
if [ $timeDiff -le $attemptPeriod ] ; then
|
||||
bddbEnableStatus $ip $lastTime
|
||||
logLine 2 "bddbEvaluateRecord($ip) exceeded ban threshold, adding to iptables"
|
||||
banIP $ip
|
||||
didBan=1
|
||||
fi
|
||||
times=`echo $times | cut -d\ -f2-`
|
||||
timeCount=`echo $times | wc -w`
|
||||
done
|
||||
[ $didBan = 0 ] && logLine 2 "bddbEvaluateRecord($ip) does not exceed threshhold, skipping"
|
||||
}
|
||||
|
||||
# Reads filtered log line and evaluates for action Args: $1=log line
|
||||
processLogLine () {
|
||||
local time=`getLogTime "$1"`
|
||||
local ip=`getLogIP "$1"`
|
||||
local status="`bddbGetStatus $ip`"
|
||||
|
||||
if [ "$status" = -1 ] ; then
|
||||
logLine 2 "processLogLine($ip,$time) IP is whitelisted"
|
||||
elif [ "$status" = 1 ] ; then
|
||||
if [ "`bddbGetTimes $ip`" -ge $time ] ; then
|
||||
logLine 2 "processLogLine($ip,$time) already banned, ban timestamp already equal or newer"
|
||||
else
|
||||
logLine 2 "processLogLine($ip,$time) already banned, updating ban timestamp"
|
||||
bddbEnableStatus $ip $time
|
||||
fi
|
||||
banIP $ip
|
||||
elif [ -n "$ip" -a -n "$time" ] ; then
|
||||
bddbAddRecord $ip $time
|
||||
logLine 2 "processLogLine($ip,$time) Added record, comparing"
|
||||
bddbEvaluateRecord $ip
|
||||
else
|
||||
logLine 1 "processLogLine($ip,$time) malformed line ($1)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Args, $1=-f to force a persistent write (unless lastPersistentStateWrite=-1)
|
||||
saveState () {
|
||||
local forcePersistent=0
|
||||
[ "$1" = "-f" ] && forcePersistent=1
|
||||
|
||||
if [ $bddbStateChange -gt 0 ] ; then
|
||||
logLine 3 "saveState() saving to temp state file"
|
||||
bddbSave "$fileStateTempPrefix" "$fileStateType"
|
||||
logLine 3 "saveState() now=`date +%s` lPSW=$lastPersistentStateWrite pSWP=$persistentStateWritePeriod fP=$forcePersistent"
|
||||
fi
|
||||
if [ $persistentStateWritePeriod -gt 1 ] || [ $persistentStateWritePeriod -eq 0 -a $forcePersistent -eq 1 ] ; then
|
||||
if [ $((`date +%s` - lastPersistentStateWrite)) -ge $persistentStateWritePeriod ] || [ $forcePersistent -eq 1 ] ; then
|
||||
if [ ! -f "$fileStatePersist" ] || ! cmp -s "$fileStateTemp" "$fileStatePersist" ; then
|
||||
logLine 2 "saveState() writing to persistent state file"
|
||||
bddbSave "$fileStatePersistPrefix" "$fileStateType"
|
||||
lastPersistentStateWrite="`date +%s`"
|
||||
fi ; fi ; fi
|
||||
}
|
||||
|
||||
loadState () {
|
||||
bddbClear
|
||||
bddbLoad "$fileStatePersistPrefix" "$fileStateType"
|
||||
bddbLoad "$fileStateTempPrefix" "$fileStateType"
|
||||
logLine 2 "loadState() loaded `bddbCount` entries"
|
||||
}
|
||||
|
||||
printUsage () {
|
||||
cat <<-_EOF_
|
||||
Usage: beardropper [-m mode] [-a #] [-b #] [-c ...] [-C ...] [-f ...] [-l #] [-j ...] [-p #] [-P #] [-s ...]
|
||||
|
||||
Running Modes (-m) (def: $defaultMode)
|
||||
follow constantly monitors log
|
||||
entire processes entire log contents
|
||||
today processes log entries from same day only
|
||||
# interval mode, specify time string or seconds
|
||||
wipe wipe state files, unhook and remove firewall chain
|
||||
|
||||
Options
|
||||
-a # attempt count before banning (def: $attemptCount)
|
||||
-b # ban length once attempts hit threshold (def: $banLength)
|
||||
-c ... firewall chain to record bans (def: $firewallChain)
|
||||
-C ... firewall chains/positions to hook into (def: $firewallHookChains)
|
||||
-f ... log facility (syslog facility or stdout/stderr) (def: $logFacility)
|
||||
-j ... firewall target (def: $firewallTarget)
|
||||
-l # log level - 0=off, 1=standard, 2=verbose (def: $logLevel)
|
||||
-p # attempt period which attempt counts must happen in (def: $attemptPeriod)
|
||||
-P # persistent state file write period (def: $persistentStateWritePeriod)
|
||||
-s ... persistent state file prefix (def: $fileStatePersistPrefix)
|
||||
-t ... temporary state file prefix (def: $fileStateTempPrefix)
|
||||
|
||||
All time strings can be specified in seconds, or using BIND style
|
||||
time strings, ex: 1w2d3h5m30s is 1 week, 2 days, 3 hours, etc...
|
||||
|
||||
_EOF_
|
||||
}
|
||||
|
||||
# Begin main logic
|
||||
#
|
||||
unset logMode
|
||||
while getopts a:b:c:C:f:hj:l:m:p:P:s:t: arg ; do
|
||||
case "$arg" in
|
||||
a) attemptCount="$OPTARG" ;;
|
||||
b) banLength="$OPTARG" ;;
|
||||
c) firewallChain="$OPTARG" ;;
|
||||
C) firewallHookChains="$OPTARG" ;;
|
||||
f) logFacility="$OPTARG" ;;
|
||||
j) firewallTarget="$OPTARG" ;;
|
||||
l) logLevel="$OPTARG" ;;
|
||||
m) logMode="$OPTARG" ;;
|
||||
p) attemptPeriod="$OPTARG" ;;
|
||||
P) persistentStateWritePeriod="$OPTARG" ;;
|
||||
s) fileStatePersistPrefix="$OPTARG" ;;
|
||||
s) fileStatePersistPrefix="$OPTARG" ;;
|
||||
*) printUsage
|
||||
exit 254
|
||||
esac
|
||||
shift `expr $OPTIND - 1`
|
||||
done
|
||||
[ -z $logMode ] && logMode="$defaultMode"
|
||||
|
||||
fileStateTemp="$fileStateTempPrefix.$fileStateType"
|
||||
fileStatePersist="$fileStatePersistPrefix.$fileStateType"
|
||||
|
||||
attemptPeriod=`expandBindTime $attemptPeriod`
|
||||
banLength=`expandBindTime $banLength`
|
||||
[ $persistentStateWritePeriod != -1 ] && persistentStateWritePeriod=`expandBindTime $persistentStateWritePeriod`
|
||||
followModeCheckInterval=`expandBindTime $followModeCheckInterval`
|
||||
exitStatus=0
|
||||
|
||||
# Here we convert the logRegex list into a sed -f file
|
||||
fileRegex="/tmp/beardropper.$$.regex"
|
||||
uciLoad logRegex 's/[`$"'\\\'']//g' '/has invalid shell, rejected$/d' \
|
||||
'/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p' \
|
||||
'/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p' > "$fileRegex"
|
||||
lastPersistentStateWrite="`date +%s`"
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
|
||||
# main event loops
|
||||
|
||||
if [ "$logMode" = follow ] ; then
|
||||
logLine 1 "Running in follow mode"
|
||||
readsSinceSave=0 lastCheckAll=0 worstCaseReads=1 tmpFile="/tmp/beardropper.$$.1"
|
||||
# Verify if these do any good - try saving to a temp. Scope may make saveState useless.
|
||||
trap "rm -f "$tmpFile" "$fileRegex" ; exit " SIGINT
|
||||
[ $persistentStateWritePeriod -gt 1 ] && worstCaseReads=$((persistentStateWritePeriod / followModeCheckInterval))
|
||||
firstRun=1
|
||||
$cmdLogread -f | while read -t $followModeCheckInterval line || true ; do
|
||||
if [ $firstRun -eq 1 ] ; then
|
||||
trap "saveState -f" SIGHUP
|
||||
trap "saveState -f; exit" SIGINT
|
||||
firstRun=0
|
||||
fi
|
||||
sed -nEf "$fileRegex" > "$tmpFile" <<-_EOF_
|
||||
$line
|
||||
_EOF_
|
||||
line="`cat $tmpFile`"
|
||||
[ -n "$line" ] && processLogLine "$line"
|
||||
logLine 3 "ReadComp:$readsSinceSave/$worstCaseReads"
|
||||
if [ $((++readsSinceSave)) -ge $worstCaseReads ] ; then
|
||||
now="`date +%s`"
|
||||
if [ $((now - lastCheckAll)) -ge $followModeCheckInterval ] ; then
|
||||
bddbCheckStatusAll
|
||||
lastCheckAll="$now"
|
||||
saveState
|
||||
readsSinceSave=0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
elif [ "$logMode" = entire ] ; then
|
||||
logLine 1 "Running in entire mode"
|
||||
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
|
||||
processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif [ "$logMode" = today ] ; then
|
||||
logLine 1 "Running in today mode"
|
||||
# merge the egrep into sed with -e /^$formatTodayLogDateRegex/!d
|
||||
$cmdLogread | egrep "`date +\'$formatTodayLogDateRegex\'`" | sed -nEf "$fileRegex" | while read line ; do
|
||||
processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif isValidBindTime "$logMode" ; then
|
||||
logInterval=`expandBindTime $logMode`
|
||||
logLine 1 "Running in interval mode (reviewing $logInterval seconds of log entries)..."
|
||||
timeStart=$((`date +%s` - logInterval))
|
||||
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
|
||||
timeWhen=`getLogTime "$line"`
|
||||
[ $timeWhen -ge $timeStart ] && processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif [ "$logMode" = wipe ] ; then
|
||||
logLine 2 "Wiping state files, unhooking and removing iptables chains"
|
||||
wipeFirewall
|
||||
if [ -f "$fileStateTemp" ] ; then
|
||||
logLine 1 "Removing non-persistent statefile ($fileStateTemp)"
|
||||
rm -f "$fileStateTemp"
|
||||
fi
|
||||
if [ -f "$fileStatePersist" ] ; then
|
||||
logLine 1 "Removing persistent statefile ($fileStatePersist)"
|
||||
rm -f "$fileStatePersist"
|
||||
fi
|
||||
else
|
||||
logLine 0 "Error: invalid log mode ($logMode)"
|
||||
exitStatus=254
|
||||
fi
|
||||
|
||||
rm -f "$fileRegex"
|
||||
exit $exitStatus
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-beardropper": {
|
||||
"description": "Grant UCI access for luci-app-beardropper",
|
||||
"read": {
|
||||
"uci": [ "beardropper" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "beardropper" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"config": "beardropper",
|
||||
"init": "beardropper"
|
||||
}
|
||||
Reference in new issue
Block a user