grepファイルのIP番号の一部

grepファイルのIP番号の一部

ファイアウォールがクラス全体をブロックできるように、IPアドレスを分類する必要があります。 /24 クラスで動作しようとすると正しく動作しますが、/16 クラスで動作すると正しく動作しません。ソートしたいIPのリストはtxtファイルにあります。

for IPBL in `cat /tmp/IPs`; do 
  CT=`grep -c ${IPBL%.[0-9]*} /tmp/IPs`
    if [ "$CT" -gt "10" ]; then 
      echo "$IPBL  ${IPBL%.[0-9]*}.0/24  $CT" >>/tmp/spam.lst
    fi
done
cat /tmp/spam.lst |sort -n

したがって、これはうまく機能し、10よりも一致するすべてのIPがクラスCであることを印刷します。

for IPBL in `cat /tmp/IPs`; do 
  CT=`grep -c ${IPBL%.[0-9]*.[0-9]*} /tmp/IPs`
    if [ "$CT" -gt "10" ]; then 
      echo "$IPBL  ${IPBL%.[0-9]*.[0-9]*}.0.0/16  $CT" >>/tmp/spam.lst
    fi
done
cat /tmp/spam.lst |sort -n

したがって、この例ではほとんどの一致が大丈夫ですが、一部の一致はそれ以上のものですgrep

  • IPなどが8.6.X.X一致します18.6.X.X168.6.X.X

^${IPBL%.[0-9]*.[0-9]*}一致する行の先頭に配置しようとしましたが、grep役に立ちませんでした。

grep -E -c "${IPBL%.[0-9]{1,3}.[0-9]{1,3}}" /tmp/IPs

IP 番号の特定の桁を一致させ、^文字列の前に置かないでください。

正確な一致を抽出する最も効率的な方法は何ですか?
/tmp/IPsファイルは大きいですが、Bマスクgrepを実行すると、次のIP番号がすべて一致します。正確には一致する項目は1つだけです(2行目)。

#IPBL=8.6.144.6
#grep ${IPBL%.[0-9]*.[0-9]*} /tmp/IPs
5.188.62.76
8.6.144.6
39.48.63.128
49.178.61.44
68.61.98.98
73.121.228.65
78.128.60.44
81.68.68.194
86.185.248.61
103.129.178.69
108.61.115.213
108.61.199.100
138.68.224.206
138.68.235.36
142.4.218.69
148.63.196.97
148.64.121.254
148.66.129.250
148.66.130.114
149.202.8.66
173.228.198.65
174.251.128.60
176.78.65.246
176.9.208.67
178.128.68.121
178.62.67.41
178.63.146.46
212.48.66.224

ベストアンサー1

私が正しく理解したら、IPリストを解析して、そのIPが属するクラスBまたはクラスCネットワークを確認したいと思います。そのネットワークが10回以上表示される場合は、コメントにIPとそのネットワークが属するネットワークを印刷する必要があります。

A.B.C.D   A.B.0.0/16  n

または

A.B.C.D   A.B.C.0/24  n

各出力ファイルを作成しますspam.lst。ここでは、nそのサブネットの実際の発生回数です。

awk私は仕事について次の手順を提案します(と呼びますsort.awk)。

#!/bin/awk -f

BEGIN{
    FS=OFS="."
}

NF==4{
    if (FNR==NR) {
        NF=cl
        count[$0]++
        next
    }
    for (n in count) {
        if (index($0,n)==1) {
            if (count[n]<=th) next
            printf "%s %s",$0,n
            for (i=cl;i<4;i++) printf ".0"
            printf "/%d %d\n",8*cl,count[n]
        }
    }
}

次のように呼び出すことができます。

awk -v cl=2 -v th=1 -f sort.awk ips.txt ips.txt> spam.lst

入力ファイルは2回処理されるため、awk!の引数として2回表示されます。

プログラムの仕組みは次のとおりです。

  • CIDR ネットワークカテゴリをawkクラス B ネットワークまたはクラス C ネットワークの変数として指定できます。cl23
  • サブネット全体をブロックする最小発生回数をawk変数として指定できますth
  • プログラムは、.入力行をフィールドに分割するために入力と出力の区切り文字を設定します.
  • スクリプトは、4つのフィールドを持つ行のみを考慮します(IPの最小限の完全性チェック)。
  • 最初のステップ(FNRファイルごとの行カウンターがNRグローバル行カウンターと同じです)では、見つかったサブネットを登録します。各行のフィールド番号は、clクラスBまたはクラスCネットワークの「ベースアドレス」に切り捨てるために値に切り捨てられます。その後、配列内のこの(新しく作成された)ベースアドレスのカウンタがインクリメントcountされ、処理が次の行にジャンプします。
  • 2番目のパスでは、すべての項目を繰り返します。索引(つまり、count最初のパスに登録されているすべてのサブネット)現在の行のIPがそのサブネットアドレスで始まることを確認してください。接続数がしきい値を超えると、現在のIPアドレスを出力してからベースアドレスを出力し、.0右側にCIDR表記でネットマスクを追加し、最後に発生回数を出力します。

の出力は、表示されているサンプルIPリストcl=2とともに次のとおりです。th=1

108.61.115.213 108.61.0.0/16 2
108.61.199.100 108.61.0.0/16 2
138.68.224.206 138.68.0.0/16 2
138.68.235.36 138.68.0.0/16 2
148.66.129.250 148.66.0.0/16 2
148.66.130.114 148.66.0.0/16 2

最初の提案は、次のように既存のスクリプトに統合することでした。

awk -v cl=2 -v nw="8.6.0.0" -F'.' 'BEGIN{split(nw,ref,/\./)} NF==4{for (i=1;i<=cl;i++) {if ($i!=ref[i]) next} printf "%s %s/%d\n",$0,nw,8*cl}' ips.txt

ここでは、IPリストを分析して、awkそのIPが変数で指定されたネットワークベースアドレスと同じネットワークに属していることを確認しますnw

  • 最初は、参照ネットワークのデフォルトIPがフィールドごとに配列に分割されますref
  • 見つかった各行に対して、プログラムは最初にその行に4つのフィールドが含まれていることを確認します(IPの最小限の完全性チェック)。その場合、cl現在の行を参照IPの最初のフィールドと比較します。一致しない項目がある場合は、その行をスキップして次の行を処理し続けます。すべての関連フィールドが一致すると、IPが印刷され、CIDR表記でネットワークが印刷されます。

おすすめ記事