CloudWatchで監視するWindowsイベントログ

こんにちは、吉井です。
いかがお過ごしでしょうか。

今回は、Windows ServerのイベントログをCloudWatchで監視する方法を紹介します。
具体的には

  • SSMエージェントを最新化
  • CloudWatchエージェントのインストールと設定
  • イベントログをCloudWatch Logsへ転送
  • メトリクスフィルタを作成
  • アラームを作成してメール通知

という流れになります。

本エントリはイベントログのなかでもSecurityを監視する例になっています。
メトリクスフィルタの部分をカスタマイズすれば様々なイベントログに対応することが可能です。

準備

本エントリではSystems Managerを使って設定を行います。
準備としてSSMエージェントとCloudWatchエージェントをサーバーへインストール(または最新化)します。
※EC2インスタンスは起動済みの前提です。

Systems Managerについてはこちらのエントリも詳しいので参照ください。

SSH不要時代がくるか!?AWS Systems Manager セッションマネージャーがリリースされました!

EC2にIAMロールを割り当て

AWSマネジメントコンソールへログインし
IAM → ロール → ロールの作成 をクリックします。

EC2 を選択して 次のステップ をクリックします。

下の2つのポリシーを選択して 次のステップ をクリックします。

  • AmazonEC2RoleforSSM
  • CloudWatchAgentAdminPolicy

任意のロール名を付与します。
ポリシーが正しく付いていることを確認して ロールの作成 をクリックします。

次にマネジメントコンソールで EC2 → インスタンス を開きます。
任意のインスタンスにチェックを入れて アクション → インスタンスの設定 → IAMロールの割り当て/置換 をクリックします。

先ほど作成したIAMロールを選択して 適用 をクリックします。

SSMエージェントの最新化

マネジメントコンソールで Systems Manager → ランコマンド→コマンドの実行 をクリックします。
コマンドのドキュメントから AWS-UpdateSSMAgent (Windows Server2016の場合)、または AWS-UpadteEC2Config (Windows Server 2012とそれ以前) にチェックを入れます。

ターゲット からターゲットインスタンスを選択します。
対象を手動選択することも出来ますし、タグを指定して一括選択することも出来ます。
タグキー:OS、タグ値:Windows Server 2016 などにしておくと管理が楽になると思います。

出力オプションS3バケットへの書き込みの有効化 にチェックを入れます。
S3バケットへの書き込みを有効化しない場合、標準出力の最後2500文字のみが表示されます。
エラー時の解析には全ての出力が必要になりますので、S3バケットへの書き込みを有効化するようにしておきます。

実行 をクリックします。

コマンド実行画面に遷移します。しばらくするとステータスが 成功 に変わります。

SSMエージェントの最新化は完了です。

CloudWatchエージェントのインストール

同じくランコマンドを使います。
コマンドのドキュメントから AWS-ConfigureAWSPackage にチェックを入れます。

コマンドのパラメータNameAmazonCloudWatchAgent と入力します。

ターゲット出力オプション は前の手順と同じです。
実行 をクリックします。

コマンド実行画面に遷移します。しばらくするとステータスが 成功 に変わります。

CloudWatchエージェントの初期設定

続いてCloudWatchエージェントの初期設定を行います。
CloudWatchエージェントはEC2からCloudWatchへ送信するメトリクスを設定ファイルに保存しています。
設定ファイルは手動で編集することも可能ですが、記載する項目が多く複雑なのでここでは設定ウィザードを使用します。

マネジメントコンソールで Systems Manager → セッションマネージャ をクリックします。
任意のWindows Serverを一台選択して セッションの開始 をクリックします。
※ご利用のブラウザでポップアップブロックが出る場合は解除してください。

このような背景が黒いPowerShellのプロンプトが開きます。

次のコマンドを実行して設定ウィザードを実行します。

cd "C:\Program Files\Amazon\AmazonCloudWatchAgent"
amazon-cloudwatch-agent-config-wizard.exe

CloudWatchエージェントの設定を対話式で行います。以下の例の通り入力してみます。
各項目のカスタマイズは公式ドキュメントを参照ください。(本エントリでは割愛します。ご了承ください。)
今回はWindowsイベントログの箇所をハイライトしています。注意して入力をします。

=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
default choice: [2]:
2
Trying to fetch the default region based on ec2 metadata...
Are you using EC2 or On-Premises hosts?
1. EC2
2. On-Premises
default choice: [1]:
1
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
1
Which port do you want StatsD daemon to listen to?
default choice: [8125]

What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s
default choice: [1]:

What is the aggregation interval for metrics collected by StatsD daemon?
1. Do not aggregate
2. 10s
3. 30s
4. 60s
default choice: [4]:

Do you have any existing CloudWatch Log Agent configuration file to import for migration?
1. yes
2. no
default choice: [2]:

Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:

Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]:

Do you want to add ec2 dimensions (ImageId, InstanceId, InstanceType, AutoScalingGroupName) into all of your metrics if the info is available?
1. yes
2. no
default choice: [1]:

Would you like to collect your metrics at high resolution (sub-minute resolution)? This enables sub-minute resolution for all metrics, but you can customize for sp
ecific metrics in the output json file.
1. 1s
2. 10s
3. 30s
4. 60s
default choice: [4]:

Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:
3
Current config as follows:
{
        "metrics": {
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "LogicalDisk": {
                                "measurement": [
                                        "% Free Space"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "Memory": {
                                "measurement": [
                                        "% Committed Bytes In Use"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "Paging File": {
                                "measurement": [
                                        "% Usage"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "PhysicalDisk": {
                                "measurement": [
                                        "% Disk Time",
                                        "Disk Write Bytes/sec",
                                        "Disk Read Bytes/sec",
                                        "Disk Writes/sec",
                                        "Disk Reads/sec"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "Processor": {
                                "measurement": [
                                        "% User Time",
                                        "% Idle Time",
                                        "% Interrupt Time"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "TCPv4": {
                                "measurement": [
                                        "Connections Established"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "TCPv6": {
                                "measurement": [
                                        "Connections Established"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "statsd": {
                                "metrics_aggregation_interval": 60,
                                "metrics_collection_interval": 10,
                                "service_address": ":8125"
                        }
                }
        }
}
Are you satisfied with the above config? Note: it can be manually customized after the wizard completes to add additional items.
1. yes
2. no
default choice: [1]:

Do you want to monitor any customized log files?
1. yes
2. no
default choice: [1]:
2
Do you want to monitor any Windows event log?
1. yes
2. no
default choice: [1]:

Windows event log name:
default choice: [System]

Do you want to monitor VERBOSE level events for Windows event log System ?
1. yes
2. no
default choice: [1]:

Do you want to monitor INFORMATION level events for Windows event log System ?
1. yes
2. no
default choice: [1]:

Do you want to monitor WARNING level events for Windows event log System ?
1. yes
2. no
default choice: [1]:

Do you want to monitor ERROR level events for Windows event log System ?
1. yes
2. no
default choice: [1]:

Do you want to monitor CRITICAL level events for Windows event log System ?
1. yes
2. no
default choice: [1]:

Log group name:
default choice: [System]

In which format do you want to store windows event to CloudWatch Logs?
1. XML: XML format in Windows Event Viewer
2. Plain Text: Legacy CloudWatch Windows Agent (SSM Plugin) Format
default choice: [1]:

Do you want to specify any additional Windows event log to monitor?
1. yes
2. no
default choice: [1]:

Windows event log name:
default choice: [System]
Security
Do you want to monitor VERBOSE level events for Windows event log Security ?
1. yes
2. no
default choice: [1]:

Do you want to monitor INFORMATION level events for Windows event log Security ?
1. yes
2. no
default choice: [1]:

Do you want to monitor WARNING level events for Windows event log Security ?
1. yes
2. no
default choice: [1]:

Do you want to monitor ERROR level events for Windows event log Security ?
1. yes
2. no
default choice: [1]:

Do you want to monitor CRITICAL level events for Windows event log Security ?
1. yes
2. no
default choice: [1]:

Log group name:
default choice: [Security]

In which format do you want to store windows event to CloudWatch Logs?
1. XML: XML format in Windows Event Viewer
2. Plain Text: Legacy CloudWatch Windows Agent (SSM Plugin) Format
default choice: [1]:

Do you want to specify any additional Windows event log to monitor?
1. yes
2. no
default choice: [1]:
2
Saved config file to config.json successfully.
Current config as follows:
{
        "logs": {
                "logs_collected": {
                        "windows_events": {
                                "collect_list": [
                                        {
                                                "event_format": "xml",
                                                "event_levels": [
                                                        "VERBOSE",
                                                        "INFORMATION",
                                                        "WARNING",
                                                        "ERROR",
                                                        "CRITICAL"
                                                ],
                                                "event_name": "System",
                                                "log_group_name": "System"
                                        },
                                        {
                                                "event_format": "xml",
                                                "event_levels": [
                                                        "VERBOSE",
                                                        "INFORMATION",
                                                        "WARNING",
                                                        "ERROR",
                                                        "CRITICAL"
                                                ],
                                                "event_name": "Security",
                                                "log_group_name": "Security"
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "LogicalDisk": {
                                "measurement": [
                                        "% Free Space"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "Memory": {
                                "measurement": [
                                        "% Committed Bytes In Use"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "Paging File": {
                                "measurement": [
                                        "% Usage"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "PhysicalDisk": {
                                "measurement": [
                                        "% Disk Time",
                                        "Disk Write Bytes/sec",
                                        "Disk Read Bytes/sec",
                                        "Disk Writes/sec",
                                        "Disk Reads/sec"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "Processor": {
                                "measurement": [
                                        "% User Time",
                                        "% Idle Time",
                                        "% Interrupt Time"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "TCPv4": {
                                "measurement": [
                                        "Connections Established"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "TCPv6": {
                                "measurement": [
                                        "Connections Established"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "statsd": {
                                "metrics_aggregation_interval": 60,
                                "metrics_collection_interval": 10,
                                "service_address": ":8125"
                        }
                }
        }
}
Please check the above content of the config.
The config file is also located at config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:

What parameter store name do you want to use to store your config? (Use 'AmazonCloudWatch-' prefix if you use our managed AWS policy)
default choice: [AmazonCloudWatch-windows]

Trying to fetch the default region based on ec2 metadata...
Which region do you want to store the config in the parameter store?
default choice: [us-west-2]
ap-northeast-1

Which AWS credential should be used to send json config to parameter store?
1. XXXXXXXXXXXXXXXXXXXX(From SDK)
2. Other
default choice: [1]:

Successfully put config to parameter store AmazonCloudWatch-windows.
Please press Enter to exit...

Program exits now.

上の例のまま入力すると、設定値がSSMパラメータストアに「AmazonCloudWatch-Windows」という名前で格納されます。 (後ほど使いますのでメモしておいてください)

EC2にIAMロールを変更

前の手順でIAMロールを作成しました。
CloudWatchAgentAdminPolicyは設定ファイルを作成するために必要でした。
設定ファイルの作成や変更をしないEC2インスタンスはCloudWatchAgentServerPolicyを割り当てます。

  • AmazonEC2RoleforSSM
  • CloudWatchAgentServerPolicy

実際の運用では、業務サーバーと設定管理サーバーでIAMロールを別に用意することになるかと思います。

各EC2インスタンスへ適用

さて準備が終わりました。
設定を各EC2インスタンスへ適用していきます。
ここでもランコマンドを使います。
コマンドのドキュメントから AmazonCloudWatch-ManageAgent にチェックを入れます。

コマンドのパラメータOptional Configuration Location にSSMパラメータストアに格納した設定値を入力します。

ターゲット出力オプション は前の手順と同じです。
実行 をクリックします。

しばらくすると、コマンドのステータスが成功に変わります。

メトリクスフィルタの作成

EC2インスタンスへの適用が完了するとCloudWatch Logsにイベントログが格納されてきます。
マネジメントコンソールから CloudWatch → ログ をクリックします。
ロググループに「System」や「Security」が追加されています。
Security 行のフィルタ列 フィルタ をクリックします。

メトリクスフィルタはログのなかから特定文字列をフィルターし、メトリクスやアラームで可視化するための設定です。
早速 メトリクスフィルタの追加 をクリックします。

フィルタパターン に以下の文字列を入力します。

"<EventID>4624</EventID>" "<Data Name='LogonType'>3</Data>"

任意のインスタンスIDを選択してパターンのテストをしてみます。
問題が無ければ メトリクスの割当て をクリックします。

以下の画面例を参考に値を入れます。
今回のメトリクス名は「Windows-Logon-Success」としました。
そうです。前の画面でフィルタパターンに入力した文字列はRDPでのログオンを示しています。
フィルタの作成 をクリックします。

メトリクスフィルタ追加

同じ要領で以下のフィルタパターンを作ります。

"<EventID>4625</EventID>" "<Data Name='LogonType'>3</Data>"

メトリクス名は「Windows-Logon-Fail」としておきます。

アラームの作成

作成したメトリクスフィルタの横にある アラームの作成 をクリックします。

しきい値や間隔などを運用要件に合わせて入力していきます。
入力例を貼っておきます。

確認

CloudWatchのメトリクスに作成したメトリクスが表示されていると思います。

CloudWatchのアラームに作成したメトリクスが表示されていると思います。

主なセキュリティイベントログ

アカウント関連の主なイベントIDを記載します。
他にもプロセスやファイルシステムなど監視すべきイベントはあると思いますが、詳細は セキュリティの監視と攻撃検出 を参照ください。

イベントログ メトリクスフィルタ 備考
ネットワーク経由のログオン成功 "<EventID>4624</EventID>" "<Data Name='LogonType'>3</Data>"
ネットワーク経由のログオン失敗 "<EventID>4625</EventID>" "<Data Name='LogonType'>3</Data>"
オブジェクトに対するハンドル要求 "<EventID>4625</EventID>" "<Data Name='ObjectName'<C:\Documents\大切なファイル</Data>" 機密性の高い重要なオブジェクトへのアクセスをチェック
ユーザーアカウント作成 "<EventID>4720</EventID>"
ユーザーアカウントパスワード変更 "<EventID>4723</EventID>"
ユーザーアカウントパスワードリセット "<EventID>4724</EventID>"
ユーザーアカウント無効化 "<EventID>4725</EventID>"
ユーザーアカウント削除 "<EventID>4726</EventID>"
ユーザーアカウントロック "<EventID>4740</EventID>" パスワード連続失敗など
ローカルグループにメンバーが追加 "<EventID>4732</EventID>" "<Data Name='TargetUserName'>Administrators</Data>" Administratorsグループに予期しないメンバーが追加などをチェック
新しいログオンに特権が割り当て "<EventID>4672</EventID>"

参考

イベントログの詳細についてはマイクロソフト公式の ログインの監査 を参照ください。