パブリックなEC2 Instance Connect(Endpoint未使用)とEC2 Instance Connect Endpointでログは変わるのか検証してみた

パブリックなEC2 Instance Connect(Endpoint未使用)とEC2 Instance Connect Endpointでログは変わるのか検証してみた

今回は、パブリックなEC2 Instance Connect(Endpoint未使用)とEC2 Instance Connect Endpointでログを比較してみます。
Clock Icon2023.10.13

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

はじめに

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

みなさん、EC2に接続する際に、パブリックなEC2 Instance Connect(Endpoint未使用)を経由するのと、EC2 Instance Connect Endpointを経由するので、アクセスログがどのように変化するのか気になりませんか?私は非常に気になります。

先日からEC2のイベントログ調査ブログを続けています。

前回のブログでは、EC2 Instance Connect Endpointを変えてイベント履歴を比較しました。しかし、そもそもInstance Connectには、Endpointを使用する接続方法と使用しない方法があります。これらを比較すると、ログの違いからEndpointの有無が把握できそうです。

ということで、今回はパブリックなEC2 Instance Connect(Endpoint未使用)とEC2 Instance Connect Endpointでログを比較してみたいと思います。

前提条件

今回使用するEC2インスタンスのスペックは以下の通りです。通常のInstance Connect接続と、Endpoint経由のInstance Connect接続をそれぞれ同一インスタンスで試します。

  • マシンイメージ: Amazon Linux 2023 AMI (ami-079cd5448deeace01 64 ビット x86)
  • インスタンスタイプ: t2.micro

またイベント履歴の取得には、こちらの記事でも紹介したPythonコードを参考にします。

import boto3

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")

AWSマネジメントコンソールから接続した場合

AWSのマネジメントコンソールを経由して、EC2 Instance Connect(Endpoint未使用)とEC2 Instance Connect Endpointに接続した際のログを、以下に示します。

EC2 Instance Connect(Endpoint未使用)

EC2 Instance Connect(Endpoint未使用) のケースでは、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"
    }',
}

EC2 Instance Connect Endpoint

EC2 Instance Connect Endpointのケースでは、OpenTunnelイベントとSendSSHPublicKeyイベントが取得できました。

{
    "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"
    }',
}
{
    "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"
    }',
}

両者の違い

AWSマネジメントコンソールから接続した場合、Endpointなしの場合とありでは検出されるイベントに違いが見られました。

具体的には、Endpointなしの場合はSendSSHPublicKey、Endpointありの場合はOpenTunnelSendSSHPublicKeyが検出されました。

こちらの違いは、以前執筆したブログ内でも紹介していますので、よければ参考にしてください。

また、両方で検出されたSendSSHPublicKeyイベント履歴には、以下の項目で違いが見られました。なお、タイムスタンプが違うのは自明なので割愛しています。

  • EventId
  • AccessKeyId
  • CloudTrailEvent.userIdentity.accessKeyId
  • CloudTrailEvent.requestParameters.sSHPublicKey
  • CloudTrailEvent.responseElements.requestId
  • CloudTrailEvent.requestID
  • CloudTrailEvent.eventID
{
    "EventId": "9515...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,5,15,37,43, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "username",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-09..."
        }
    ],
    "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-05T06:37:33Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2023-10-05T06:37:43Z",
        "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-09...",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "2202...",
            "success": true
        },
        "requestID": "2202...",
        "eventID": "9515...",
        "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"
    }',
}

EventId, CloudTrailEvent.eventID

こちらの値に関しては、こちらのドキュメントに記載があります。

eventID

各イベントを一意に識別するために CloudTrail によって生成された GUID。この値を使用して、単一のイベントを識別できます。たとえば、プライマリキーとして ID を使用し、検索可能なデータベースからログデータを取得できます。

これらの値は、イベントを一意に特定するためのIDとなっています。CloudTrailを使用してAPIの呼び出しを記録する際に、このIDを使って特定のAPIの呼び出しを追跡したり、問題が発生したときの原因を特定できます。 

今回のケースだと、そもそもイベント自体が異なるものとなっています。そのため、EventId, CloudTrailEvent.eventIDといった値に違いが出ています。

AccessKeyId, CloudTrailEvent.userIdentity.accessKeyId

こちらの値に関しては、こちらのドキュメントに記載があります。

accessKeyId

リクエストに署名するために使用された アクセスキー ID。リクエストが、一時的セキュリティ認証情報で行われた場合、これは、一時的認証情報のアクセスキー IDです。セキュリティ上の理由から、accessKeyId が存在しないか、空の文字列として表示される可能性があります。

この値は、APIが呼び出された時に、呼び出し元のユーザーのアクセスキーIDが記録されます。「一時的認証情報のアクセスキー IDです」と記載があるので、リクエストのたびにアクセスキーを生成して認証を行っていると考えられます。

CloudTrailEvent.requestParameters.sSHPublicKey

こちらの値に関しては、こちらのドキュメントに記載があります。

requestParameters

リクエストとともに送信されたパラメータ (ある場合)。これらのパラメータは、該当する AWS のサービスの API リファレンスドキュメントに記載されています。このフィールドの最大サイズは 100 KB です。この制限を超えるコンテンツは切り捨てられます。

CloudTrailEvent.requestParametersには、AWSサービスのAPI呼び出しで指定されたリクエストパラメータが含まれています。CloudTrailEvent.requestParameters.sSHPublicKeyには、AWSサービスのAPI呼び出しで指定されたSSH公開鍵が含まれています。

今回、EC2 Instance Connectを用いたEC2インスタンスへの接続では、裏で一時的なSSH鍵が生成されています。この公開鍵をEC2インスタンスに送信することで接続を可能としています。そのため、Endpointの有無に関わらず、こちらの値にも違いが見られています。

CloudTrailEvent.responseElements.requestId

こちらの値に関しては、こちらのドキュメントに記載があります。

responseElements

変更を行うアクションのレスポンスの要素 (アクションの作成、更新、削除)。アクションが状態を変更しない場合 (例: オブジェクトの取得やリストのリクエスト)、この要素は省略されます。これらのアクションは、該当する AWS のサービスの API リファレンスドキュメントに記載されています。このフィールドの最大サイズは 100 KB です。この制限を超えるコンテンツは切り捨てられます。

こちらの値は、リクエストのレスポンスに紐づくIDとなっています。API呼び出しのレスポンスが返ってきた時に、それがどのリクエスト由来のものなのかを識別できます。一般的には、レスポンスが成功した場合や、特定のAPI呼び出しに対するレスポンスにのみ存在することが多いようです。

Endpointの有無に関わらず、リクエスト自体が別々に処理され、そのレスポンスも別々に返ってきています。そのため、CloudTrailEvent.responseElements.requestIdの項目に違いが出ています。

CloudTrailEvent.requestID

こちらの値に関しては、こちらのドキュメントに記載があります。

requestID

リクエストを識別する値。呼び出されているサービスがこの値を生成します。このフィールドの最大サイズは 1 KB です。この制限を超えるコンテンツは切り捨てられます。

この値は、AWSがAPIリクエストを識別するためのIDです。AWSのAPIが処理される時に、AWS側で自動的に生成され、APIの呼び出しに関連付けられます。

Endpointの有無に関わらず、リクエスト自体が別々に処理されているため、CloudTrailEvent.requestIDの項目に違いが出ています。

全体を見ると、Endpoint由来の値の違いは見られませんでした。

AWS CLIから接続した場合

AWS CLIを経由して、EC2 Instance Connect(Endpoint未使用)とEC2 Instance Connect Endpointに接続した際のログを、以下に示します。

EC2 Instance Connect(Endpoint未使用)

EC2 Instance Connect(Endpoint未使用) のケースでは、SendSSHPublicKeyイベントが取得できました。

{
    "EventId": "5d31...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,15,4,42, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-1697...",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-0d75..."
        }
    ],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:botocore-session-1697...",
            "arn": "arn:aws:sts::1234...:assumed-role/username/botocore-session-1697...",
            "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:04:40Z",
                    "mfaAuthenticated": "false"
                }
            }
        },
        "eventTime": "2023-10-12T06:04:42Z",
        "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-0d75...",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "53e0...",
            "success": true
        },
        "requestID": "53e0...",
        "eventID": "5d31...",
        "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"
        }
    }',
}

EC2 Instance Connect Endpoint

EC2 Instance Connect(Endpoint未使用) のケースでは、OpenTunnelSendSSHPublicKeyイベントが取得できました。

{
    "EventId": "0826...",
    "EventName": "OpenTunnel",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,15,18,50, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-1697...",
    "Resources": [],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:botocore-session-1697...",
            "arn": "arn:aws:sts::1234...:assumed-role/username/botocore-session-1697...",
            "accountId": "1234...",
            "accessKeyId": "ASIA...",
            "userName": ""
        },
        "eventTime": "2023-10-12T06:18:50Z",
        "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-0c78...",
            "maxTunnelDuration": "3600",
            "remotePort": "22",
            "privateIpAddress": "10..."
        },
        "responseElements": null,
        "requestID": "3a11...",
        "eventID": "0826...",
        "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"
    }',
}
{
    "EventId": "c181",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,15,18,49, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-1697...",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-0d75..."
        }
    ],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:botocore-session-1697...",
            "arn": "arn:aws:sts::1234...:assumed-role/username/botocore-session-1697...",
            "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:04:40Z",
                    "mfaAuthenticated": "false"
                }
            }
        },
        "eventTime": "2023-10-12T06:18:49Z",
        "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-0d75",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "38c6...",
            "success": true
        },
        "requestID": "38c6...",
        "eventID": "c181...",
        "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"
        }
    }',
}

両者の違い

AWS CLIから接続した場合、Endpointなしの場合とありでは検出されるイベントに違いが見られました。

具体的には、Endpointなしの場合はSendSSHPublicKey、Endpointありの場合はOpenTunnelSendSSHPublicKeyが検出されました。

また、両方で検出されたSendSSHPublicKeyイベント履歴には、以下の項目で違いが見られました。なお、タイムスタンプが違うのは自明なので割愛しています。

  • EventId
  • CloudTrailEvent.requestParameters.sSHPublicKey
  • CloudTrailEvent.responseElements.requestId
  • CloudTrailEvent.requestID
  • CloudTrailEvent.eventID
{
    "EventId": "c181...",
    "EventName": "SendSSHPublicKey",
    "ReadOnly": "false",
    "AccessKeyId": "ASIA...",
    "EventTime": datetime.datetime(2023,10,12,15,18,49, tzinfo=tzlocal()),
    "EventSource": "ec2-instance-connect.amazonaws.com",
    "Username": "botocore-session-1697...",
    "Resources": [
        {
            "ResourceType": "AWS::EC2::Instance",
            "ResourceName": "i-0d75..."
        }
    ],
    "CloudTrailEvent": '{
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "AssumedRole",
            "principalId": "AROA...:botocore-session-1697...",
            "arn": "arn:aws:sts::1234...:assumed-role/username/botocore-session-1697...",
            "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:04:40Z",
                    "mfaAuthenticated": "false"
                }
            }
        },
        "eventTime": "2023-10-12T06:18:49Z",
        "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-0d75",
            "instanceOSUser": "ec2-user",
            "sSHPublicKey": "ssh-ed25519 AAAA..."
        },
        "responseElements": {
            "requestId": "38c6...",
            "success": true
        },
        "requestID": "38c6...",
        "eventID": "c181...",
        "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"
        }
    }',
}

EventId, CloudTrailEvent.eventID

再掲になりますが、こちらの値に関しては、こちらのドキュメントに記載があります。

eventID

各イベントを一意に識別するために CloudTrail によって生成された GUID。この値を使用して、単一のイベントを識別できます。たとえば、プライマリキーとして ID を使用し、検索可能なデータベースからログデータを取得できます。

これらの値は、イベントを一意に特定するためのIDとなっています。CloudTrailを使用してAPIの呼び出しを記録する際に、このIDを使って特定のAPIの呼び出しを追跡したり、問題が発生したときの原因を特定できます。 

今回のケースだと、そもそもイベント自体が異なるものとなっています。そのため、EventId, CloudTrailEvent.eventIDといった値に違いが出ています。

CloudTrailEvent.requestParameters.sSHPublicKey

こちらの値に関しても再掲になりますが、こちらのドキュメントに記載があります。

requestParameters

リクエストとともに送信されたパラメータ (ある場合)。これらのパラメータは、該当する AWS のサービスの API リファレンスドキュメントに記載されています。このフィールドの最大サイズは 100 KB です。この制限を超えるコンテンツは切り捨てられます。

CloudTrailEvent.requestParametersには、AWSサービスのAPI呼び出しで指定されたリクエストパラメータが含まれています。CloudTrailEvent.requestParameters.sSHPublicKeyには、AWSサービスのAPI呼び出しで指定されたSSH公開鍵が含まれています。

今回、EC2 Instance Connectを用いたEC2インスタンスへの接続では、裏で一時的なSSH鍵が生成されています。この公開鍵をEC2インスタンスに送信することで接続を可能としています。そのため、Endpointの有無に関わらず、こちらの値にも違いが見られています。

CloudTrailEvent.responseElements.requestId

こちらの値に関しても再掲になりますが、こちらのドキュメントに記載があります。

responseElements

変更を行うアクションのレスポンスの要素 (アクションの作成、更新、削除)。アクションが状態を変更しない場合 (例: オブジェクトの取得やリストのリクエスト)、この要素は省略されます。これらのアクションは、該当する AWS のサービスの API リファレンスドキュメントに記載されています。このフィールドの最大サイズは 100 KB です。この制限を超えるコンテンツは切り捨てられます。

こちらの値は、リクエストのレスポンスに紐づくIDとなっています。API呼び出しのレスポンスが返ってきた時に、それがどのリクエスト由来のものなのかを識別できます。一般的には、レスポンスが成功した場合や、特定のAPI呼び出しに対するレスポンスにのみ存在することが多いようです。

Endpointの有無に関わらず、リクエスト自体が別々に処理され、そのレスポンスも別々に返ってきています。そのため、CloudTrailEvent.responseElements.requestIdの項目に違いが出ています。

CloudTrailEvent.requestID

こちらの値に関しても再掲になりますが、こちらのドキュメントに記載があります。

requestID

リクエストを識別する値。呼び出されているサービスがこの値を生成します。このフィールドの最大サイズは 1 KB です。この制限を超えるコンテンツは切り捨てられます。

この値は、AWSがAPIリクエストを識別するためのIDです。AWSのAPIが処理される時に、AWS側で自動的に生成され、APIの呼び出しに関連付けられます。

Endpointの有無に関わらず、リクエスト自体が別々に処理されているため、CloudTrailEvent.requestIDの項目に違いが出ています。

AccessKeyId, CloudTrailEvent.userIdentity.accessKeyIdが、AXS CLIだと同じ値になる理由の考察

今回の検証でひとつ気になったのが、「AWS マネジメントコンソールから接続すると、Endpointなし・ありでAccessKeyId,CloudTrailEvent.userIdentity.accessKeyIdに違いが見られた一方で、AWS CLIから接続すると同じ値になっていた」という点です。

ここで、先ほどのAccessKeyId,CloudTrailEvent.userIdentity.accessKeyIdの説明を再掲します。

accessKeyId

リクエストに署名するために使用された アクセスキー ID。リクエストが、一時的セキュリティ認証情報で行われた場合、これは、一時的認証情報のアクセスキー IDです。セキュリティ上の理由から、accessKeyId が存在しないか、空の文字列として表示される可能性があります。

こちらは、AWS CLIのセッションが継続している間は、同じアクセスキーでEC2に接続しているためだと考えられます。

イベント履歴を見ても、アクセスキーの値が同じかつAWS CLIで接続しているときのイベント履歴では、Usernamebotocore-session-XXXX...XXXX...の値が同じになっていました。botocore-sessionの値自体は変わるのですが、それに伴ってアクセスキーも変わる形式になっているようです。

さいごに

各種接続時に、Endpointの有無によってアクセスログに違いが出るという結果は、なんとなく予想はできていました。しかし、AWS CLI接続時のセッションが生きている場合、アクセスキーの値は同一のものが記録されるという、思わぬ検証結果も得られました。

Endpointの有無だけでなく、どんなサービスを経由するかでイベント履歴が変わるのも面白いですね。

こちらのブログがお役に立てれば幸いです。では!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.