我正在编写一个 bash 脚本,每 5 分钟检查一次 IP 地址是否有 100 次或更多无效密码(暴力攻击)尝试。
以下脚本有效:
blockIPs="$(cat /var/log/secure | grep "Failed password for" | grep -v "invalid" | awk {'print $11'} | sort | uniq -c | awk -v limit=100 '$1 > limit{print $2}')"
while read -r line; do
iptables -A INPUT -s $line -p tcp --dport 22 -j DROP
echo "Blocking IP address: $line"
done <<< "$blockIPs"
上述脚本的问题是,一个小时后,iptables
中出现了重复的条目。因此,我尝试扩展我的脚本,检查 IP 地址是否已被阻止,如果是,则应跳过它。
这是脚本:
blockIPs="$(cat /var/log/secure | grep "Failed password for" | grep -v "invalid" | awk {'print $11'} | sort | uniq -c | awk -v limit=100 '$1 > limit{print $2}')"
currentIPs="$(iptables-save)"
while read -r line; do
if grep -q $line $currentIPs
then
echo "IP address already blocked, skipping"
else
iptables -A INPUT -s $line -p tcp --dport 22 -j DROP
echo "Blocking IP address: $line"
fi
done <<< "$blockIPs"
但由于某些原因它不起作用,我得到了奇怪的输出:
grep: 2: No such file or directory
grep: 18:19:53: No such file or directory
grep: 2015: No such file or directory
Blocking IP address: 59.47.0.152
grep: #: No such file or directory
grep: Generated: No such file or directory
grep: by: No such file or directory
grep: iptables-save: No such file or directory
我的脚本有什么问题?
最佳答案
你基本上做的是:
grep -q test this is a string that contains the word test
希望匹配字符串中的单词。 Grep 认为每个单词都是一个文件,并给出像您所看到的输出:
grep: this: No such file or directory
grep: is: No such file or directory
grep: a: No such file or directory
grep: string: No such file or directory
要匹配文字字符串而不是文件,请在标准输入上发送字符串:
if grep -q "$line" <<< "$currentIPs"
虽然你最好使用全局匹配:
if [[ "$currentIPs" = *"$line"* ]]
请注意,如果您已禁止 1.2.3.45
,1.2.3.4
将匹配,因此不会被禁止。您可以将上述方法与 *"$line "*
一起使用,以确保其周围有空格(如果您的输入有空格)。
还可以考虑安装fail2ban,它会以可靠的方式自动执行此操作。
关于Bash 检查 grep 是否匹配字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30601655/