ファイアウォールがクラス全体をブロックできるように、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.X
。168.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 ネットワークの変数として指定できます。cl
2
3
- サブネット全体をブロックする最小発生回数を
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表記でネットワークが印刷されます。
答え2
元の質問に基づいてgrepステートメントを更新し、目的の結果を得ました。 bash専用のソリューションに興味がある人のために更新されたコードセクションは次のとおりです。
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 アドレスの 2 番目の数字の後にドットを追加すると、特定のクラス B IP 範囲と正確に一致します。
"^${IPBL%.[0-9]*.[0-9]*}\."
ip 8.6.144.6 では IPs ファイルに一致が 1 つしかないため、出力には表示されませんが、クラス B の一致は次のようになります。
3.8.35.118 3.8.0.0/16 12
3.8.36.119 3.8.0.0/16 12
3.8.36.121 3.8.0.0/16 12
3.8.37.124 3.8.0.0/16 12
3.8.37.125 3.8.0.0/16 12
3.8.37.126 3.8.0.0/16 12
3.8.37.94 3.8.0.0/16 12
3.8.37.96 3.8.0.0/16 12
3.8.37.97 3.8.0.0/16 12
3.8.37.97 3.8.0.0/16 12
3.8.37.98 3.8.0.0/16 12
3.8.37.98 3.8.0.0/16 12