├── DenyPwdHack.sh └── README.md /DenyPwdHack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | 3 | ## OpenWRT 版本判断 4 | Vfile=/etc/banner 5 | OWTV=`awk 'BEGIN{IGNORECASE=1}/openwrt/ {split($2,v,"."); print v[1]}' $Vfile` 6 | [[ $OWTV -lt 18 ]] && echo "OpenWRT version must be >= 18" && exit 1 7 | 8 | ## 黑名单所在iptables链表 9 | ChainName=DenyPwdHack 10 | 11 | ## 日志路径 12 | LOG_DEST=/tmp/DenyPwdHack.log 13 | 14 | ## 检测到攻击时需要针对攻击IP封禁的端口,可以将ssh/luci/ftp等端口加上 15 | Deny_Port="22,443" 16 | INPUT_RULE="INPUT -p tcp -m multiport --dports $Deny_Port -j $ChainName" 17 | 18 | ## 日志关键字,每个关键字可以用"|"号隔开,支持grep的正则表达式 19 | ## 注: SSH 攻击可以大量出现四种关键字:Invalid user/Failed password for/Received disconnect from/Disconnected from authenticating 20 | ## Luci 攻击可以出现"luci: failed login on / for root from xx.xx.xx.xx" 21 | LOG_KEY_WORD="auth\.info\s+sshd.*Failed password for|luci:\s+failed\s+login|auth\.info.*sshd.*Connection closed by.*port.*preauth" 22 | 23 | ## 白名单IP可以用"|"号隔开,支持grep的正则表达式 24 | exclude_ip="192.168.|127.0.0.1" 25 | 26 | ## 失败次数 27 | Failed_times=5 28 | 29 | ## 黑名单过期时间,单位小时,3个月2160小时 30 | BlackList_exp=2160 31 | 32 | ## 日志时间 33 | LOG_DT=`date "+%Y-%m-%d %H:%M:%S"` 34 | 35 | ## 判断链是否存在 36 | iptables -n --list $ChainName > /dev/null 2>&1 37 | if [[ $? -ne 0 ]] ; then 38 | iptables -N $ChainName 39 | echo "[$LOG_DT] iptables -N $ChainName" >> $LOG_DEST 40 | fi 41 | 42 | ## 判断INPUT跳到链的规则是否存在 43 | iptables -C $INPUT_RULE > /dev/null 2>&1 44 | if [[ $? -ne 0 ]] ; then 45 | iptables -I $INPUT_RULE 46 | echo "[$LOG_DT] iptables -I $INPUT_RULE" >> $LOG_DEST 47 | fi 48 | 49 | DenyIPLIst=`logread \ 50 | | awk '/'"$LOG_KEY_WORD"'/ {for(i=1;i<=NF;i++) \ 51 | if($i~/^(([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/) \ 52 | print $i}' \ 53 | | grep -v "${exclude_ip}" \ 54 | | sort | uniq -c \ 55 | | awk '{if($1>'"$Failed_times"') print $2}'` 56 | IPList_sum=`echo "${DenyIPLIst}" | wc -l` 57 | if [[ $IPList_sum -ne 0 ]];then 58 | for i in ${DenyIPLIst} 59 | do 60 | iptables -vnL $ChainName | grep -q $i 61 | [[ $? -ne 0 ]] && iptables -A $ChainName -s $i -m comment --comment "Added at $LOG_DT by DenyPwdHack" -j DROP \ 62 | && echo "[$LOG_DT] iptables -A $ChainName -s $i -j DROP" >> $LOG_DEST 63 | done 64 | fi 65 | 66 | ## 黑名单过期删除 67 | ChainList=`iptables --line-numbers -nL $ChainName |\ 68 | awk '/Added at/ {for(i=1;i<=NF;i++) if($i~/[0-9]{4}(-[0-9]{2}){2}/) print $1","$i" "$(i+1)}' |\ 69 | sort -rn` 70 | 71 | ## 链表必须从后端删除,如果从前端删除,后端的实际rulenum会变 72 | ChainList_num=`echo "${ChainList}" | grep -v "^$" | wc -l` 73 | if [[ ${#ChainList} -ne 0 ]] && [[ $ChainList_num -gt 0 ]] ; then 74 | for tl in `seq 1 $ChainList_num` 75 | do 76 | Dtime=`echo "${ChainList}" | sed -n ''"$tl"'p' | awk -F, '{print $2}'` 77 | Stime=`date -d "$Dtime" +%s` 78 | Ntime=`date +%s` 79 | if [[ $(($Ntime - $Stime)) -ge $(($BlackList_exp * 3600)) ]] ; then 80 | RuleNum=`echo "${ChainList}" | sed -n ''"$tl"'p' | awk -F, '{print $1}'` 81 | iptables -D $ChainName $RuleNum 82 | if [[ $? -eq 0 ]] ; then 83 | echo "[$LOG_DT] iptables -D $ChainName $RuleNum" >> $LOG_DEST 84 | else 85 | echo "[$LOG_DT] execute delete failed: iptables -D $ChainName $RuleNum" >> $LOG_DEST 86 | fi 87 | fi 88 | done 89 | fi 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## deny-ssh-password-attack 2 | 3 | Openwrt 自身没有对抗ssh破解的工具,为了使我们暴露在互联网的路由器更加安全,基于iptables编写了一个小脚本, 脚本通过crontab定时执行. 4 | 5 | Openwrt does not have its own tools to combat SSH cracking. To make our Internet-exposed routers more secure, a small script based on iptables is written. The script is executed by crontab timing. 6 | 7 | 脚本的功能是读取 logread 中的失败日志,对于失败次数超过5次的同一个IP,在Iptables 中增加一条封锁规则,并记录日志到 /tmp/DenyPwdHack.log 8 | 9 | 操作步骤如下: 10 | 11 | 下载文件DenyPwdHack.sh , 以root登录,放在 /root/ 目录下, 然后执行 chmod u+x /root/DenyPwdHack.sh 在Openwrt增加以下 crontab 内容: 12 | 13 | 执行命令: crontab -e 14 | 15 | 然后贴入以下内容: 16 | ``` 17 | 每3 小时执行一次脚本例子: 0 */3 * * * /root/DenyPwdHack.sh 18 | 每15分钟执行一次脚本例子: */15 * * * * /root/DenyPwdHack.sh 19 | ``` 20 | 21 | 脚本中的参数: 22 | 23 | #检测到ssh或者luci攻击后封禁的端口 24 | Deny_Port=22,443 25 | 26 | #日志的绝对路径,因为 /tmp文件系统从内存中开辟的,写到该文件系统速度快,对芯片也安全 27 | LOG_DEST=/tmp/DenyPwdHack.log 28 | 29 | #白名单IP可以用"|"号隔开,支持grep的正则表达式 30 | exclude_ip="192.168.|127.0.0.1" 31 | 32 | #登录失败多少次后封锁IP 33 | Failed_times=10 34 | 35 | #黑名单过期时间,单位小时,3个月2160小时 36 | BlackList_exp=2160 37 | --------------------------------------------------------------------------------