セッションマネージャーのリモートホストポートフォワードを禁止したり検出してみたりした

2022.06.06

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

はじめに

こんにちは。大阪オフィスの林です。

先日、AWS System Managerセッションマネージャーがリモートホストのポートフォワードに対応しました。

凄く便利で効率的に作業が進められそうな反面、便利すぎるが故、悪意のあるユーザーの抜け道になったりと、管理者としては考慮するべき課題も出てきそうです。
そこで今回はSystem Managerセッションマネージャーを使ったリモートホストのポートフォワードの利用を制限するIAMポリシーを幾つか紹介したいと思います。

リモートホストのポートフォワードを制限してみた

問答無用で禁止する場合

下記IAMポリシーを付与してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost"
        }
    ]
}

AWS-StartPortForwardingSessionToRemoteHostはAWS管理のDocumentなのでARN内のAWSアカウント部分は*とします。

AWS パブリックドキュメント (AWS-* で始まるドキュメント) については、Amazon リソースネーム (ARN) にアカウント ID を指定しないでください。

リモートホストのポートフォワードを条件付きで許可してみた

特定のユーザーのみ許可する場合

許可するユーザーのARNを記載し、グループにアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost",
            "Condition": {
                "ArnNotLike": {
                    "aws:PrincipalArn": [
                        "arn:aws:iam::123456789012:user/my-test1"
                    ]
                }
            }
        }
    ]
}

複数のユーザーに許可する場合

許可するユーザーのARNをカンマ(,)区切りで記載し、グループにアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost",
            "Condition": {
                "ArnNotLike": {
                    "aws:PrincipalArn": [
                        "arn:aws:iam::123456789012:user/my-test1",
                        "arn:aws:iam::123456789012:user/my-test2"
                    ]
                }
            }
        }
    ]
}

MFAが設定されている場合のみ許可

MFAが有効化されている場合のみ許可します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost",
            "Condition": {
                "ForAnyValue:BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

指定したSourceのIPアドレスからのみ許可

指定したIPアドレスからのみ許可します。x.x.x.xには許可したいIPアドレスを記載します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "x.x.x.x"
                }
            }
        }
    ]
}

色々組み合わせ

柔軟な組み合わせで条件を付けることも可能です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "ssm:StartSession",
            "Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost",
            "Condition": {
                "ArnNotLike": {
                    "aws:PrincipalArn": [
                        "arn:aws:iam::123456789012:user/my-test1",
                        "arn:aws:iam::123456789012:user/my-test2"
                    ]
                },
                "NotIpAddress": {
                    "aws:SourceIp": "x.x.x.x"
                },
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

ここで紹介した以外にも柔軟な条件を付けることが可能です。下記も参考にして頂きながら要件に応じて是非カスタマイズしてみてください。

リモートホストのポートフォワードを検出してみた

リモートホストのポートフォワードを禁止するまでではないけれども、検出はしておきたいという方は以下を参考にしてください。
System Manager Session ManagerはEventBridgeデフォルトの検出タイプには出てこないので、個別にCloudTrailイベントを取得して検出する必要があります。
イベントパターンには以下のJSONを指定しています。※検出にはCloudTrailの証跡有効化が必要です。

{
  "detail": {
    "eventSource": ["ssm.amazonaws.com"],
    "eventName": ["StartSession"],
    "requestParameters": {
      "documentName": ["AWS-StartPortForwardingSessionToRemoteHost"]
    }
  },
  "detail-type": ["AWS API Call via CloudTrail"],
  "source": ["aws.ssm"]
}

予め設定しておいたSNSに通知します。その際にデフォルトのJSONだと見栄えが悪いので、入力トランスフォーマで少しだけ整形しておきます。

  • 入力パス
{
  "AWS_Account": "$.detail.userIdentity.accountId",
  "Region": "$.region",
  "RemortHost": "$.detail.requestParameters.parameters.host",
  "RemortHostPort": "$.detail.requestParameters.parameters.portNumber",
  "Target": "$.detail.requestParameters.target",
  "User_ARN": "$.detail.userIdentity.arn"
}
  • 入力テンプレート
"リモートホストのポートフォワードを検出しました。"
"ユーザーARN : <User_ARN>"
"AWSアカウントID : <AWS_Account>"
"リージョン : <Region>"
"ターゲット : <Target>"
"リモートホスト : <RemortHost>"
"リモートホストポート : <RemortHostPort>"

メールでイイ感じに通知を受信できました。

まとめ

リモートホストのポートフォワードを完全に禁止するポリシーや一部条件付きで許可、検出について紹介させて頂きました。
セッションマネージャでのリモートホストのポートフォワードの運用管理の参考になりましたら幸いです。

以上、大阪オフィスの林がお送りしました!