ユーザの操作を記録
Windows Serverで、ファイルの監査を行なって、「誰が・いつ・どのファイル・どうした」という統計と、問題が発生した場合にその原因を特定するために、詳細なログを取ることに…。
手順は簡単。まあどの本を見ても書かれているので、詳細は必要ないとは思うけど、参考にした資料くらいは載せておこうと思う。
- ローカルポリシー→監査ポリシー→「オブジェクトアクセスの監査」で成功・失敗をON
- その他「アカウント ログオン イベントの監査」「ログオン イベントの監査」も設定
- エクスプローラで監査したいフォルダを選択。→プロパティ→詳細設定→監査タブで追加→グループもしくはユーザもしくはeveryoneで設定する。
- 設定内容は「ファイルの作成/データの書き込み」「フォルダの作成/データの追加」「サブフォルダとファイルの削除」「削除」「アクセス許可の変更」「所有権の変更」あたりでOKかと…。必要に応じて設定してください。
あとは、セキュリティログに記録されるので、イベントビューワーあたりで確認すればOK。
大量のログが…
ところが、訳の分からない大量のログが発生していて、すぐに溢れてしまう。上書きに設定してもⅠ時間と持たない。アーカイブするようにしても滅茶苦茶な量になる。
どうやら「フィルタリングプラットフォームの接続」に関するログががががが…。
ということで、これじゃログが使いものにならないクズだらけのログになってしまうので、対策を練ることに。
探してみると
- グループポリシー→Windowsの設定→セキュリティの設定→監査ポリシーの詳細な設定→監査ポリシー→オブジェクトアクセス→「フィルタリングプラットフォームの接続の監査」が有るじゃないですか。
- 思い切って、「監査なし」に設定する。
すると、今度は全くログを取らなくなってしまう。悩ましい。
そこで、ポリシーを探してみると、
- 詳細な設定→監査ポリシー→オブジェクトアクセス→「ファイルシステムの監査」と
- ログオンログオフの監査→「ログオンの監査」「ログオフの監査」
- ついでに「アカウントのロックアウトの監査」
このあたりを成功・失敗もしくは成功などを設定してやると、思い通りのログが取れるようになった。
最初から、こうしてくださいな…。
Windowsのログは使いにくい
ログを見るにも速度は遅いし、ログ情報は詳細だけど一覧性が悪すぎる。
サードパーティのソフトを使ってるケースが多いらしいのだけれど、それも馬鹿らしい。
とにかく、紐付けをしてくれないので、散らばったログを、個別に追いかけないといけない。
そこで、今回の目的に合いそうなスクリプトを作成することにした。
いや待てよ、自分が思うことはきっと他の管理者も思うに違いない!ということで探してみる。
これは敬意を込めて、このまま使用させてもらいます。
スクリプトの問題点
ただ、これにも問題があった。すでにアーカイブされたログからの切り出しができない。
Get-wineventを使うと良いらしいということで、過去のアーカイブ用にスクリプトを書き換えて、同じような出力ができるように…。
現在のログは、頂いたスクリプトで処理。
過去のアーカイブログは、変更したスクリプトで処理する。
ちょっと苦労したものの、何とか動かせるようになった。
変更点は多くない。
- ConvertACLは全面的に変更。すでに文字列で取得できているので、trimして返すだけに。
- Get-EventLog Securityの部分は変更。しかもファイル名は標準入力から突っ込む形に。まあ問題無いだろう。
$archive = Read-Host "Archive log file name";
$logons = Get-winevent -Path $archive | Where-Object { $_.ID -eq '4624' };
$acslogs = Get-winevent -Path $archive | Where-Object { $_.ID -eq '4663' };
- 日付の取り出しも変更
$csv = [String]$entry.TimeCreated.ToString("yyyy/MM/dd HH:mm:ss");
ふぅ、なんとか、これで動いた。
あとは、リダイレクトでcsvファイルに保存してやればOK。
csvになれば後は、連結してgrepかまそうが、excelに登場してもらおうが、好きな手段が選べますのでww
注意事項としては、where-Objectがメモリ展開しているために結構遅めです。なので、イベントログのサイズは、あんまり大きくしないほうが精神衛生上よろしいかも。
ちなみに、当初爆裂にログを吐くときは100MBとか1GBとかでテストしていましたが、フィルタリングプラットフォームの設定を変更してからは10MB程度でアーカイブするような設定で運用しています。
この程度のファイルを食わせても、結構時間がかかります。が、それ程速度を要求する処理でもないので、様子見です。
ちなみに35MB程度のイベントログから、ファイル操作だけのデータで、23KBのcsvに生まれ変わりました。
しばらく様子を見て、タスクで実行させるとか、複数ファイルを日付指定で全部処理するとか…。いろいろ応用はできそうなので、その内に…。
以下、スクリプト全文です。
#requires -version 2.0
function GetValue([String]$category, [String]$key, [String[]]$properties)
{
$b = $false;
foreach ($property in $properties) {
if ($b -eq $false) {
if ($property.contains($category)) {
$b = $true;
continue;
}
} else {
if ($property.contains($key)) {
return [String]$property.Substring($property.IndexOf(":")+1).Trim();
}
}
}
return "";
}
function ConvertACL([string]$accessList)
{
return $accessList.trim();
}
function GetLogonInfo([String]$logonid, [Object[]]$entrys)
{
foreach ($entry in $entrys) {
$properties = $entry.Message.Split("`n");
#ID4663のログオンIDとID4624のログオンIDが一致するかどうか
if ($logonid -eq (GetValue "新しいログオン:" "ログオン ID:" $properties)) {
return (GetValue "ネットワーク情報:" "ワークステーション名:" $properties), `
(GetValue "ネットワーク情報:" "ソース ネットワーク アドレス:" $properties);
}
}
return "","";
}
#初期エントリポイント
#$archive = "C:/Windows/System32/winevt/Logs/Archive-Security-2012-10-01-11-06-43-152.evtx";
$archive = Read-Host "Archive log file name";
$logons = Get-winevent -Path $archive | Where-Object { $_.ID -eq '4624' };
$acslogs = Get-winevent -Path $archive | Where-Object { $_.ID -eq '4663' };
$i = 0;
Write-Output "日時,ユーザ名,ドメイン名,コンピュータ名,IPアドレス,ファイル名,操作,アプリケーション";
foreach ($entry in $acslogs) {
$i = $i + 1;
Write-Progress -Activity "Outputting Event" `
-Status "Progress:" -PercentComplete ($i/$acslogs.count*100);
$properties = $entry.Message.Split("`n");
$csv = [String]$entry.TimeCreated.ToString("yyyy/MM/dd HH:mm:ss");
$csv = $csv+","+(GetValue "サブジェクト:" "アカウント名:" $properties);
$csv = $csv+","+(GetValue "サブジェクト:" "アカウント ドメイン:" $properties);
$logoninfo = (GetLogonInfo (GetValue "サブジェクト:" "ログオン ID:" $properties) $logons);
$csv = $csv+","+($logoninfo[0]); #ワークステーション名
$csv = $csv+","+($logoninfo[1]); #ソースネットワークアドレス
$csv = $csv+","+(GetValue "オブジェクト:" "オブジェクト名:" $properties);
$csv = $csv+","+(ConvertACL((GetValue "アクセス要求情報:" "アクセス:" $properties)));
$csv = $csv+","+(GetValue "プロセス情報:" "プロセス名:" $properties);
Write-Output $csv;
}
exit 0;
ダメやん…。
テストしてみたら、ワークステーション名とIPアドレスがうまく表示できていなかった…。
ので、再度検討中。(泣)
検討結果
スクリプトの内容を、詳細に検討・テストした結果、異常はなかった。
でもって、調べてみたらサンプルデータが少なくて、異常な結果を出しているだけだった…トホホ。
ログの一部を切り出してテストしていたので、前後の情報が欠落していて、出力されていないだけだったので、このまま運用することに決定〜。
1日も検証にかかったわ〜。
ログの管理に参考にさせていただきました。
返信削除ありがとうございます。
ログの整理 #2/#3の方が参考になるかもです。
削除power-shellが遅すぎて、イラっとしますのでperlで作成したものを載せてあります。
役に立てば何よりですが…