Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

Question is how can I make it "pretty", aka, 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 somethig like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

/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

Thanks in advance!

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading