AWS Systems Manager Session Managerの利用状況をAmazon Athenaで調べる

2019.05.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

AWS Systems Manager Session Managerを利用すると、SSH/RDP を使わずに、Amazon EC2 インスタンスを管理できます。

運用の一環として

  • Session Manager の利用頻度
  • 利用者、対象インスタンスのアクセスコントロール

などを確認したいことがあります。

そのような目的のために、Amazon Athena から AWS CloudTrail に SQL を投げて調査する方法をユースケース別に紹介します。

前提

AWS 操作の証跡を残す AWS CloudTrail を有効にしてください。

また、CloudTrailが取得したログをAthenaで分析できるように、テーブルを作成してください。 テーブルの作成方法は、以下を参照ください。

AWS Systems Manager Session Manager の CloudTrail ログについて

API の種類

AWS Systems Manager Session Manager に関する API は以下があります。

調査では、これら API を利用します。

Systems Manager Session Manager のログファイルエントリ

StartSession の場合、次のような CloudTrail ログエントリが作成されます。

{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AAA:jane.doe",
        "arn": "arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe",
        "accountId": "123456789012",
        "accessKeyId": "BBB",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "true",
                "creationDate": "2019-05-03T14:56:17Z"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "CCC",
                "arn": "arn:aws:iam::123456789012:role/jane.doe",
                "accountId": "123456789012",
                "userName": "jane.doe"
            }
        }
    },
    "eventTime": "2019-05-03T15:41:58Z",
    "eventSource": "ssm.amazonaws.com",
    "eventName": "StartSession",
    "awsRegion": "eu-central-1",
    "sourceIPAddress": "1.2.3.4",
    "userAgent": "aws-internal/3 aws-sdk-java/1.11.534 Linux/4.9.137-0.1.ac.218.74.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.202-b08 java/1.8.0_202 vendor/Oracle_Corporation",
    "requestParameters": {
        "target": "i-1234"
    },
    "responseElements": {
        "sessionId": "jane.doe-0cebe29e113af220c",
        "tokenValue": "Value hidden due to security reasons.",
        "streamUrl": "Value hidden due to security reasons."
    },
    "requestID": "ca99926a-...",
    "eventID": "f832760f-...",
    "resources": [
        {
            "ARN": "arn:aws:ec2:eu-central-1:123456789012:instance/i-1234",
            "accountId": "123456789012"
        }
    ],
    "eventType": "AwsApiCall",
    "recipientAccountId": "123456789012"
}

このログエントリから以下の情報がわかります。

  • いつ(eventTime)
  • 誰が(userIdentity.arn)
  • どこから(sourceIPAddress)
  • どのインスタンスに(resources, requestParameters)
  • 何をしたのか(eventName)

ユースケース別SQL例

ここからはユースケース別にSQLを紹介します。

API 呼び出し一覧を取得

セッションマネージャー系 API の利用履歴を出力します。

SELECT eventtime,
       eventname ,
       element_at(resources, 1).arn resource_target,
       useridentity.arn,
       sourceipaddress
FROM "default"."cloudtrail_logs_table_name"
WHERE eventsource = 'ssm.amazonaws.com'
        AND eventname IN ('StartSession', 'TerminateSession', 'ResumeSession')
        AND eventtime
    BETWEEN '2019-04-01T00:00:00Z'
        AND '2019-05-01T00:00:00Z'
ORDER BY eventtime;

出力例

"eventtime","eventname","resource_target","arn","sourceipaddress"
"2019-04-03T19:27:31Z","StartSession","arn:aws:ec2:eu-central-1:123456789012:instance/i-1234","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","1.2.3.4"
"2019-04-06T08:46:42Z","StartSession","arn:aws:ec2:eu-central-1:123456789012:instance/i-9876","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","1.2.3.4"
"2019-04-20T13:03:42Z","TerminateSession","arn:aws:ssm:eu-central-1:123456789012:session/jane.doe-05864affb98807843","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","2.3.4.5"

SQL メモ

resources は struct の array です。 element_at(resources, 1) で array の1つ目の要素を抽出し、struct の 変数 arn には .arn でアクセスしています。

EC2のインスタンスIDだけがわかれば十分な場合、string 型の requestparameters を利用し、 json_extract(requestparameters, '$.target') としてください。

EC2インスタンスとユーザーのペア一覧を取得

Session Manager 利用なインスタンスを制限していたり、本番・開発といった環境によって、Session Manager 可能なユーザーを制限していることがあります。

期待通りにアクセスコントロールできていることを確認するために、 EC2 インスタンスとユーザーのペアを出力します。

SELECT element_at(resources, 1).arn resource_target,
       useridentity.arn,
       count(*) cnt
FROM "default"."cloudtrail_logs_table_name"
WHERE eventsource = 'ssm.amazonaws.com'
        AND eventname IN ('StartSession', 'TerminateSession', 'ResumeSession')
        AND eventtime
    BETWEEN '2019-04-01T00:00:00Z'
        AND '2019-04-15T00:00:00Z'
GROUP BY 1, 2

出力例

"resource_target","arn","cnt"
"arn:aws:ec2:eu-central-1:123456789012:instance/i-1234","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","2"
"arn:aws:ec2:eu-central-1:123456789012:instance/i-1234","arn:aws:iam::123456789012:assumed-role/john.smith/john.smith","1"

日別の利用頻度を取得

セッションマネージャー系 API の日別の利用数を出力します。

SELECT date_trunc('day', from_iso8601_timestamp(eventtime)) eventtime,
       count(*) cnt
FROM "default"."cloudtrail_logs_table_name"
WHERE eventsource = 'ssm.amazonaws.com'
        AND eventname IN ('StartSession', 'TerminateSession', 'ResumeSession')
        AND eventtime
    BETWEEN '2019-04-01T00:00:00Z'
        AND '2019-04-15T00:00:00Z'
GROUP BY 1
ORDER BY 1

出力例

"eventtime","cnt"
"2019-04-03 00:00:00.000 UTC","1"
"2019-04-06 00:00:00.000 UTC","4"
"2019-04-11 00:00:00.000 UTC","2"

SQL メモ

eventime は string 型のため from_iso8601_timestamp(string) 関数で timestamp 型に変換しています。 さらに、date_trunc(unit, x) 関数により、指定した unit に切り捨てています。

SELECT '2019-05-04T15:41:58Z' 
       ,from_iso8601_timestamp( '2019-05-04T15:41:58Z')
       ,date_trunc('day', from_iso8601_timestamp( '2019-05-04T15:41:58Z'))

-- SELECT 結果

2019-05-04T15:41:58Z, 2019-05-04 15:41:58.000 UTC, 2019-05-04 00:00:00.000 UTC

date_trunc 関数の unit を hour, month などにかえることで、集約の粒度を変更できます。

まとめ

AWS Systems Manager Session Manager の利用状況を調査する際のクエリパターンをまとめました。

Session Manager の運用において、リアルタイム通知とは別に、利用状況や正しくアクセスコントロールされていることを確認したい場合、今回の様なアプローチがおすすめです。

それでは。

参考