Proxmoxでサーバ構築

イメージ
これまでテスト用にi5第8世代の廃棄PCを使用してきた。 とはいえ今の所何も問題は起きていないが、入れ替えも視野に入れ予備サーバを用意することに。 - メモリ:16GB - SSD:500GB - DDNS+Let's Encrypt - Ubuntu24.04 この環境なので、すぐに構築し直すことは可能だが、とりあえずこのまま置いておいて別のサーバを立てることにする。 最初はRaspberryPiで構築しようと思ったけれど、本体電源+外付けHDD電源+ディスプレイ電源と考えると、邪魔なので廃案。 そこで廃棄しようと思っていた「Lavie NS300/N」が手元にあったので、これを利用することに。 一応バッテリーは正常に動作するので、UPS代わりにそのまま。 - Core™ i3-8145U(やや非力) - メモリ:8GB(少ないが…) - HDD:1TB なので、これまで使用しているものより、若干スペックダウン。 ただ用途は、非常勤で教えに行っている専門学校生用の練習マシンとする予定なので、まぁ問題なさそう。 Proxmox導入 直接、Linuxを導入してもよいのだけれど、今回は Proxmox を導入し、その上でUbuntu Serverを動作させる計画。 USBにProxmoxのイメージを焼いて、インストールすれば問題なく完了。 ただ、現在のバージョンはdebian - trixieがベースになっているので、若干参考になるサイトが少なめ。とはいえ旧版のは参考になるので調べつつ… HDDなだけあって、最初の起動は少し遅いものの、立ち上がってしまえば問題ない。 さぁ、VMにするかCTにするか…。 GUI使うのであれば、VMかなぁ。サーバだしCTでいいかぁ。 という程度の選定で、CT(コンテナ)で進めることに。 - メモリ:4GB - CPU:2 - HDD:20GB(root disk) - HDD:400GB(home用) - Ubuntu24.04 という構成で進めることにした。 テンプレートを用意して、初期設定を行い起動。 まぁすんなりと入った。 液晶を閉じたら、Suspendになってしまったので、若干設定変更。 $ sudo nano /etc/systemd/logind.conf HandleLidSwitch=ignore $ sudo sy...

ログの整理 #3

PowerShellでは遅すぎて…

実際問題、ログからcsvに切り出すことは可能になったものの、10MBのログから200kb前後のcsvファイルを生成するのに前回のスクリプトだと約2時間かかるんですねぇ。
そりゃ、1レコードを生成するのに、ログオンIDで再度全部ログを舐めて、PCの名前とIPを拾っているわけで…。
単純に考えればO(n^2)というわけですね。
ログのローテーションというか上限を5MB(半分)にすれば、多分処理速度は1/4程度にまで下がるとは思われるけれど、120分が30分になって、ファイル数が倍なので実質1時間かかるわけで…。orz。

何が遅い?

実際、何に時間がかかっているのかを調べ始めたのだけれど、まずwhere-Objectが結構な時間を消費している。その後foreachで回す処理は激遅い。
結局、イベントログからオブジェクトとして扱っているのが、遅さの原因ぽい。

最適化しようにも、PowerShell自体の扱いに慣れていないので、とっても疲れるです。

他に良い方法は無いものだろうか?と思案し始めた時に、以前オライリーの本で見た記憶があったので、ちょいっと検索してみる。

方針変更!

perlのモジュールにW32::EventLogが有るじゃないですか。
早速、マニュアルを参考にテスト用のコードを書いてみる。
さすがに、サーバ上での作業は心配なので、VM上のWindows7にActivePerlを入れてテストすることに。

細かい仕様を決めようか、汎用的に作ろうかと迷いつつも、現状の作業をサックリ行えることを目的に作成した。約1日かけて、コーディング終了。前回までのスクリプトと同じ結果を返すようにするところで、少々苦労したわ。

なので、若干コードは汚い(perlなのでさらに汚いww)とは思うのだけれど、これが素晴らしい性能を発揮してくれた。

コードは以下全体を載せておくので、もし万が一使いたい人は、自己責任にてお願いします。

さて、実際に同じデータを食わせてみると、なっなんと、2時間かかっていた処理を1分以内に終えてくれる!!!

あぁ、これで今後のログの整理が快適になる。
1週間分、いや1ヶ月分まとめて処理だって怖くない!
あとは、コマンドラインでイベントログを引数として渡せば良い仕様にしたので、バッチでも動かせるし…。

もう少し、バグ取りなんかも必要かもしれないし、エラー時の処理なんかは、全くしていないレベルなので、暇な時にでもやろうとは思っている。

この手間は、大きな差を産んでくれる! 120倍速の処理完了〜。


use Win32::EventLog;
$Win32::EventLog::GetMessageText = 1;
$DEBUG=0;
sub make_time {
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @_;
  return sprintf("%04d/%02d/%02d %02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec);
}
sub event_hash4624{
my($strings)=@_;
my @event=('SubjectUserSid','SubjectUserName'    ,'SubjectDomainName'      ,'SubjectLogonId',
  'TargetUserSid' ,'TargetUserName'     ,'TargetDomainName'         , 'TargetLogonId',
  'LogonType'     ,'LogonProcessName'   ,'AuthenticationPackageName','WorkstationName',
  'LogonGuid'     ,'TransmittedServices','LmPackageName'            ,'KeyLength',
  'ProcessId'     ,'ProcessName'        ,'IpAddress'                ,'IpPort');
my @list = split(/[\0]/, $strings);
my %h;
for(my $idx=0;$idx<$#event;$idx++){
$h{$event[$idx]}=$list[$idx];
}
return %h;
}
sub event_hash4663{
my($strings)=@_;
my @event=('SubjectUserSid','SubjectUserName','SubjectDomainName' ,'SubjectLogonId',
  'ObjectServer'  ,'ObjectType'     ,'ObjectName'        ,'HandleId',
  'AccessList'    ,'AccessMask'     ,'ProcessId'         ,'ProcessName');
my @list = split(/[\0]/, $strings);
my %h;
for(my $idx=0;$idx<$#event;$idx++){
$h{$event[$idx]}=$list[$idx];
}
return %h;
}
sub convert_acl{
my ($access_list)=@_;
my %acl = ('%%1537'=>"Delete"                 ,'%%1538'=>"Read_CONTROL"  ,'%%1539'=>"Write_DAC",
  '%%1540'=>"Write_OWNER"            ,'%%1541'=>"Synchronize"   ,'%%4416'=>"ReadData (or List Directory)",
  '%%4417'=>"WriteData (or Add File)",'%%4418'=>"AppendData (or AddSubdirectory or CreatePipeInstance)",
  '%%4419'=>"ReadEA"                 ,'%%4420'=>"WriteEA"       ,'%%4421'=>"ExecuteFile",
  '%%4422'=>"DeleteChild"            ,'%%4423'=>"ReadAttributes",'%%4424'=>"WriteAttributes");
$access_list =~ s/^\s*(.*?)\s*$/$1/;
if($acl{$access_list}){
return $acl{$access_list};
}else{
return "Other";
}
}
sub make_db_id {
my ($eventlogname,$event_id) = @_;
  my $handle = Win32::EventLog->new($eventlogname) or die "can't open event log.\n";
  $handle->GetNumber($recs) or die "Can't get number of EventLog records\n";
  $handle->GetOldest($base) or die "Can't get number of oldest EventLog record\n";

  my $x=0;
  while ($x < $recs) {
    $handle->Read(EVENTLOG_FORWARDS_READ|EVENTLOG_SEEK_READ,
                  $base+$x,
                  $hashRef) or die "Can't read EventLog entry #$x\n";
    if($hashRef->{EventID} eq $event_id){
%eventdata = event_hash4624($hashRef->{Strings});
$workpc    = $eventdata{'WorkstationName'}?$eventdata{'WorkstationName'}:"";
$logonname = $eventdata{'TargetUserName'}?$eventdata{'TargetUserName'}:"";
    $logonid   = $eventdata{'TargetLogonId'};
$logonip   = $eventdata{'IpAddress'}?$eventdata{'IpAddress'}:"";
      if(!($logonname =~ /\$/)){
        $db_id{$logonid}=$workpc . "," . $logonip;
}
    }
    $x++;
  }
return %db_id;
}
my $archivelogname = $ARGV[0];
my %id_list = make_db_id($archivelogname,"4624");
my $csvfilename;
$csvfilename = $archivelogname;
$csvfilename =~ s/\.evtx$/\.csv/;
$csvfilename =~ s/^.+\\//;
open(FH,">$csvfilename") or die("Can't open csv file\n");
print FH "日時,ユーザ名,ドメイン名,ログオンID,コンピュータ名,IPアドレス,ファイル名,操作,アプリケーション";
    my $event_id="4663";
  my $handle = Win32::EventLog->new($archivelogname) or die "can't open event log.\n";
  $handle->GetNumber($recs) or die "Can't get number of EventLog records\n";
  $handle->GetOldest($base) or die "Can't get number of oldest EventLog record\n";

  my $x=0;
  while ($x < $recs) {
    $handle->Read(EVENTLOG_FORWARDS_READ|EVENTLOG_SEEK_READ,
                  $base+$x,
                  $hashRef) or die "Can't read EventLog entry #$x\n";
    if($hashRef->{EventID} eq $event_id){
%eventdata = event_hash4663($hashRef->{Strings});
            $csv = make_time(localtime($hashRef->{'TimeGenerated'})) . ",";
            $csv .= $eventdata{'SubjectUserName'} . ",";
            $csv .= $eventdata{'SubjectDomainName'} . ",";
            $csv .= $eventdata{'SubjectLogonId'} . ",";
if($id_list{$eventdata{'SubjectLogonId'}}){
$csv .= $id_list{$eventdata{'SubjectLogonId'}} . ",";
}else{
$csv .= ",,";
}
            $csv .= $eventdata{'ObjectName'} . ",";
            $csv .= &convert_acl($eventdata{'AccessList'}) . ",";
            $csv .= $eventdata{'ProcessName'};
            print FH $csv."\n";
    }
    $x++;
  }
close(FH);

コメント

このブログの人気の投稿

Ubuntu24.04 でGUIが死んだ

VirtualBoxが異常

MEGAにも弱点があった?