さまざまな方法でEC2に接続して、各接続方法ごとにCloudTrailのイベント履歴やイベントレコードを比較してみた

さまざまな方法でEC2に接続して、各接続方法ごとにCloudTrailのイベント履歴やイベントレコードを比較してみます。EC2に接続した際に発火するイベントの種類や内容を把握しておくと、EC2の不具合時に調査する手掛かりとして使えます。
2023.09.08

はじめに

こんにちは、おのやんです。

みなさん、EC2インスタンスへ接続した際に、接続方法によってどんなイベント履歴が取れるのか気になりませんか?私はものすごぉ〜く気になります。

EC2に接続した際に発火するイベントや、イベント履歴に書かれている内容を把握しておくと、EC2が不具合などを起こした時に調査する手掛かりとして使えます。ということで、今回はEC2への各種接続方法ごとに、CloudTrailのイベント履歴やイベントレコードをまとめたいと思います。

今回検証する接続方法

今回は、EC2インスタンスのOS、操作対象、接続方法の3つの条件を変えて、それぞれ検証していきます。

なお、今回はLinuxインスタンスのAMIはAmazon Linux 2023 AMI 2023.1.20230825.0 x86_64 HVM kernel-6.1

Windows ServerのAMIはMicrosoft Windows Server 2022 Full Locale English AMI provided by Amazonとなっています。

今回検証したEC2インスタンスOSと接続方法は、それぞれ以下の通りです。

番号 EC2インスタンスのOS 操作対象 接続方法
1 Linux ローカルPC SSH接続
2 Linux マネジメントコンソール Session Manager
3 Linux マネジメントコンソール Instance Connect(Endpointなし)
4 Linux マネジメントコンソール Instance Connect(Endpointあり)
5 Linux AWS CLI Session Manager
6 Linux AWS CLI instance Connect(Endpointなし)
7 Linux AWS CLI instance Connect(Endpointあり)
8 Windows マネジメントコンソール Session Manager
9 Windows マネジメントコンソール Fleet Manager
10 Windows AWS CLI Instance Connect

CloudTrailイベント履歴の取得方法

今回は、PythonのライブラリであるBoto3でコードを実行します。正常に処理が実行されれば、そのレスポンスとして辞書型データに加工されたイベント履歴が返ってきます。

なお、条件によってはEC2インスタンスを変えているので、ec2_instance_idは都度適切な値に書き直す必要があります。また、AWS CLIのプロファイル情報は適切に設定できているものとします。

import boto3

ec2_instance_id = "i-0f..."
aws_region = "ap-northeast-1"

session = boto3.Session(profile_name="get-event-history", region_name=aws_region)
cloudtrail_client = session.client("cloudtrail")

response = cloudtrail_client.lookup_events(
    LookupAttributes=[
        {"AttributeKey": "ReadOnly", "AttributeValue": "false"},
    ],
    MaxResults=10,
)

events = response.get("Events", [])
for event in events:
    print(event)
    print("\n")

なお、実際にこちらのコードを実行した場合には、複数のイベント履歴がダァーーっと表示されます。そのため、EC2インスタンス接続時のイベントをまとめる際には、コードを複数回実行して接続時刻とイベント発火時刻が同じものを選定しています。

CloudTrailイベント履歴の取得方法に関する詳しい内容はこちらにまとめました。よければ参考にしてください。

1. LinuxインスタンスにローカルPCからSSH接続する場合

LinuxインスタンスにローカルPCからSSH接続する場合、CloudTrailのイベント履歴には記録されません。なぜなら、SSH接続はAWSのAPIとは関係ないからです。

何回かBoto3のコードを実行したのですが、SSH接続したタイミングに記録されたイベントは見られませんでした。マネジメントコンソール上でもイベントは記録されませんでした。

こちらは、AWSのドキュメントを見てもらえれば分かると思います。

これらのイベントは、AWS Management Console、AWS Command Line Interface、AWS の SDK および API を通じて行われたアクティビティをキャプチャします。

自明なことではありますが、LinuxインスタンスにSSH接続するのはAWS固有の操作ではありません。そのためCloudTrailの履歴にも記録されません。

2. Linuxインスタンスにマネジメントコンソール上のSession Managerで接続する場合

Linuxインスタンスにマネジメントコンソール上のSession Managerで接続した場合、CloudTrailイベント履歴からは StartSession イベントが取得されます。

StartSessionイベントに関しては、APIのリファレンスに記述があります。

Initiates a connection to a target (for example, a managed node) for a Session Manager session. Returns a URL and token that can be used to open a WebSocket connection for sending input and receiving outputs.

セッションマネージャーセッションのターゲット(管理ノードなど)への接続を開始します。入力の送信と出力の受信のために WebSocket 接続を開くために使用できる URL とトークンを返します。(DeepLにて翻訳)

ここでいうターゲットとはEC2インスタンスのことですね。マネジメントコンソール上のSession Managerが、EC2インスタンスへ接続を開始する時に実行されるAPIのようです。

イベント履歴は、Pythonの辞書型データに加工されて取得できます。イベントに関する情報が記述されているほか、実行したユーザーなども読み取れます。

StartSession

{
    "EventId": "b243ee4a-...",
    "EventName": "StartSession",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,4,14,56,4, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "cm...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "attributes": {
                    "creationDate": "2023-09-04T05: 54: 51Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-09-04T05: 56: 04Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "StartSession",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "AWS Internal",
        "requestParameters": {
            "target": "i-02..."
        },
        "responseElements": {
            "sessionId": "cm...",
            "tokenValue": "Value hidden due to security reasons.",
            "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..."
        },
        "requestID": "a27d...",
        "eventID": "b243...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "sessionCredentialFromConsole": "true"
    }
}

3. Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connect(Endpointなし)で接続する場合

Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connectで接続した場合、CloudTrailイベント履歴には SendSSHPublicKey イベントが記録されます。

EC2 Instance Connectは、内部でSSH接続を利用しています。具体的には、Instance Connect APIからSSHのパブリックキーがインスタンスメタデータに送信されます。

Amazon EC2 Instance Connect は、Secure Shell (SSH) を使用して Linux インスタンスに接続するシンプルで安全な方法を提供します。

EC2 Instance Connect を使用してインスタンスに接続すると、Instance Connect API から SSH パブリックキーがインスタンスメタデータにプッシュされ、60 秒間保持されます。

こちらの動作が、CloudTrailイベント履歴にも記録されたということですね。

イベント履歴は、Pythonの辞書型データに加工されて取得できます。ローカルのSSH公開鍵を、EC2インスタンスに送信していることがわかりますね。

SendSSHPublicKey

{
    "EventId": "cdc5...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,6,10,53,19, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "cm...",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-02..."
        }
    ],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm..",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "webIdFederationData": {},
                "attributes": {
                    "creationDate": "2023-09-06T01: 21: 36Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-09-06T01: 53: 19Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "SendSSHPublicKey",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "Mozilla/5.0",
        "requestParameters": {
            "instanceId": "i-02...",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "f84e...",
            "success": true
        },
        "requestID": "f84e...",
        "eventID": "cdc5...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "tlsVersion": "TLSv1.3",
            "cipherSuite": "TLS_AES_128_GCM_SHA256",
            "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com"
        },
        "sessionCredentialFromConsole": "true"
    }
}

4. Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connect(Endpointあり)で接続する場合

Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connectで接続した場合、CloudTrailイベント履歴には SendSSHPublicKey イベントとOpenTunnelイベントが記録されます。

EC2 Instance Connectは、内部でSSH接続を利用しています。具体的には、Instance Connect APIからSSHのパブリックキーがインスタンスメタデータに送信されます。

EC2 Instance Connect を使用してインスタンスに接続すると、Instance Connect API から SSH パブリックキーがインスタンスメタデータにプッシュされ、60 秒間保持されます。

また、AWSサービスとEC2インスタンスとの間にOpenTunnelイベントでWebSocket接続を確立します。 こちらの動作が、CloudTrailイベント履歴にも記録されたということですね。

イベント履歴は、Pythonの辞書型データに加工されて取得できます。ローカルのSSH公開鍵を、EC2インスタンスに送信していることがわかりますね。

SendSSHPublicKey

{
    "EventId": "a0a9...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,16,52,18, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "username",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-0d75..."
        }
    ],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:username",
            "arn": "arn:aws:sts::1234...:assumed-role/username/username",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam::1234...:role/username",
                    "accountId": "1234...",
                    "userName": "username"
                },
                "webIdFederationData": {},
                "attributes": {
                    "creationDate": "2023-10-12T06:53:19Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-10-12T07:52:18Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "SendSSHPublicKey",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
        "requestParameters": {
            "instanceId": "i-0d75...",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "ee95e...",
            "success": true
        },
        "requestID": "ee95e...",
        "eventID": "a0a9...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "tlsVersion": "TLSv1.3",
            "cipherSuite": "TLS_AES_128_GCM_SHA256",
            "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com"
        },
        "sessionCredentialFromConsole": "true"
    }',
}

OpenTunnel

{
    "EventId": "9947...",
    "EventName": "OpenTunnel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,16,52,18, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "username",
    "Resources": [],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:username",
            "arn": "arn:aws:sts::1234...:assumed-role/username/username",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "userName": ""
        },
        "eventTime": "2023-10-12T07:52:18Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "OpenTunnel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
        "requestParameters": {
            "instanceConnectEndpointId": "eice-0c78...",
            "maxTunnelDuration": "3600",
            "remotePort": "22",
            "privateIpAddress": "10..."
        },
        "responseElements": null,
        "requestID": "bd7b...",
        "eventID": "9947...",
        "readOnly": false,
        "resources": [
            {
                "accountId": "1234...",
                "type": "AWS::EC2::InstanceConnectEndpoint",
                "ARN": "arn:aws:ec2:ap-northeast-1:1234...:instance-connect-endpoint/eice-0c78..."
            }
        ],
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management"
    }',
}

5. LinuxインスタンスにAWS CLIのSession Managerで接続する場合

LinuxインスタンスにAWS CLIのSession Managerで接続した場合、CloudTrailイベント履歴にはStartSessionイベント、CreateDataChannelイベント、OpenDataChannelイベントが記録されます。

こちらは、ssmmessages:CreateDataChannelssmmessages:OpenDataChannelの言及があるこちらのリファレンスから読み取れます。

このエンドポイントは、クラウド内の Session Manager サービスでセッションチャネルを作成および削除するために必要です。

推測ですが、AWS CLIから接続する際には、マネジメントコンソールがやってくれていたCreateDataChannelOpenDataChannelもAWS CLIが実行すると考えています。マネジメントコンソールからSessionManagerを使用するときと比べて、やることが多いのかもしれません。

AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのSession Manager設定は済んでいるものとします。

$ aws ssm start-session --target i-03... --region ap-northeast-1 --profile onoyan

イベント履歴は、Pythonの辞書型データに加工されて取得できます。

StartSession

{
    "EventId": "fe52...",
    "EventName": "StartSession",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,16,50,54, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "botocore-session-16...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../botocore-session-16...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "attributes": {
                    "creationDate": "2023-09-07T07: 18: 26Z",
                    "mfaAuthenticated": "false"
                }
            }
        },
        "eventTime": "2023-09-07T07: 50: 54Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "StartSession",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ssm.start-session",
        "requestParameters": {
            "target": "i-03..."
        },
        "responseElements": {
            "sessionId": "botocore-session-16...",
            "tokenValue": "Value hidden due to security reasons.",
            "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..."
        },
        "requestID": "9c0b...",
        "eventID": "fe52...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "tlsVersion": "TLSv1.2",
            "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
            "clientProvidedHostHeader": "ssm.ap-northeast-1.amazonaws.com"
        }
    }
}

CreateDataChannel

{
    "EventId": "cfd4...",
    "EventName": "CreateDataChannel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,16,50,54, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "i-03...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/AmazonSSMManagedInstanceCore/i-03...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/AmazonSSMManagedInstanceCore",
                    "accountId": "1234...",
                    "userName": "AmazonSSMManagedInstanceCore"
                },
                "attributes": {
                    "creationDate": "2023-09-07T07: 41: 39Z",
                    "mfaAuthenticated": "false"
                },
                "ec2RoleDelivery": "2.0"
            }
        },
        "eventTime": "2023-09-07T07: 50: 54Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "CreateDataChannel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "13...",
        "userAgent": "Go-http-client/1.1",
        "requestParameters": {
            "messageSchemaVersion": "1.0",
            "requestId": "11fb...",
            "sessionId": "botocore-session-16...",
            "clientId": ""
        },
        "responseElements": {
            "messageSchemaVersion": "1.0",
            "tokenValue": "Value hidden due to security reasons."
        },
        "requestID": "e209...",
        "eventID": "cfd4...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "clientProvidedHostHeader": "ssmmessages.ap-northeast-1.amazonaws.com"
        }
    }
}

OpenDataChannel

{
    "EventId": "6eda...",
    "EventName": "OpenDataChannel",
    "ReadOnly": "false",
    "EventTime": datetime.datetime(2023,9,7,16,50,56, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "accountId": "1234..."
        },
        "eventTime": "2023-09-07T07: 50: 56Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "OpenDataChannel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "ssm.amazonaws.com",
        "requestParameters": {
            "sessionId": "botocore-session-16..."
        },
        "responseElements": null,
        "requestID": "cf3f...",
        "eventID": "6edf...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management"
    }
}

6. LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endopintなし)で接続する場合

LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endpointなし)で接続した場合、CloudTrailイベント履歴にはSendSSHPublicKeyイベントが記録されます。

EC2 Instance Connectは、裏でSSH接続を行っていました。そのため、SendSSHPublicKeyイベントが記録されています。

AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのInstance Connect設定は済んでいるものとします。

$ aws ec2-instance-connect ssh --instance-id i-0a... --connection-type eice --profile onoyan

イベント履歴は、Pythonの辞書型データに加工されて取得できます。

SendSSHPublicKey

{
    "EventId": "6111...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,15,58,49, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "username",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-0d75..."
        }
    ],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:username",
            "arn": "arn:aws:sts::1234...:assumed-role/username/username",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam::1234...:role/username",
                    "accountId": "1234...",
                    "userName": "username"
                },
                "webIdFederationData": {},
                "attributes": {
                    "creationDate": "2023-10-12T06:53:19Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-10-12T06:58:49Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "SendSSHPublicKey",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
        "requestParameters": {
            "instanceId": "i-0d75...",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "1c3f...",
            "success": true
        },
        "requestID": "1c3fe...",
        "eventID": "6111...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "tlsVersion": "TLSv1.3",
            "cipherSuite": "TLS_AES_128_GCM_SHA256",
            "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com"
        },
        "sessionCredentialFromConsole": "true"
    }',
}

7. LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endopintあり)で接続する場合

LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endpointなし)で接続した場合、CloudTrailイベント履歴にはSendSSHPublicKeyイベントとOpenTunnelイベントが記録されます。

OpenTunnelに関しては、こちらのリファレンスに記載があります。

SSH を使用して Linux インスタンスに接続し、open-tunnel コマンドを使用してプライベートトンネルを確立できます。open-tunnel はシングル接続またはマルチ接続モードで使用できます

EC2 Instance Connectは、裏でSSH接続を行っていました。そのため、SendSSHPublicKeyイベントが記録されています。今回はそれに加えてAWS CLIの処理も含まれています。そのため、こちらのopen-tunnelコマンドがイベント履歴にも記録されているのだと思われます。

AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのInstance Connect設定は済んでいるものとします。

$ aws ec2-instance-connect ssh --instance-id i-0a... --connection-type eice --profile onoyan

イベント履歴は、Pythonの辞書型データに加工されて取得できます。

SendSSHPublicKey

{
    "EventId": "4fad...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,16,33,17, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-16...",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-0a..."
        }
    ],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../botocore-session-16...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "webIdFederationData": {},
                "attributes": {
                    "creationDate": "2023-09-07T07: 18: 26Z",
                    "mfaAuthenticated": "false"
                }
            }
        },
        "eventTime": "2023-09-07T07: 33: 17Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "SendSSHPublicKey",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ec2-instance-connect.ssh",
        "requestParameters": {
            "instanceId": "i-0a...",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AA..."
        },
        "responseElements": {
            "requestId": "5298...",
            "success": true
        },
        "requestID": "5298...",
        "eventID": "4fad...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "tlsVersion": "TLSv1.3",
            "cipherSuite": "TLS_AES_128_GCM_SHA256",
            "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com"
        }
    }
}

OpenTunnel

{
    "EventId": "e966...",
    "EventName": "OpenTunnel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,16,33,18, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-16...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../botocore-session-16...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "userName": ""
        },
        "eventTime": "2023-09-07T07: 33: 18Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "OpenTunnel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ec2-instance-connect.open-tunnel",
        "requestParameters": {
            "instanceConnectEndpointId": "eice-0e...",
            "maxTunnelDuration": "3600",
            "remotePort": "1",
            "privateIpAddress": "10..."
        },
        "responseElements": null,
        "requestID": "3004...",
        "eventID": "e966...",
        "readOnly": false,
        "resources": [
            {
                "accountId": "1234...",
                "type": "AWS: :EC2: :InstanceConnectEndpoint",
                "ARN": "arn:aws:ec2:ap-northeast-1: 1234...:instance-connect-endpoint/eice-0e..."
            }
        ],
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management"
    }
}

8. Windowsインスタンスにマネジメントコンソール上のSession Managerで接続する場合

Windowsインスタンスにマネジメントコンソール上のSession Managerで接続した場合、CloudTrailイベント履歴にはStartSessionイベント、CreateDataChannelイベント、OpenDataChannelイベントが記録されます。

こちらは、上述したSession Managerでのイベント発火と同じくStartSession, CreateDataChannel, OpenDataChannelが記録されていますね。

イベント履歴は、Pythonの辞書型データに加工されて取得できます。LinuxインスタンスにAWS CLIのSession Managerで接続した場合と同じイベントが発火しています。

StartSession

{
    "EventId": "d9da...",
    "EventName": "StartSession",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,17,9,52, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "cm...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../cm...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "attributes": {
                    "creationDate": "2023-09-07T07: 36: 11Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-09-07T08: 09: 52Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "StartSession",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "AWS Internal",
        "requestParameters": {
            "target": "i-0f..."
        },
        "responseElements": {
            "sessionId": "cm...",
            "tokenValue": "Value hidden due to security reasons.",
            "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..."
        },
        "requestID": "9cc8...",
        "eventID": "d9da...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "sessionCredentialFromConsole": "true"
    }
}

CreateDataChannel

{
    "EventId": "d7cb...",
    "EventName": "CreateDataChannel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,17,9,54, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "i-0f...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/AmazonSSMManagedInstanceCore/i-0f...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/AmazonSSMManagedInstanceCore",
                    "accountId": "1234...",
                    "userName": "AmazonSSMManagedInstanceCore"
                },
                "attributes": {
                    "creationDate": "2023-09-07T08: 05: 55Z",
                    "mfaAuthenticated": "false"
                },
                "ec2RoleDelivery": "2.0"
            }
        },
        "eventTime": "2023-09-07T08: 09: 54Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "CreateDataChannel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "Go-http-client/1.1",
        "requestParameters": {
            "messageSchemaVersion": "1.0",
            "requestId": "a4e...",
            "sessionId": "cm...",
            "clientId": ""
        },
        "responseElements": {
            "messageSchemaVersion": "1.0",
            "tokenValue": "Value hidden due to security reasons."
        },
        "requestID": "155b...",
        "eventID": "d7cb...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "tlsDetails": {
            "clientProvidedHostHeader": "ssmmessages.ap-northeast-1.amazonaws.com"
        }
    }
}

OpenDataChannel

{
    "EventId": "a8a9...",
    "EventName": "OpenDataChannel",
    "ReadOnly": "false",
    "EventTime": datetime.datetime(2023,9,7,17,9,52, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "accountId": "1234..."
        },
        "eventTime": "2023-09-07T08: 09: 52Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "OpenDataChannel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "ssm.amazonaws.com",
        "requestParameters": {
            "sessionId": "cm..."
        },
        "responseElements": null,
        "requestID": "cbce...",
        "eventID": "a8a9...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management"
    }
}

9. Windowsインスタンスにマネジメントコンソール上のFleet Managerで接続する場合

Windowsインスタンスにマネジメントコンソール上のEC2 Instance Connectで接続した場合、CloudTrailイベント履歴には StartSessionStartConnectionOpenDataChannelCreateDataChannelと、さまざまなイベントが乱立しています。

これまでの接続方法と比べると、多くのイベントが続けて実行されるのが特徴的です。Fleet ManagerではWindowsのGUIデスクトップにマネコンからリモートで接続できるため、EC2内で処理されるイベントも多くなっていますね。

それでも、イベント自体は上述のSession Managerで見られたような処理が実行されています。Fleet Manager自体がマネジメントコンソール上のSystems Managerで利用可能なので、裏側ではSession Managerと同じような処理を行っていると考えられます。

イベント履歴は、Pythonの辞書型データに加工されて取得できます。

StartSession

{
    "EventId": "c652...",
    "EventName": "StartSession",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,10,59,24, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "cm...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "attributes": {
                    "creationDate": "2023-09-07T01: 04: 06Z",
                    "mfaAuthenticated": "true"
                }
            },
            "invokedBy": "ssm-guiconnect.amazonaws.com"
        },
        "eventTime": "2023-09-07T01: 59: 24Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "StartSession",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "ssm-guiconnect.amazonaws.com",
        "userAgent": "AWS Internal",
        "requestParameters": {
            "target": "i-07...",
            "documentName": "AWS-StartPortForwardingSession",
            "reason": "Used for SSM Fleet Manager Remote Desktop",
            "parameters": {
                "localPortNumber": [
                    "9"
                ],
                "portNumber": [
                    "3"
                ]
            }
        },
        "responseElements": {
            "sessionId": "cm...",
            "tokenValue": "Value hidden due to security reasons.",
            "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..."
        },
        "requestID": "e4a5...",
        "eventID": "c652...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management",
        "sessionCredentialFromConsole": "true"
    }
}

StartConnection

{
    "EventId": "2921...",
    "EventName": "StartConnection",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA.",
    "EventTime": datetime.datetime(2023,9,7,10,59,24, tzinfo=tzlocal()),
    "EventSource": "ssm-guiconnect.amazonaws.com",
    "Username": "cm...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/cm...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/cm...",
                    "accountId": "1234...",
                    "userName": "cm..."
                },
                "webIdFederationData": {},
                "attributes": {
                    "creationDate": "2023-09-07T01: 04: 06Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-09-07T01: 59: 24Z",
        "eventSource": "ssm-guiconnect.amazonaws.com",
        "eventName": "StartConnection",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "aws-internal/3 aws-sdk-java/1.12.479 Linux/5.10.186-157.751.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.372-b08 java/1.8.0_372 vendor/Oracle_Corporation cfg/retry-mode/standard",
        "requestParameters": {
            "ConnectionParameters": {
                "SupportGraphicsPipeline": true
            },
            "AuthType": "Credentials",
            "Protocol": "RDP",
            "ConnectionType": "SessionManager",
            "InstanceId": "i-07"
        },
        "responseElements": {
            "ConnectionArn": "arn:aws:ssm-guiconnect:ap-northeast-1: 1234...:connection/1e9d...",
            "ConnectionKey": "e1a8...",
            "ClientToken": "c559...",
            "requestId": "9556..."
        },
        "requestID": "9556...",
        "eventID": "2921...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234",
        "eventCategory": "Management"
    }
}

OpenDataChannel

{
    "EventId": "707a...",
    "EventName": "OpenDataChannel",
    "ReadOnly": "false",
    "EventTime": datetime.datetime(2023,9,7,10,59,25, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "accountId": "1234"
        },
        "eventTime": "2023-09-07T01: 59: 25Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "OpenDataChannel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "AWS Internal",
        "userAgent": "ssm.amazonaws.com",
        "requestParameters": {
            "sessionId": "cm..."
        },
        "responseElements": null,
        "requestID": "9f09...",
        "eventID": "707a...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "eventCategory": "Management"
    }
}

CreateDataChannel

{
    "EventId": "dd82...",
    "EventName": "CreateDataChannel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,7,10,59,26, tzinfo=tzlocal()),
    "EventSource": "ssm.amazonaws.com",
    "Username": "i-07...",
    "Resources": [],
    "CloudTrailEvent": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts: : 1234...:assumed-role/AmazonSSMManagedInstanceCore/i-07...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "sessionContext": {
                "sessionIssuer": {
                    "type": "Role",
                    "principalId": "AROA...",
                    "arn": "arn:aws:iam: : 1234...:role/AmazonSSMManagedInstanceCore",
                    "accountId": "1234...",
                    "userName": "AmazonSSMManagedInstanceCore"
                },
                "attributes": {
                    "creationDate": "2023-09-07T01: 48: 52Z",
                    "mfaAuthenticated": "false"
                },
                "ec2RoleDelivery": "2.0"
            }
        },
        "eventTime": "2023-09-07T01: 59: 26Z",
        "eventSource": "ssm.amazonaws.com",
        "eventName": "CreateDataChannel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10...",
        "userAgent": "Go-http-client/1.1",
        "requestParameters": {
            "messageSchemaVersion": "1.0",
            "requestId": "59a2...",
            "sessionId": "cm...",
            "clientId": ""
        },
        "responseElements": {
            "messageSchemaVersion": "1.0",
            "tokenValue": "Value hidden due to security reasons."
        },
        "requestID": "ae7f...",
        "eventID": "dd82...",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "1234...",
        "vpcEndpointId": "vpce-03...",
        "eventCategory": "Management",
        "tlsDetails": {
            "clientProvidedHostHeader": "ssmmessages.ap-northeast-1.amazonaws.com"
        }
    }
}

10. WindowsインスタンスにAWS CLIのInstance Connectで接続する場合

WindowsインスタンスにAWS CLIのInstance Connectで接続した場合、CloudTrailイベント履歴にはOpenTunnelイベントが取得されます。

「5. LinuxインスタンスにAWS CLIのEC2 Instance Connectで接続する場合」で述べたように、今回はAWS CLIのopen-tunnelコマンドがイベント履歴に記録されているのだと思われます。

また、LinuxインスタンスにInstance Connectで接続する際には、裏側でSSH接続を行っていました。しかし今回はWindowsインスタンスに接続するため、裏側ではRDP接続の処理が走ります。こういった流れがあって、SendSSHPublicKeyのようなイベントは記録されない、ということが読み取れます。

AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのInstance Connect設定は済んでいるものとします。

$ aws ec2-instance-connect open-tunnel \
--instance-connect-endpoint-id eice-06... \
--private-ip-address 10.0... \ 
--local-port 13389 \
--remote-port 3389 \
--profile onoyan

イベント履歴は、Pythonの辞書型データに加工されて取得できます。

OpenTunnel

{
    "EventId": "da6f...",
    "EventName": "OpenTunnel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,9,19,14,12,7, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-1695...",
    "Resources": [],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...",
            "arn": "arn:aws:sts::2459...:assumed-role/cm-onoyama.shodai/botocore-session-1695...",
            "accountId": "2459...",
            "accessKeyId": "ASIA...",
            "userName": ""
        },
        "eventTime": "2023-09-19T05:12:07Z",
        "eventSource": "ec2-instance-connect.amazonaws.com",
        "eventName": "OpenTunnel",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "10.10...",
        "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ec2-instance-connect.open-tunnel",
        "requestParameters": {
            "instanceConnectEndpointId": "eice-06...",
            "maxTunnelDuration": "3600",
            "remotePort": "3389",
            "privateIpAddress": "10.10..."
        },
        "responseElements": null,
        "requestID": "909e...",
        "eventID": "da6f...",
        "readOnly": false,
        "resources": [
            {
                "accountId": "2459...",
                "type": "AWS::EC2::InstanceConnectEndpoint",
                "ARN": "arn:aws:ec2:ap-northeast-1:2459...:instance-connect-endpoint/eice-06..."
            }
        ],
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "2459...",
        "eventCategory": "Management"
    }',
}

さいごに

EC2の接続方法は他にもありますので、今回の検証結果には検証の余地はあります。

それでもEC2への接続方法によって、記録されるイベント履歴が変わることが分かりました。AWS CLIとマネジメントコンソールとでは、必要なAPIが異なります。また、Session ManagerやInstance Connectでは接続の仕組みも違ってきます。

EC2に何かしらの不具合が生じて、ClouTrailのイベント履歴を見る必要が出てきた際は、これらのイベントを重点的に探すといいでしょう。効率的に原因を特定できるかもしれません。では!