Last active
June 28, 2023 08:55
-
-
Save deadbok/77118bfd16a77125b195 to your computer and use it in GitHub Desktop.
OpenWRT ssh brute force drop (https://forum.openwrt.org/viewtopic.php?id=32685)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# dropBrute.sh by robzr | |
# | |
# minimalist OpenWRT/dropbear ssh brute force attack banning script | |
# | |
# Installation steps: | |
# | |
# 1) Optionally edit the variables in the header of this script to customise | |
# for your environment | |
# | |
# 2) Insert a reference for this rule in your firewall script before you | |
# accept ssh, something like: | |
# | |
# iptables -N logndrop | |
# iptables -N dropBrute | |
# iptables -A logndrop -j LOG | |
# iptables -A logndrop -j DROP | |
# iptables -A input_rule -p tcp --dport 22 -i eth1 -m state --state NEW -m recent --set | |
# iptables -A input_rule -p tcp --dport 22 -i eth1 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j logndrop | |
# iptables -A input_rule -p tcp --dport 22 -j dropBrute | |
# | |
# This will block the brute force attack until the IP is banned by the script | |
# | |
# 3) Run the script periodically out of cron: | |
# | |
# echo '*/10 * * * * /usr/sbin/dropBrute.sh 2>&1 >> /tmp/dropBrute.log' >> /etc/crontabs/root | |
# | |
# 4) If cron is not enabled, you'll also need to run the following: | |
# | |
# /etc/init.d/cron enable && /etc/init.d/cron start | |
# | |
# | |
# To whitelist hosts or networks, simply add a manual entry to the lease | |
# file with a leasetime of -1. This can be done with the following syntax: | |
# | |
# echo -1 192.168.1.0/24 >> /tmp/dropBrute.leases | |
# | |
# A static, or non-expiring blacklist of a host or network can also be | |
# added, just use a lease time of 0. This can be done with the following syntax: | |
# | |
# echo 0 1.2.3.0/24 >> /tmp/dropBrute.leases | |
# How many bad attempts before banning. Only the log entries from the | |
# current day are checked. | |
allowedAttempts=10 | |
# How long IPs are banned for | |
# default is 1 day | |
secondsToBan=$((1*60*60*24)) | |
# the "lease" file - defaults to /tmp which does not persist across reboots | |
leaseFile=/tmp/dropBrute.leases | |
# This is the iptables chain that drop commands will go into. | |
# you will need to put a reference in your firewall rules for this | |
iptChain=dropBrute | |
# the IP Tables drop rule | |
iptDropRule='-j DROP' | |
# the IP Tables whitelist rule | |
iptWhiteRule='-j RETURN' | |
# You can put default leasefile entries in the following space. | |
# Syntax is simply "leasetime _space_ IP_or_network". A leasetime of -1 is a | |
# whitelist entry, and a leastime of 0 is a permanent blacklist entry. | |
[ -f $leaseFile ] || cat <<__EOF__>>$leaseFile | |
-1 192.168.1.0/24 | |
__EOF__ | |
# End of user customizable variables (unless you know better :) ) | |
ipt='/usr/sbin/iptables' | |
[ `date +'%s'` -lt 1320000000 ] && echo System date not set, aborting. && exit -1 | |
$ipt -N $iptChain >&/dev/null | |
now=`date +'%s'` | |
nowPlus=$((now + secondsToBan)) | |
echo Running dropBrute on `date` \($now\) | |
# find new badIPs | |
for badIP in `logread | fgrep dropbear | egrep -i 'login attempt for nonexistent user'\|'bad password attempt for'| sed 's/^.*from //' | sed 's/:.*$//' | sort -u` ; do | |
found=`logread | fgrep dropbear | egrep -i 'login attempt for nonexistent user'\|'bad password attempt for'|sed 's/^.*from //'|sed 's/:.*$//' | fgrep $badIP | wc -l` | |
if [ $found -gt $allowedAttempts ] ; then | |
# if there is not a lease, add it | |
if [ $(egrep -c $badIP$ $leaseFile) -eq 0 ] ; then | |
echo $nowPlus $badIP >> $leaseFile | |
fi | |
fi | |
done | |
# now parse the leaseFile | |
cat $leaseFile | while read lease ; do | |
leaseTime=`echo $lease|cut -f1 -d\ ` | |
leaseIP=`echo $lease|cut -f2 -d\ ` | |
# when used with the iptables example on the top a return rule is not needed | |
if [ $leaseTime -lt 0 ] ; then | |
if [ `$ipt -S $leaseChain|egrep \ $leaseIP/32\ \|\ $leaseIP\ |fgrep -- "$iptWhiteRule"| wc -l` -lt 1 ] ; then | |
#echo Adding new whitelist rule for $leaseIP | |
#$ipt -I $iptChain -s $leaseIP $iptWhiteRule | |
true | |
fi | |
elif [ $leaseTime -ge 1 -a $now -gt $leaseTime ] ; then | |
echo Expiring lease for $leaseIP | |
$ipt -D $iptChain -s $leaseIP $iptDropRule | |
$ipt -D $iptChain -s $leaseIP -j LOG --log-prefix "dropBrute " | |
sed -i /$leaseIP/d $leaseFile | |
elif [ $leaseTime -ge 0 -a `$ipt -S $leaseChain|egrep \ $leaseIP/32\ \|\ $leaseIP\ |wc -l` -lt 1 ] ; then | |
echo Adding new rule for $leaseIP | |
$ipt -I $iptChain -s $leaseIP $iptDropRule | |
$ipt -I $iptChain -s $leaseIP -j LOG --log-prefix "dropBrute " | |
fi | |
done < $leaseFile |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment