IAMポリシー作成ssm:StartSessionのポートフォワーディングでポリシー制限を厳しく設定
困ったこと
AWS Systems Manager Session Managerを利用して、ローカルマシン(ユーザーの端末)-->>EC2インスタンス(bastionサーバー)に接続し、さらにそのサーバー経由でリモートデータベース(プライベートネットワーク内のホスト)にポートフォワーディングを行いたいと考えました。
ただし、ポリシーの制限を強くするためにSSMを許容するEC2インスタンスを特定のインスタンスのみに絞りたいです。
ポートフォワーディングセッションが失敗し、どのIAMポリシーに問題があるのかがわかりませんでした...
IAMポリシーの評価論理
AWS IAMポリシーの評価は次のようなルールに基づいています:
- 暗黙的な拒否:IAMでは、デフォルトですべてのアクションが拒否されます。つまり、許可が明示されない限り、全てのリソースやアクションにアクセスすることはできません。
- 明示的な許可: 明示的に許可されたアクションやリソースのみが実行可能です。ポリシーに「Effect: Allow」と記載されたものがこれに該当します。
- 明示的な拒否: ポリシー内に「Effect: Deny」と明示されたアクションは、そのアクションに対して許可が存在していたとしても、強制的に拒否されます。
公式ドキュメント:
StartPortForwardingSessionToRemoteHostとは
AWS-StartPortForwardingSessionToRemoteHost は、AWS Systems ManagerのSession Managerが提供するドキュメントの一つで、特定のEC2インスタンス経由でリモートホスト(DBやアプリケーションサーバー)へのポートフォワーディングを行うために使用されます。このドキュメントを利用することで、SSHやバスチョンホストを使わずに、セキュアなトンネルを介してリモートホストにアクセスすることが可能です
SSMコマンド例
下記のコマンドで、ローカルマシン(ユーザーの端末)-->>EC2インスタンス(bastionサーバー)-->>リモートデータベース(プライベートネットワーク内のホスト)にポートフォワーディングを行いたいと考えました。
aws ssm start-session \
--target <instance-id> \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":[<dbのhost-cluster-url>],"portNumber":["3306"], "localPortNumber":["13306"]}' \
--profile stg \
--region ap-northeast-1
設定したポリシー
修正前
当初は、全てのリソースに対してssm:StartSessionを許可していました。
勿論、SSMは実行可能ですが、権限を最小限にしたいです。
特定のEC2インスタンス(bastionサーバー)からのみSSMを許可しようと思います。
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "*"
},
失敗例
EC2インスタンスのタグに「Name: bastion-db-maintenance」が付いているEC2インスタンスのみに制限しようとしました。 しかし、SSMを実行すると権限が無いというエラーになるのです。
Conditionの使い方は問題無さそうでした...
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ssm:ResourceTag/Name": [
"bastion-db-maintenance"
]
}
}
},
勘違いしていたこと
今回の接続では、下記の2つA・Bが存在しています。
この両方がssm:StartSession actionの権限が必要だったようです。
A: ローカルマシン(ユーザーの端末)-->>EC2インスタンス(bastionサーバー)
B: EC2インスタンス(bastionサーバー)-->>リモートデータベース(プライベートネットワーク内のホスト)
つまり、失敗例では
A: は許可できるが、B: の権限が無いということです。
修正後
こちらに修正することによって、
A: ローカルマシン(ユーザーの端末)-->>EC2インスタンス(bastionサーバー)
-->> bastion-db-maintenance のみに制限する
B: EC2インスタンス(bastionサーバー)-->>リモートデータベース(プライベートネットワーク内のホスト)
-->> AWS-StartPortForwardingSessionToRemoteHost を許可する
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ssm:ResourceTag/Name": [
"bastion-db-maintenance"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "arn:aws:ssm:*:*:document/AWS-StartPortForwardingSessionToRemoteHost"
},
参考
Discussion