实时监控,IP无法封禁

Realtime monitoring, IP cannot be blocked

我想从日志文件中屏蔽 IP 地址,IP 是从 apache2 中的 access.log 文件中收集的。 IP 已正确收集在文件 ips.log 中,但在读取文件以禁止收集的 IP 时,阻止未完成。

 #!/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  } ' >> ips.log; done

 done # end for


while IFS= read -r ip; do
iptables -A INPUT -s "$ip" -j DROP
done < ips.log

您的代码有很多问题:

  • 它 运行 为所选的每一行创建一个 awk 的新副本(根本不需要 awk);
  • 它尝试运行第一个循环多次("$BADWORDS"的每个元素一次)
  • 第一个循环永远不会结束(因为 tail -F)所以 iptables 循环永远不会开始
  • iptables 命令附加一条新规则,即使该 IP 之前已被看到
  • 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" 提供 grep

grep --line-buffered -Ff "$words" "$log" | ...

但仅使用专为此类任务设计的 fail2ban 可能不太容易出错。