我想阻止IP地址从一个日志文件,IP是从access.log文件收集在apache2中。is被正确地收集在文件ips.log中,但是在读取文件以禁止收集的is时,块没有完成。
#!/bin/bash
# Store words to avoid an search for
BADWORDS=( '/etc/passwd' 'file?' 'w00tw00t' 'fckeditor' 'ifconfig' )
# Get number of elements in the backup_files array
entries=${#BADWORDS[@]}
for ((i=0; i<= entries-1; i++))
do
setBadWord=${BADWORDS[$i]}
tail -F /var/log/apache2/access.log | grep --line-buffered "$setBadWord" | while read -r a; do echo "$a" | awk '{ print $1 } ' >> ips.log; done
done # end for
while IFS= read -r ip; do
iptables -A INPUT -s "$ip" -j DROP
done < ips.log发布于 2020-03-28 22:49:22
您的代码有许多问题:
它为所选的每一行运行一个新的awk副本(根本不需要awk);
tail -F,第一个循环的每个元素都没有完成),因此iptables循环从来不启动
H 112 iptables命令附加一个新规则,即使在H 214<>H 115>之前看到了它,编写i<entries比i<=entries-1更简单,而且使用for setBadword in "${BADWORDS[@]}"; do ...更简单。
如果您真的想永久循环读取日志文件,则可以使用GNU实用程序执行如下操作:
#!/bin/sh
log=/var/log/apache2/access.log
words=/my/list/of/badwords/one/per/line
banned=/my/list/of/already/banned/ips
tail -F "$log" |\
grep --line-buffered -Ff "$words" |\
while read ip junk; do
grep -qxF $ip "$banned" || (
iptables -A INPUT -s $ip -j DROP
echo $ip >> "$banned"
)
done
# we never get here because "tail -F" never finishes要只处理日志文件一次,然后完成,您可以直接从"$log"中输入"$log":
grep --line-buffered -Ff "$words" "$log" | ...但是,仅仅使用明确针对这类任务设计的fail2ban可能就不那么容易出错了。
https://stackoverflow.com/questions/60905172
复制相似问题