while tail grep for string 如果为真,则为 ip 发出 iptables 命令?

While tail grep for string and if true, issue iptables command for the ip?

尝试追踪一个日志文件(iptraf 日志)并 grep 一个字符串以自动禁止访问 telnet 端口的人。

日志永远滚动(意味着它不断被写入),我需要不断地从中读取 iptraf 添加的每一行。

更新-1:

它获得了 ip 但现在我需要使用它,但是如果我用 var= 替换 echo 它不会触发 bash 命令

#!/bin/bash
tail -f /iptraf/ip.log | 
while read LINE
    do
       echo "${LINE}" | grep -o '[0-9]\{0,3\}\.[0-9]\{0,3\}\.[0-9]\{0,3\}\.[0-9]\{0,3\}:[0-9]\{0,6\}\ to localhost:telnet' | cut -d':' -f1
done

这会通过将返回的 grep 与分号分开并获取作为违规者 ip 的第一部分来打印第一个 ip。

似乎不​​能将回显部分放入变量中? 我还需要能够确定它是否是数组 ["x.x.x.x","x.x.x.x"] 中的 IP,而不是禁止这些 IP。

更新 2:

#!/bin/bash

#Rolling log file
tail -f /iptraf/iplog.log | 

while read LINE
    do
        #get the ip of the offender x.x.x.x <----
        #Example of output
        #Sun Apr 21 09:54:41 2019; TCP; eth0; 52 bytes; from x.x.x.x:53923 to localhost:telnet; first packet (SYN)
        #Regex/cut output ends up with this: x.x.x.x

        ip=${
            "${LINE}" | sed -n 's/^.* from \(.*\) to localhost:telnet;.*//p' | cut -d':' -f1
        };

        #bad substitution error?

        if [[$ip !== 'localhost']] then
            #ban offender and log to console
            iptables -I INPUT -s $ip -j DROP && route add -host $ip reject
            echo "Offender Banned: $ip";
        fi
done

对于这个,控制台向我抛出一条刻薄的消息 "BAD SUBSTITUTION"

我知道这是在重新发明轮子,但我需要它来为其他日志创建我自己的脚本。我每天还要和大量的黑客打交道,所以不能自动完成这件事真是令人气愤。

iptraf 输出示例

Sun Apr 21 01:50:44 2019; TCP; eth0; 52 bytes; from x.x.x.x:52364 to x.x.x.x:telnet; first packet (SYN)

PS,x.x.x.x是实际的IP,比如111.111.111.111,刚刚标出来。

更新 3:

#!/bin/bash

tail -f /var/log/iptraf/ip_traffic-1.log |
awk -v skipIps="192.168.1.1,127.0.0.1" '
    BEGIN {
        split(skipIps,tmp,/,/)
        for (i in tmp) {
            skipSet[tmp[i]]
        }
    }
    /to localhost:telnet/ {
        ip = 
        sub(/:.*/,"",ip)
        if ( !(ip in skipSet) ) {
            printf "BANNING TELNET: %s\n", ip | "cat>&2"
            print "[External] EXTERNAL HIT TELNET [Telnet Server Connection]:", ip
            fflush()
            system("iptables -I INPUT -s "ip" -j DROP && route add -host "ip" reject")
        } else {
            printf "That was US! TELNET: %s\n", ip | "cat>&2"
            print "[Allowed] INTERNAL HIT TELNET [Telnet Server Connection]:", ip
            fflush()
        }
    }
'

既然我们可以禁止访问端口的 ip,那么最好每月清除 iptables 日志以防止它减慢服务器速度,对吗? - 我可以稍后自己做,我现在感兴趣的是它声明端口的部分 "localhost:telnet" - 我真的需要能够根据已知端口名称列表检查多个端口名称像 "telnet"、"ircd"、"ssh"、"ftp"、"sip-tls" 等

如果有人能帮助我解决此 post 的 update-3 中的多个端口名称,那就太好了。

由于您需要(有点)复杂的模式匹配,您可以直接将 tail 结果通过管道传输到 awk,如下所示:

# First pipe the tail output to awk
tail -f /logs/iptraf.log | awk '/to localhost:telnet/{
# The /pattern/ looks for a pattern
# We reach this stage only if the patten match is successful.
ip=gensub(/^.*from[[:blank:]]+([^[:blank:]]+).*$/,"\1","g")
# Above lines searches a record([=10=]) for the IP that we wish to block
# and assign it to an awk variable 'ip'
system("iptables -I INPUT -s " ip " -j DROP") 
# Above line executes a bash command using the system awk command
}'

测试

iptables -L # To see the modified rules.

注意:您应该有一个 GNU awk 来执行上述操作。另外,查看 here 以了解有关 awk 字符串函数的更多信息。

我稍微修改了你的代码:

tail -f /logs/iptraf.log | grep "to localhost:telnet"  |
while 
   read OFFENDING_IP EXTRA
do 
  echo "uhoh! - $OFFENDING_IP hit telnet port.. We need to ban the ip"
  iptables -I INPUT -s $OFFENDING_IP -j DROP
done

代码未经测试。我只是假设 IP 首先出现在 "to localhost:telnet".

之前的行中

至于解释,你的代码是有道理的。但是,您不知道如何从 grep 的行中提取 IP。读取命令将获取 grep 命令的输出,因为我更改了你的;一个 |将 grep 的输出提供给下一个命令。此外,读取命令会将行解析为字段并将值填充到命令行上的变量中。第一个字段(大概是 IP)放在 OFFENDING_IP 字段中,该行的其余部分填充到 EXTRA 变量中。

tail -f /logs/iptraf.log |
awk -v skipIps="a.b.c.d,w.x.y.z" '
    BEGIN {
        split(skipIps,tmp,/,/)
        for (i in tmp) {
            skipSet[tmp[i]]
        }
    }
    /to localhost:telnet/ {
        ip = 
        sub(/:.*/,"",ip)
        if ( !(ip in skipSet) ) {
            printf "uhoh! - this ip %s hit telnet port.. We need to ban the ip\n", ip | "cat>&2"
            print ip
            fflush()
        }
    }
' | xargs -I {} iptables -I INPUT -s '{}' -j DROP

查看(使用 cat file 代替 tail -f ... 并在 iptables 之前添加 echo 以演示脚本的其余部分工作):

$ cat file
Sun Apr 21 01:50:44 2019; TCP; eth0; 52 bytes; from x.x.x.x:52364 to localhost:telnet; first packet (SYN)

cat file |
awk '/to localhost:telnet/ {
    ip = 
    sub(/:.*/,"",ip)
    printf "uhoh! - this ip %s hit telnet port.. We need to ban the ip\n", ip | "cat>&2"
    print ip
    fflush()
}' |
xargs -I {} echo iptables -I INPUT -s '{}' -j DROP
iptables -I INPUT -s x.x.x.x -j DROP
uhoh! - this ip x.x.x.x hit telnet port.. We need to ban the ip