EC2 Instance Connect エンドポイントの操作をSCPで拒否してみた

2023.06.30

みなさんこんにちは、杉金です。
今回は EC2 Instance Connect Endpoint の操作をSCPで拒否してみます。SCPのポリシー内容とどのように操作が拒否されるかについてご紹介します。

拒否するポリシー

EC2 Instance Connect Endpoint関連の操作を拒否するポリシーは以下です。
4つのアクションを拒否します。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Deny",
			"Action": [
				"ec2-instance-connect:OpenTunnel",
				"ec2:CreateInstanceConnectEndpoint",
				"ec2:DeleteInstanceConnectEndpoint",
				"ec2:DescribeInstanceConnectEndpoints"
			],
			"Resource": "*"
		}
	]
}

SCP適用後の動作

SCP適用後にどのように拒否されるか試してみます。

マネジメントコンソールからEC2インスタンスに接続

EC2コンソールから対象のインスタンスを選び、「接続」からEC2 instance Connect エンドポイントを使用して接続しようとすると、EC2 Instance Connect エンドポイントが選択できません。

You are not authorized to perform this operation.

と表示されていますが、これはec2:DescribeInstanceConnectEndpointsの拒否によりエンドポイントの情報を取得できないためです。

ローカル端末からEC2インスタンスに接続

コマンドライン(1-2行目)で接続しようとすると、DescribeInstanceConnectEndpointsの呼び出しでエラー(4行目)となり失敗します。

$ ssh -i my-key-pair.pem ec2-user@i-0123456789example \
    -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-0123456789example'

An error occurred (UnauthorizedOperation) when calling the DescribeInstanceConnectEndpoints operation: You are not authorized to perform this operation.

エンドポイントの作成と削除

VPCコンソールの「エンドポイント」から、EC2 Instance Connect エンドポイントを確認しようとしても一覧に表示されません。そのためエンドポイントの削除が行えません。
これもec2:DescribeInstanceConnectEndpoints拒否によるものです。

補足事項

既存リソースとして、ゲートウェイ型のS3エンドポイントも存在したのですが、こちらも表示されなくなっていました。 AWS CLIからdescribe-vpc-endpointsを実行するとエンドポイントの情報は取得できるため、コンソールの問題のように見受けられます。コンソール下からフィードバックを送りました。

エンドポイントの作成は、作成時にエラーとなります。

エラーメッセージがエンコードされていますので、デコードして中身を確認する方法は以下のブログが参考になります。

ec2:DescribeInstanceConnectEndpointsアクションの拒否によってエンドポイントが表示されず、インスタンスへの接続やエンドポイントの削除ができないことが分かりました。
それでは、ec2:DescribeInstanceConnectEndpointsのみSCPから除外した場合にどのような動きとなるか試してみます。

SCP適用後の動作(Describe無しバージョン)

適用するSCPは以下です。冒頭のポリシーからDescribeアクションのみ削除しました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Statement2",
      "Effect": "Deny",
      "Action": [
        "ec2-instance-connect:OpenTunnel",
        "ec2:CreateInstanceConnectEndpoint",
        "ec2:DeleteInstanceConnectEndpoint"
      ],
      "Resource": "*"
    }
  ]
}

マネジメントコンソールからEC2インスタンスに接続

今度はエンドポイントが選択できるようになっています。
エンドポイントを選び「接続」を選択します。

画面遷移後にエラーとなりました。ec2-instance-connect:OpenTunnelアクション拒否によるものと思われます。  

ローカル端末からEC2インスタンスに接続

接続は拒否され、SCPで拒否されていることが分かるようなエラーメッセージに変わりました。

$ ssh -i my-key-pair.pem ec2-user@i-0123456789example \
    -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-0123456789example'

awscli.customizations.ec2instanceconnect.websocket - ERROR - {"ErrorCode":"AccessDeniedException","Message":"User: xxxxxx is not authorized to perform: ec2-instance-connect:OpenTunnel on resource: arn:aws:ec2:ap-northeast-1:0123456789012:instance-connect-endpoint/eice-xxxxxx with an explicit deny in a service control policy"}

エンドポイントの作成と削除

今度はエンドポイントが表示されるため、EC2 Instance Connectエンドポイントを選んで削除を選びます。

削除を実行しようとするとエラーとなりました。

エンドポイントの作成は、先ほどと同様のエラーになりました。

以上が、DescribeアクションをSCPから除いた時のインスタンスへの接続やエンドポイントの作成/削除の動きでした。

EC2 Instance Connect接続の拒否を追加

EC2 Instance Connectは「EC2 Instance Connect」と「EC2 Instance Connect Endpoint」の2つがあります。これまで紹介したものは後者の「EC2 Instance Connect Endpoint」ですが、「EC2 Instance Connect」の拒否についても試してます。

「EC2 Instance Connect」を拒否するポリシーを加えたものが以下です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Statement3",
      "Effect": "Deny",
      "Action": [
        "ec2-instance-connect:OpenTunnel",
        "ec2:CreateInstanceConnectEndpoint",
        "ec2:DeleteInstanceConnectEndpoint",
        "ec2:DescribeInstanceConnectEndpoints",
        "ec2-instance-connect:SendSSHPublicKey"
      ],
      "Resource": "*"
    }
  ]
}

拒否アクションとしてec2-instance-connect:SendSSHPublicKeyを加えています。
こちらは下図の2の操作を拒否するものです。その他のアクションでEC2 Instance Connectの操作をSCPで制限するものはなさそうでした。

引用:EC2のSSHアクセスをIAMで制御できるEC2 Instance Connectが発表されました | DevelopersIO

このポリシーを適用した状態での動作確認をしてみます。

マネジメントコンソールからEC2インスタンスに接続

「接続」を試みると、画面遷移後にエラーメッセージが表示されて接続ができませんでした。

Failed to connect to your instance
Access denied by EC2 Instance Connect. Either your AWS credentials are not valid or you do not have access to the EC2 instance.

ローカル端末からEC2インスタンスに接続

以前はmsshコマンドを使用して接続していましたが、現在はAWS CLIのec2-instance-connect sshを使用できます。

$ aws ec2-instance-connect ssh --instance-id i-0123456789example

An error occurred (AccessDeniedException) when calling the SendSSHPublicKey operation: User: arn:aws:sts::0123456789012:xxxxxx is not authorized to perform: ec2-instance-connect:SendSSHPublicKey on resource: arn:aws:ec2:ap-northeast-1:0123456789012:instance/i-0123456789example with an explicit deny in a service control policy

エラーとなりました。EC2 Instance Connect経由の接続は拒否されますが、キーペアを用いたSSH接続など、SCPで制限をかけた以外での接続方法は利用可能です。

EC2 Instance ConnectとEC2 Instance Connect Endpointの違い

この両者は名前が似ており、ついつい混同してしまいます。
そこで2つの違いを個人的な主観でピックアップしてみました。

比較項目 EC2 Instance Connect(EIC) EC2 Instance Connect Endpoint(EICE)
EC2インスタンスの
パブリックIPアドレス
必要 不要(付与されていても影響ない)
対応OS 専用ツールをOSに導入するため指定あり(Amazon Linux2, Ubuntu)1 SSHまたはRDP接続できるOS
EC2インスタンスのセキュリティグループ AWS指定IPレンジからのssh接続を許可 エンドポイントからの接続を許可

他にも違いはありますが、あくまでも個人的なチョイスですのでご容赦ください。
EICとEICEの違いについては、下記ブログでの解説も参考になります。

EICEとSSMセッションマネージャーとの違いは以下のブログが分かりやすいです。

最後に

EICとEICEの操作をSCPで制限をかけてみました。EICEのdescribeアクションの拒否は、ReadOnlyユーザーの運用に影響がありそうなので、describeはSCPで制限をかけなくてもいいかなと個人的には思います。
本記事ではEICEだけ書くつもりでしたが、似た名前のEICに触れないのはもったいないと感じて着手してみました。結果としてEICとEICEの違いを理解することに近づけたので満足しています。

参考資料


  1. AWS公式ドキュメントの記載が見つかりませんでしたが、Amazon Linux 2023でもEICで接続できることを確認しています