2016-05-02 54 views
0

私はまったく動作しないコードサンプルを持っています。私はawkによって生成されるエラーを永久に得る。awk:cmd。行:1:(FILENAME = - FNR = 1)致命的:フィールド-1にアクセスしようとしました

queried_num=$(echo -e "$domains"|awk '{print $(NF-1)}'|awk -F. '{print $(NF-2) "." $(NF-1)}'|wc -l) 

queried_domain=$(echo -e "$domains"|awk '{print $(NF-1)}'|awk -F. '{print $(NF-2) "." $(NF-1)}'|uniq) 

私は何がうまくいかず、それを修正する方法を実際に知りません。

エラーはawk:cmdです。行:1:(FILENAME = - FNR = 1)致命的な:フィールドにアクセスしようとすると-1

+2

あなたは何をしようとしていますか?簡潔でテスト可能なサンプル入力と予想される出力を含めるように質問を編集してください。 –

+1

ヒント:入力に1行に少なくとも1つの '.'がない場合、' NF-2'とは何ですか?おそらく 'awk'コードを' awk -F 'のようなもので修飾したいと思うでしょう。 'NF> 2 {印刷...}' '。 – twalberg

答えて

1

あなたが投稿2つのスクリプト:

queried_num=$(echo -e "$domains"|wc -l) 

queried_domain=$(echo -e "$domains"|awk '{n=split($(NF-1),f,/./); $0=f[n-2] "." f[n-1]} !seen[$0]++') 

queried_num=$(echo -e "$domains"|awk '{print $(NF-1)}'|awk -F. '{print $(NF-2) "." $(NF-1)}'|wc -l) 

queried_domain=$(echo -e "$domains"|awk '{print $(NF-1)}'|awk -F. '{print $(NF-2) "." $(NF-1)}'|uniq) 

のようなだけで何かのように書くことができ(あなたが記述問題を引き起こす)空行を廃棄する

、その後は次のようになります。

queried_num=$(echo -e "$domains"|grep '.'|wc -l) 

queried_domain=$(echo -e "$domains"|awk '!NF{next} {n=split($(NF-1),f,/./); $0=f[n-2] "." f[n-1]} !seen[$0]++') 

それがどのようなyのない場合私たちがあなたを助けることができるように、あなたの質問を編集して、簡潔でテスト可能なサンプル入力と予想される出力を含めてください。

0

申し訳ありませんが、私のせいでした。ここに完全なコードがあります:

#!/bin/bash 
SHELL=/bin/sh 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
#this script checks for massive outgoing connections to nameservers 
#it then finds the domains queried and blocks those queries 
#using iptables and string matching 

#block the sources of the queries or their targets? 
#sources,targets 
block="sources" 

#max 50 connections to one DNS server allowed 
limit="50" 

#threshold for identical A queries 
threshold="10" 

#blacklist file 
blacklist="/etc/domain_blacklist" 

#sources file, users who query the blacklisted domains 
sources="/etc/domain_sources" 

#what to query? 
queries="A? TXT?" 

#interface for tcpdump 
interface="eth0" 

#number of packets to tcpdump capture 
packets="10" 

#whitelist domains, prevent from being listed in firewall 
whitelist="google.com google.de" 

#list of DNS servers with open conections 
list=$(hostname -I | cut -d' ' -f1) 

for ip in $(hostname -I | cut -d' ' -f1) 
do 
     connections=$(netstat -an|grep 53|grep -v udp6|grep -v 2001|grep 10.10.10.10|wc -l) 
     if [[ $connections -gt ${limit} ]] 
     then 
       #show number of open connections to this DNS 
       echo -e "IP: $ip\tCONS: $connections" 
       for query in $queries 
       do 
         domains=$(tcpdump -i eth0 -n -c 10 host 10.10.10.10 and port 53 2>/dev/null|grep "$query"|awk '{print $(NF-1)}') 
         if [[ ! $domains ]] 
         then 
           continue 
         fi 

       done 

         else 
           break 
         fi 
#    done 

       #show what FQDN are queried 
       echo -e "${domains}" 
       #calculate identical queried domains in dump 
       queried_num=$(echo -e "$domains"|awk '{print $(NF-1)}'|awk -F. '{print $(NF-2) "." $(NF-1)}'|wc -l) 
       if [[ $queried_num -eq $threshold ]] 
       then 
         queried_domain=$(echo -e "$domains"|awk '{print $(NF-1)}'|awk -F. '{print $(NF-2) "." $(NF-1)}'|uniq) 
         #add domain to blacklist if it does not exist 
         if [[ ! $(grep "$queried_domain" $blacklist) ]] 
         then 
           echo $queried_domain >> $blacklist 
         fi 
       fi 

#  fi 
#done 

#find sources who query those domains 
for i in $(cat /etc/domain_blacklist) 
do 
     sources_list=$(tcpdump -i eth0 -P in -s 0 -l -n -c1000 port 53 2>/dev/null|grep "$i"|cut -d' ' -f 3|cut -d'.' -f1-4|sort -u) 
     for j in $sources_list 
     do 
       if [[ ! $(grep $j $sources) ]] 
       then 
         echo $j >>$sources 
       fi 
     done 
done 


#done grabbing domains that are abused, now lets block the complete list! 
if [[ $block == "targets" ]] 
then 

     for entry in $(cat $blacklist) 
     do 
       if [[ $whitelist =~ $entry ]] 
       then 
         continue 
       fi 

       echo "Blocking $entry" 

       #careful, we have to separate domain and TLD and convert separately to HEX. 
       #if TLD is 2 characters long e.g. cn then hex value 02 is used for dot, if 3 e.g. com then 03 
       domain=$(echo $entry|cut -d'.' -f1) 
       tld=$(echo $entry|cut -d'.' -f2) 
       echo "Domain is: $domain, TLD is $tld" 

       #find length of tld 
       tld_length=${#tld} 
       #convert to hex 
       domain_hex=$(echo -n $domain|xxd -p) 
       tld_hex=$(echo -n $tld|xxd -p) 
       if [[ $tld_length -eq 2 ]] 
       then 
         dot_hex="02" 
       fi 

       if [[ $tld_length -eq 3 ]] 
       then 
         dot_hex="03" 
       fi 

       echo "hex domain: $domain_hex, tld hex: $tld_hex, length tld: $tld_length" 

       #check if rule exists 
       iptables -C INPUT -p udp --dport 53 -m string --from 34 --to 90 --algo bm --hex-string "|$domain_hex$dot_hex$tld_hex|" -j DROP -m comment --comment "Drop DNS $entry" 
       if [[ $? -gt 0 ]] 
       then 
         iptables -I INPUT -p udp --dport 53 -m string --from 34 --to 90 --algo bm --hex-string "|$domain_hex$dot_hex$tld_hex|" -j DROP -m comment --comment "Drop DNS $entry" 
       fi 

     done 
elif [[ $block == "sources" ]] 
then 
     for entry in $(cat $sources) 
     do 
       if [[ $whitelist =~ $entry ]] 
       then 
         continue 
       fi 

       echo "Blocking $entry" 
       #check if rule exists 
       iptables -C INPUT -p udp --dport 53 -s $entry -j DROP -m comment --comment "Drop DNS query $entry" 
       if [[ $? -gt 0 ]] 
       then 
         iptables -I INPUT -p udp --dport 53 -s $entry -j DROP -m comment --comment "Drop DNS query $entry" 
       fi 
     done 


fi 

done 

exit 0 
関連する問題