1

perl を初めて使用するので、正規表現とその使用方法について頭を悩ませるのに役立つ可能性があります。成功したログインと失敗したログインの両方を含むファイル名 auth.log があります。ファイルを読み込んで 1 行ずつ読むための正しいコードを手に入れたので、失敗したものを取り出して日付ごとに画面に出力する方法を理解する必要があります。以下は、失敗したログインの例と、ファイルを読み取るコードです。正規表現が失敗した単語の一致を探すことは知っていますが、構文を取得できません。

Sep 14 07:23:59 icarus sshd[10393]: 137.190.220.15 ポート 64704 ssh2 からの someUser のパスワードの失敗

Sep 14 07:24:04 icarus sshd[10393]: 137.190.220.15 ポート 64704 ssh2 からの someUser のパスワードの失敗

Sep 14 07:30:17 icarus sshd[10523]: 137.190.19.13 ポート 58506 ssh2 から someUser のパスワードを受け入れました

ファイル内の失敗したパスワードの数を吐き出すためだけにカウント変数を開始しようとしていると思います。このスクリプトを実行すると、最終的にはプロンプトで終了する大量の数字が得られます。これは、少なくともauth.log全体でまだ実行されていることを意味しますか、それとも終わりがないのでしょうか? 何か案は?

#!/usr/bin/perl
$count = 0;

open (MYFILE, 'auth.log');
while (my $line = <MYFILE>){
if ($line =~ /Failed password/){
$count++;
}
print $count;
#print "$line\n" if $line =~ /Failed password/; 
#this was a test to make sure it was was getting all the Failed password attempts in              the auth.log.
}
close (MYFILE);

どんな助けでも素晴らしいでしょう。

4

3 に答える 3

2
use strict;
use warnings;

my $current_date = '';

open ( my $file, 'auth.log') or die 'Could not open auth.log';

while ( <$file> ) {
    next unless my ( $user_id ) = m/\Q: Failed password for \E(\w+)/;
    my ( $date ) = m/^((?:J[au]n|Feb|Ma[ry]|Apr|Jul|Aug|Sep|Oct|Nov|Dec) \s+ \d+)/x;
    if ( $date ne $current_date ) {
        $current_date = $date;
        %failures_for = ();
        print "$current_date\n--- --\n";
    }
    my $time = ++$failures_for{$user_id};
    print "$user_id #$time: $_";
}
print "\n";
close $file;

また、ユーザーの失敗数のようなものを保存し、毎日リセットするというアイデアを追加しました。

于 2013-03-14T20:27:23.067 に答える
2

これが、スイス アーミー ナイフのアプローチです。

すべての失敗を表示するには:

cat auth.log | perl -ne 'print if /Failed password/'

9 月のすべての障害を表示するには:

cat auth.log | perl -ne 'print if /Failed password/' | perl -ne 'print if /^Sep/'

「Sep 07 00:00:00」から「Oct 18 22:20:00」までのすべての障害を表示するには

cat auth.log | perl -ne 'print if /Failed password/' | perl -ane '$date = @F[0..2]; print if q(Sep 07 00:00:00) <= $date && $date <= q(Oct 18 22:20:00)'

それらを数えるには:

cat auth.log | perl -ne 'print if /Failed password/' | perl -ane '$date = @F[0..2]; print if q(Sep 07 00:00:00) <= $date && $date <= q(Oct 18 22:20:00)' | wc -l

SomeRandomUser のためにそれらを見つけるには

cat auth.log | perl -ne 'print if /Failed password/' | perl -ne 'print if / for SomeRandomUser /'

私の論文は、このスタイルの Perl を学習することで、事前に予測するのが困難な方法で、ログ ファイルからカスタム抽出をすばやく実行できるようになるということです。それらを機能させたら、後でより堅牢なプログラムに変えることができます。それがあなたの会社に価値をもたらすのであれば。

Ps。私のお気に入りは、ファイルの 123 行目から 456 行目までを抽出する方法です。次のように head と tail を組み合わせて使用​​できます。

cat file | tail -n +123 | head -334

ただし、これには 2 つのコマンドが必要であり、減算とフェンスポスト エラーの可能性があります。代わりに私は覚えました:

cat file | perl -ne 'print if 123 .. 456'

123 からファイルの最後までを印刷するには:

cat file | perl -ne 'print if 123 .. eof'

これはあなたの場合に役立ちます - Perl の -a スイッチと半魔法の '$date = @F[1..3]' の使用方法を覚えようとするのではなく、エディターを使用してログを確認できます。関心のある日付のエントリは 1234 行から 2345 行にあり、次に実行します。

cat auth.log | perl -ne 'print if 1234 .. 2345' | perl -ne 'print if /Failed password/'
于 2013-03-14T22:17:29.150 に答える
1

このようなものはうまくいくはずです..

#!/usr/bin/perl
open(MYFILE, '<auth.log');
while (my $line = <MYFILE>) {
  print "$line\n" if $line =~ /Failed password/;
}
close(MYFILE);

派手になってユーザー/IPだけを取り出したい場合は、これを行うことができます

print "$1 User: $2, IP: $3\n" if $line =~ m/^([A-Za-z]{3}\s+[0-9]{,2}\s+[0-9:]+).*Failed password for ([^ ]+) from ([^ ]+)/;

この手法は、正規表現で後方参照を使用して呼び出されます。Perl では、$N(N は数値) は、左から右に、括弧の各セットで囲まれた文字列に対応します。したがって$1、日付に対応します..$2に続くデータ(この場合はスペース以外の任意の文字)に対応しますFailed password for..または指定したすべてのログに含まれますsomeUser. 同様$3に、これは 3 番目の括弧のセットであり、string に続くスペース以外の文字をキャプチャするため、IP が含まれますfrom

于 2013-03-14T20:30:44.287 に答える