我正在编写一个bash脚本,如果IP地址有100个或更多无效密码(暴力攻击)尝试,则每5分钟检查一次。
以下脚本有效:
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
我的剧本出了什么问题?
答案 0 :(得分:2)
你基本上做的是:
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
要匹配文字字符串而不是文件,请在stdin上发送字符串:
if grep -q "$line" <<< "$currentIPs"
虽然你最好使用全局匹配:
if [[ "$currentIPs" = *"$line"* ]]
请注意,如果您已禁止1.2.3.45
,1.2.3.4
将匹配,因此不会被禁止。您可以将上述方法与*" $line "*
一起使用,以确保它周围有空格,如果您输入的话。
还要考虑安装fail2ban,它会以健壮的方式自动执行此操作。
答案 1 :(得分:1)
您可以将if grep -q $line $currentIPs
更改为:
if echo "$currentIPs" |grep -q "$line"