Hrvoje
Hrvoje

Reputation: 13

Shell script command help to shorten?

I have a command that is like this:

/bin/netstat -an | /usr/bin/awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="0.0.0.0" && a[1]!="127.0.0.1" && a[1]!="111.222.111.222" ... 50 addresses... && a[1]!="211.112.211.112"){c[a[1]]++}} END{for(ip in c){if(c[ip]>max){print ip}}}' | while read ip; do /sbin/iptables -m comment --comment "SCAN BLOCK" -I INPUT 1 -s $ip -j DROP; done

How can I shorten it to read IP addresses from file, or from a array list above command, or something like that as I have now almost 100 IPs and all are one next to another in one big command line.

Basicaly, how to make command something like this:

/bin/netstat -an | /usr/bin/awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="read from file"){c[a[1]]++}} END{for(ip in c){if(c[ip]>max){print ip}}}' | while read ip; do /sbin/iptables -m comment --comment "SCAN BLOCK" -I INPUT 1 -s $ip -j DROP; done

Upvotes: 1

Views: 99

Answers (2)

RARE Kpop Manifesto
RARE Kpop Manifesto

Reputation: 2895

If you don't care about output order, why not just read in 1st iplist.txt into an array, as others have suggested, then just output whenever it's exactly 1 more than your vmax threshold, e.g. :

# imagine the <( echo ... ) is the iplist.txt being read in

jot -b '1.0.0.1' 105 | gcat -n | 

mawk 'FNR==NR ? __[$(_<_)] : $NF in __  && 
                         __[ $NF ]++==+_' \_='100' <( echo '1.0.0.1' ) -
101 1.0.0.1

ps : jot -w '%d 1.0.0.1' 105 works just as well for line 1, but it really doesn't matter what line 1 is since it represents whatever comes in via the pipe

Upvotes: 0

markp-fuso
markp-fuso

Reputation: 35256

Place the list of ips in a file, eg:

$ cat iplist.txt
0.0.0.0
127.0.0.1
111.222.111.222
... snip ...
211.112.211.112

The general approach is to have awk process 2 input files with different logic, eg:

/bin/netstat -an | 
/usr/bin/awk -vmax=100 '

# process 1st file (iplist.txt): 

FNR==NR { iplist[$1]                 # FNR==NR is only true for the 1st file; for follow-on files FNR resets to 1 but NR keeps increasing
          next                       # skip to next input record; keeps from running follow-on code against 1st file contents
        }   

# process 2nd file (stdin):

/tcp/   { split($5,a,":")
          if (a[1] > 0 && !(a[1] in iplist))
             c[a[1]]++
        }
END     { for (ip in c) 
              if (c[ip]>max)
                 print ip
        }
' iplist.txt -                      # 2nd file actually says to read from stdin (ie, output from netstat call)

NOTE: OP would then pipe this output to the same while/iptables loop, eg:

/bin/netstat -an | 
/usr/bin/awk -vmax=100 '
FNR==NR { iplist[$1] 
... snip ...
                 print ip
        }
' iplist.txt - |  while read ip; do /sbin/iptables ...;done

# or collapsed to one line (though harder to read and/or troubleshoot):

netstat -an | awk -vmax=100 'FNR==NR{iplist[$1];next} /tcp/{split($5,a,":"); if (a[1] > 0 && !(a[1] in iplist)) c[a[1]]++} END{for (ip in c) if (c[ip]>max) print ip}' iplist.txt - | while read ip; do /sbin/iptables ...;done

Upvotes: 1

Related Questions