Session Manager のログ保存機能
Session Manager記事連投しております。第3弾です。 Session Managerコマンドの操作ログを残してくれる便利な機能があるので、その使い方を見ていきます。
操作ログはS3バケットまたはCloudWatch Logsに保存できるのですが、今回はS3上に保存する方法を紹介します。
事前準備
ログ保存を行うS3バケットを準備します。
ログ保存S3バケットの準備
S3バケットを作成します。


暗号化はAWS管理のキーで設定しておきます。

その他の設定はデフォルトでバケット作成します。

できました。

バケットポリシーの設定
せっかくなので、バケットにオブジェクトを格納できるアクセス元を限定します。
とりあえずログが保存できれば良いって方は、バケットポリシーは何もせず、この部分を読み飛ばして進めてください。
Session Managerのログは、EC2のSSM Agentから送信されるので、EC2に設定するIAMロールからのみPutObjectできるように設定します。

ただし、この制限は完璧ではありません。 EC2のIAM Roleから操作許可されるため、SSM Agentだけでなく、EC2内のAWS CLIなどでバケット上の手動更新が可能になるからです。 バケットのバージョニングやオブジェクトロックを適用して更なる改ざん防止策は可能かと思います。 バケットポリシーでログ書き込みを限定するには現状この方法が良いようです。(何かほかに良い方法あればご指摘ください)
では実際にバケットポリシーを設定していきます。 実は自アカウント内のIAM Roleのみアクセスを許可する。という設定はけっこう面倒です(苦笑)
参考:How to Restrict Amazon S3 Bucket Access to a Specific IAM Role | AWS Security Blog
aws iam get-role --role-name SessionManagerRole(ロール名)というコマンドで取得した「RoleId」の文字列をバケットポリシーで設定する必要があります。
(CLIの実行が必要です・・)

取得した「RoleId」をStringNotLike(このRoleIdじゃ無ければ)で指定し、Denyとしています。

以下のように記載しました。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "s3:Put*", "Resource": [ "arn:aws:s3:::sessionmanager-log-20200610", "arn:aws:s3:::sessionmanager-log-20200610/*" ], "Condition": { "StringNotLike": { "aws:userId": [ "AROAQQJYPEOBCXXXXXXXX:*", "[AWSアカウントID]" ] } } } ] }
- [AWSアカウントID]はアカウントごとに異なりますのでEC2に設定されるRoleに合わせて変更してください。
- 前回の記事で作成した「SessionManagerRole」というRoleから許可しています。
- Actionは(全アクション)でDenyしても良いのですが、にしてRoleIdなどにミスがあるとrootユーザー以外バケットポリシーすら変更できなくなるため、今回はこうしています。
IAM Role変更
EC2に設定するIAM Roleには、作成したバケットにログを格納する権限が必要になります。 「SessionManagerRole」に追加でポリシーを設定します。
まずは追加用のIAMポリシーを作成します。 IAMポリシーの作成方法詳細はここでは割愛しますので、ポリシー内容を参考にしてもらえればと思います。
ポリシー内容はAWS公式ドキュメントを参考に、S3ログ格納に必要な部分を設定します。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetEncryptionConfiguration" ], "Resource": "*" }, { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::sessionmanager-log-20200610/*" } ] }
- Resourceで指定しているバケット名は環境に応じて変更が必要ですので注意してください。
ポリシー名は「PutSSMLogPolicy」とします。

作成したIAMポリシーを、EC2に設定するIAM Roleに追加でアタッチすればOKです。

ログ設定有効
Systems Managerの画面から設定します。
セッションマネージャー>設定>編集の順でクリックします。

S3バケットにチェックを入れ、先ほど作成したS3バケットをリストから選択し、保存すればOKです。

接続&ログ確認
これでログが残るはず!接続してみます。今回はブラウザ(EC2の画面から)で。

適当にコマンドを打ってexitで終了します。

Session Managerの画面へ行き、セッション履歴のタブをクリックします。
すると、セッション履歴(=接続履歴)が表示され、出力場所に「Amazon S3」ボタンが表示されているのでそれをクリックします。

S3上にログファイルができていることが確認できます。 ダウンロードして中身を確認してみましょう。

一部見にくいところもありますが、実行したコマンドがきちんと表示されていますね!

ちなみに、バケットポリシーでput*を拒否しているため、ログインしているIAMユーザーでlogファイルを更新しようとすると以下の通りエラーとなります。

まとめと注意点
いかがでしたでしょうか?基本的には、ログ格納用のS3バケット(CloudWatchでもOK)を用意して、EC2(IAM Role)にログ格納の権限を付与してあげればOKです。
1点注意なのは、ログ転送はリアルタイムではないという点です。 セッション終了時にログを転送する仕組みとなっているため、shutdownコマンドでOS停止したり、ブラウザを閉じて終了した場合は、ログは転送されません。
このような終了をすると、以下のように出力場所が表示されず、ログファイルの確認ができません。

今後、リアルタイムに転送されるようアップデートされることを願います・・