fu3ak1's tech days

何事もシンプルに。主にAWS関連の記事を書いています

Session Manager のログ保存機能

Session Manager記事連投しております。第3弾です。 Session Managerコマンドの操作ログを残してくれる便利な機能があるので、その使い方を見ていきます。

操作ログはS3バケットまたはCloudWatch Logsに保存できるのですが、今回はS3上に保存する方法を紹介します。

事前準備

ログ保存を行うS3バケットを準備します。

ログ保存S3バケットの準備

S3バケットを作成します。

f:id:fu3ak1:20200610225636p:plain

f:id:fu3ak1:20200610225722p:plain

暗号化はAWS管理のキーで設定しておきます。 f:id:fu3ak1:20200610225806p:plain

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

f:id:fu3ak1:20200610225924p:plain

できました。 f:id:fu3ak1:20200610230009p:plain

バケットポリシーの設定

せっかくなので、バケットにオブジェクトを格納できるアクセス元を限定します。

とりあえずログが保存できれば良いって方は、バケットポリシーは何もせず、この部分を読み飛ばして進めてください。

Session Managerのログは、EC2のSSM Agentから送信されるので、EC2に設定するIAMロールからのみPutObjectできるように設定します。

f:id:fu3ak1:20200610230915p:plain

ただし、この制限は完璧ではありません。 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の実行が必要です・・)

f:id:fu3ak1:20200612000405p:plain

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

f:id:fu3ak1:20200612002826p:plain

以下のように記載しました。

{
    "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ログ格納に必要な部分を設定します。 f:id:fu3ak1:20200611232102p:plain

{
    "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」とします。 f:id:fu3ak1:20200611232255p:plain

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

f:id:fu3ak1:20200611230529p:plain

ログ設定有効

Systems Managerの画面から設定します。

セッションマネージャー>設定>編集の順でクリックします。

f:id:fu3ak1:20200611224836p:plain

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

f:id:fu3ak1:20200611225127p:plain

接続&ログ確認

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

f:id:fu3ak1:20200611232636p:plain

適当にコマンドを打ってexitで終了します。 f:id:fu3ak1:20200611233006p:plain

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

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

f:id:fu3ak1:20200612001416p:plain

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

f:id:fu3ak1:20200612001639p:plain

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

f:id:fu3ak1:20200612001838p:plain

まとめと注意点

いかがでしたでしょうか?基本的には、ログ格納用のS3バケット(CloudWatchでもOK)を用意して、EC2(IAM Role)にログ格納の権限を付与してあげればOKです。

1点注意なのは、ログ転送はリアルタイムではないという点です。 セッション終了時にログを転送する仕組みとなっているため、shutdownコマンドでOS停止したり、ブラウザを閉じて終了した場合は、ログは転送されません

このような終了をすると、以下のように出力場所が表示されず、ログファイルの確認ができません。

f:id:fu3ak1:20200614001121p:plain

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