Search code examples
bashawkgreplogictail

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


Trying to tail a log file (iptraf log) and grep a string to automatically ban people who hit a telnet port.

The log is forever rolling (Meaning it's constantly being written to) and i need to read from it constantly for every line that's added by iptraf.

UPDATE-1:

It gets the ip but now i need to use it, but if i replace echo with var= it does not trigger the bash command

#!/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

This prints the first ip by splitting the returned grep with the semicolon and getting the first part which is the offenders ip.

Can't seem to put the echo part into a variable? I also need to be able to determine if it's an IP in an array ["x.x.x.x","x.x.x.x"] and not to ban those.

UPDATE-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;.*/\1/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

With this one, console throws me a mean message "BAD SUBSTITUTION"

I know this is reinventing the wheel and all, but i need this to create my own scripts for other logs. I'm also dealing with a ton of hackers every day so it's extremely infuriating not being able to do it automatically.

Example of iptraf output

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 are ACTUAL IP'S such as 111.111.111.111, just marked out.

UPDATE-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 = $11
        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()
        }
    }
'

Now that we can ban ip's that hit ports, It would be best so clear the logs iptables every month to prevent it from slowing down the server right? - I can do that later my self, What I'm currently interested in right now is the part where it states the port "localhost:telnet" - I really need to be able to check multiple port names against a list of known port names like "telnet","ircd","ssh","ftp","sip-tls" etc etc.

It would be great if anyone can assist me with the multiple port names in update-3 of this post.


Solution

  • 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 = $11
            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
    

    Look (using cat file in place of tail -f ... and adding an echo before iptables to demonstrate the rest of the script working):

    $ 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 = $11
        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