AWKを使用して列の時間を比較する

AWKを使用して列の時間を比較する

私のサーバーにアクセスするすべてのIPアドレスを一覧表示する変更されたログファイルがあります。

各IPアドレス行の横には日付/時刻スタンプがあります。

ボットと悪意のある活動をフィルタリングする過程で、15秒以内に5つ以上の要求を行ったIPアドレスがあることを確認したいと思います。

質問これを測定する方法については、最初のリクエストから始めますが、これについてさらに議論したいと思います。

私は現在(G)AWKを学んでいますが、もっと学びたいです。可能であれば、(G)AWKで完了し、できるだけ明確に説明されてほしいです。だから、私はこのスクリプトを研究し、将来的に同様のスクリプトを直接書くことができることを願っています。

私はこれがおそらくPythonで実行できることを知っていますが、まだPythonを学んだことはありません。

入力サンプル

私のログファイルの完全な(動作)修正された(IPアドレスを難読化するために)バージョンは次のとおりです。 ログファイル.csv

結果をテストしたい場合に備えて、そのファイルの[追加修正]の例は次のとおりです。

03/Nov/2020:06:33:09|000.000.000.001|200|/page-1/
03/Nov/2020:07:12:21|000.000.000.002|200|/page-2/
03/Nov/2020:07:24:52|000.000.000.003|200|/page-3/
03/Nov/2020:07:30:50|000.000.000.004|200|/page-4/
03/Nov/2020:07:47:29|000.000.000.005|200|/page-5/
03/Nov/2020:07:52:42|000.000.000.006|200|/page-6/
03/Nov/2020:07:52:55|000.000.000.007|200|/page-7/
03/Nov/2020:08:00:11|000.000.000.008|200|/page-8/
03/Nov/2020:08:05:00|000.000.000.009|200|/page-9/
03/Nov/2020:08:05:06|000.000.000.010|301|/page-10/
03/Nov/2020:08:05:32|000.000.000.007|200|/page-11/
03/Nov/2020:09:02:49|000.000.000.011|304|/page-12/
03/Nov/2020:09:02:49|000.000.000.011|404|/page-13/
03/Nov/2020:09:13:18|000.000.000.011|304|/page-14/
03/Nov/2020:09:13:19|000.000.000.011|404|/page-15/
03/Nov/2020:09:14:20|000.000.000.012|200|/page-16/
03/Nov/2020:09:23:48|000.000.000.011|304|/page-17/
03/Nov/2020:09:23:49|000.000.000.011|404|/page-18/
03/Nov/2020:09:34:19|000.000.000.011|304|/page-19/
03/Nov/2020:09:34:19|000.000.000.011|404|/page-20/
03/Nov/2020:09:35:42|000.000.000.013|301|/page-21/
03/Nov/2020:09:35:42|000.000.000.013|404|/page-22/
03/Nov/2020:09:44:49|000.000.000.011|304|/page-23/
03/Nov/2020:09:44:49|000.000.000.011|404|/page-24/
03/Nov/2020:09:53:38|000.000.000.014|200|/page-25/
03/Nov/2020:09:55:19|000.000.000.011|304|/page-26/
03/Nov/2020:09:55:19|000.000.000.011|404|/page-27/
03/Nov/2020:10:05:49|000.000.000.011|304|/page-28/
03/Nov/2020:10:05:49|000.000.000.011|404|/page-29/
03/Nov/2020:10:06:27|000.000.000.005|200|/page-30/
03/Nov/2020:10:16:19|000.000.000.011|304|/page-31/
03/Nov/2020:10:16:19|000.000.000.011|404|/page-32/
03/Nov/2020:10:17:21|000.000.000.015|200|/page-33/
03/Nov/2020:10:20:35|000.000.000.016|200|/page-34/
03/Nov/2020:10:20:37|000.000.000.017|404|/page-35/
03/Nov/2020:10:20:42|000.000.000.017|404|/page-39/
03/Nov/2020:10:20:49|000.000.000.016|200|/page-40/
03/Nov/2020:10:20:55|000.000.000.017|404|/page-41/
03/Nov/2020:10:21:01|000.000.000.017|404|/page-42/
03/Nov/2020:10:21:03|000.000.000.017|404|/page-43/
03/Nov/2020:10:21:05|000.000.000.017|404|/page-44/
03/Nov/2020:10:21:06|000.000.000.017|404|/page-45/
03/Nov/2020:10:21:11|000.000.000.017|404|/page-46/
03/Nov/2020:10:21:14|000.000.000.016|200|/page-47/
03/Nov/2020:10:21:34|000.000.000.016|200|/page-48/
03/Nov/2020:10:21:47|000.000.000.016|200|/page-49/
03/Nov/2020:10:22:14|000.000.000.016|200|/page-50/
03/Nov/2020:10:22:15|000.000.000.016|200|/page-51/
03/Nov/2020:10:22:15|000.000.000.016|200|/page-52/
03/Nov/2020:10:22:16|000.000.000.016|200|/page-52/
03/Nov/2020:10:22:17|000.000.000.016|200|/page-53/
03/Nov/2020:10:22:18|000.000.000.019|200|/page-1/
03/Nov/2020:10:22:20|000.000.000.016|200|/page-55/
03/Nov/2020:10:22:20|000.000.000.016|200|/page-56/

希望の出力

bot-list.txt私はあなたが次のリストを含む文書を生成したいと思います。15秒以内に5つ以上の要求を行うIPアドレスいつでも(必ず最初の5日ではない)。後で頻度/持続時間を調整したい場合があります。

ログファイルがかなり大きいので、ここにログファイル全体を公開するのは適切ではないと思います。ただし、上記の(修正された)例の出力には2つのIPアドレスしかありません。したがって、ログファイル全体をテストする方がより安定しています。

000.000.000.017
000.000.000.016

どのようにこの結果が得られたかを明確に説明してください。。追加ボーナスとして、よく知られていないスキル/機能を使用している場合は、そのスキルについて詳しく知ることができる参考資料を教えてください。

したがって、明確に言えば、

  • すべての一意のIP検索log-file.csv
  • このIPのインスタンスが5つ以上の場合は、各行の日付/時刻スタンプを使用してインスタンス間の差(秒単位)を計算します。
  • 15秒以内に5ページ以上にアクセスするIPアドレスを隔離します。
  • これらのIPアドレスをbot-list.txt
  • 可能であれば、単一の(G)AWKスクリプトでこれを完了してください。

この概念を改善する方法に関する追加の提案を歓迎します。

私が試したこと

正直なところ、GAWKで行を比較する方法がわかりませんが、以前の質問に対する回答のいくつかを見ると可能であることは明らかです。

現在、私は「Effective AWKProgramming」という本を読んでいます。面白いのに、一部で苦労しました。連想配列についても調べていますが、プログラミングの背景知識がないのでゆっくり学んでいます。

私は特定の問題を解決するものを見つけることができず、そのトピックに関するビデオもほとんどありません。

誰もがこの種の問題を解決するのに役立つ可能性のある有用なリソースを教えてください。

日付を比較しようとしています。

egrep "000.111.000.111" log-file.csv | awk 'BEGIN{FS="|"; ORS=" "} NR==1 || NR==5 {print $1,$2}' | sed -e 's/[\/:]/\ /g' -e 's/Jan/1/g' -e 's/Feb/2/g' -e 's/Mar/3/g' -e 's/Apr/4/g' -e 's/May/5/g' -e 's/Jun/6/g' -e 's/Jul/7/g' -e 's/Aug/8/g' -e 's/Sep/9/g' -e 's/Oct/10/g' -e 's/Nov/11/g' -e 's/Dec/12/g' | awk '{print $3,$2,$1,$4,$5,$6 "," $10,$9,$8,$11,$12,$13","$14}' | awk -F, '{d2=mktime($2);d1=mktime($1);print d2-d1, $3}'  | awk '{if($1<15)print $2}' >> bot-list.txt

残念ながら、ご覧のように(G)AWKですべてを行うことはできませんが、可能であれば感謝します。

(Stack Exchangeを使用するのは今回が2番目です。質問する方法についてのアドバイスに従おうとし、間違いがある場合は追加のアドバイスを受けてうれしいです。)

ありがとうございます。

ベストアンサー1

エポック秒をメモリ(配列)に変換した後、すべてのIPアドレスとタイムスタンプを読み取る簡単な無差別代入方法ですsecs[]。その後、ファイル全体を読み取り、一度に1つのIPアドレス配列を繰り返し、違いと5つの項目ごとにタイムスタンプを確認します。 15秒未満の項目があることを確認してください。

$ cat tst.awk
BEGIN { FS="|" }
{
    split($1,t,"[/:]")
    monthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[2])+2)/3
    currSecs = mktime(t[3] " " monthNr " " t[1] " " t[4] " " t[5] " " t[6])

    secs[$2][++count[$2]] = currSecs
}
END {
    range = 5
    for (ip in secs) {
        for (beg=1; beg<=(count[ip]-range)+1; beg++) {
            end = beg + range - 1
            if ( (secs[ip][end] - secs[ip][beg]) < 15 ) {
                print ip
                break
            }
        }
    }
}

$ awk -f tst.awk file
000.000.000.016
000.000.000.017

これは、IPアドレスとエポック秒のリストを格納するのに十分なメモリが必要ですが、これが問題になるにはファイルが大きくなければならないことを意味します(数十億行)。


編集:あなたの質問に対するコメントによると、入力ファイルが正しい順序(日付+時間の増加)ではないため、次の手順を実行して問題を解決できます。

$ awk -F'|' '
    {
        split($1,t,"[/:]")
        monthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[2])+2)/3
        currSecs = mktime(t[3] " " monthNr " " t[1] " " t[4] " " t[5] " " t[6])

        print currSecs, NR, $0
    }
' log-file.csv | sort -k1,1n -k2,2n | cut -d' ' -f3- > sorted-log-file.csv

次に、THATで上記のスクリプトを実行して、次の50個のIPアドレス出力を取得します。

$ awk -f tst.awk sorted-log-file.csv | sort
000.000.000.011
000.000.000.017
000.000.000.036
000.000.000.056
000.000.000.066
000.000.000.094
000.000.000.115
000.000.000.121
000.000.000.136
000.000.000.141
000.000.000.157
000.000.000.169
000.000.000.178
000.000.000.181
000.000.000.183
000.000.000.208
000.000.000.227
000.000.000.230
000.000.000.283
000.000.000.312
000.000.000.354
000.000.000.361
000.000.000.368
000.000.000.370
000.000.000.505
000.000.000.515
000.000.000.579
000.000.000.580
000.000.000.588
000.000.000.610
000.000.000.634
000.000.000.642
000.000.000.651
000.000.000.748
000.000.000.756
000.000.000.758
000.000.000.772
000.000.000.795
000.000.000.814
000.000.000.852
000.000.000.878
000.000.000.882
000.000.000.922
000.000.000.994
000.000.000.995
000.000.001.047
000.000.001.119
000.000.001.139
000.000.001.185
000.000.001.198

おすすめ記事