はじめに
VPC内のAWSリソース(RDSやElastiCacheのような)にアクセスする際の踏み台環境ですが、昨今、EC2を利用せず、Fargateを中心としたシステム開発も増えてきていることもあり、踏み台環境もFargateで構築する機会が増えてきました。 今回は踏み台環境をFargate + ECS Execで構築する際の良いところ、注意事項、IAMポリシーを利用した制御方法をご紹介したいと思います。
Fargate + ECS Exec 踏み台の良いところ
ECS Exec機能ありきで、Fargate踏み台環境を作成する場合、以下のようなことが簡単に実現できるのが便利で大変ありがたいです。
- 必要な時だけ踏み台コンテナ起動(aws ecs run-task) ※EC2でも必要な時だけ起動は可能ですが、起動が早い
- セキュリティ統制の対応
- IAMポリシーによる権限の集中管理(接続できる人、踏み台コンテナを起動できる人等が制御可能)
- MFAの強制(IAMポリシーの制御により、接続時にMFA強制)
- 監査ログ保管(独自の作り込みをせずに用意された機能で実現可能)
- 構築簡単・管理面が手軽
- FargateはEC2と比べて構築範囲・管理範囲が狭くて済む
ECS Exec利用の注意事項
上記メリットにも記載した通り、設定自体も非常に簡単で便利なECS Exec機能ですが、AWS公式ドキュメント(https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html#ecs-exec-considerations)に記載されている内容で、利用にあたって特に注意しておきたい事項についてご紹介していこうと思います。
ECS Exec セッションのアイドルタイムアウト時間は 20 分です。この値は変更できません。
記載の通り。長時間かかるSQL等のコマンド実行する等は、シェルにしてバックグラウンドで処理させる等、少々工夫が必要になります。
SSM エージェントは、必要なディレクトリやファイルを作成するために、コンテナのファイルシステムに書き込みができる必要があります。したがって、readonlyRootFilesystemタスク定義パラメータ、またはその他の方法を使ってルートファイルシステムを読み取り専用にすることは、サポートされません。
readonlyRootFilesystemはサポートされませんのでセキュリティ要件と相談の上適用範囲、適用有無を決める必要があります。例)踏み台だけECS Exec有効化とか
以下、Dockerfileファイル例のようにSSMエージェントが書き込み可能なよう設定をすることでreadonlyRootFilesystemでも動作させること自体は可能です。ただ、あくまでデバックや一時的な利用に限定するのが良いと思います。
VOLUME [ "/var/lib/amazon", "/var/log/amazon" ]
一部の操作 (コンテナのメインプロセスの終了、コマンドエージェントの終了、依存関係の削除) によって、孤立プロセスとゾンビプロセスが発生する可能性があります。 ゾンビプロセスをクリーンアップするには、タスク定義に initProcessEnabled フラグを追加することをお勧めします。
記載の通りです。踏み台のような用途を想定すると/bin/bashプロセスが接続数分だけできてしまうためやはり、孤立プロセスが発生する可能性を考慮して有効にするのが良いと思います。
タスク定義パラメータ - Amazon Elastic Container Service
Docker run reference | Docker Documentation
execute-commandアクション外部の SSM セッションを開始することは可能ですが、これにより、セッションはログに記録されず、セッション制限に対してカウントされません。IAM ポリシーを使用した ssm:start-session操作を拒否して、このアクセスを制限することをお勧めします。詳細については、「[Start Session (セッション開始)] 操作へのアクセス制限」を参照してください。
アクセス制御の統制面を考えると、やはりこちらも記載の通り設定するのが推奨です。
AWS CLI のセッションマネージャープラグインをインストールします。
記載の通りですが利用者側(接続元環境側)でインストールが必要です。
Amazon ECS はインタラクティブセッションの開始のみをサポートするため、--interactiveフラグを使用する必要があります。
あくまで「インタラクティブセッション」ということ、コマンド1つ投げて実行のような(非インタラクティブ)用途は想定していないことは理解した上で利用しましょう。
IAMポリシー条件キーを利用した制御
AWS公式ドキュメントにも記載ありますが、IAMポリシー条件キーを利用した制御についても可能で、例えば以下のようなことも可能です。
ECSタスクのタグ、Loginキーがtrue値でないとECS Exec接続を許可しません。 Loginキーの値は常にfalseにしておき、ECS Exec接続許可した場合にタグ値をtrueへ変更して接続させる等のログイン運用などが可能です。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "ecs:ExecuteCommand", "Resource": "*", "Condition": { "StringNotEqualsIfExists": { "ecs:ResourceTag/Login": "true" } } } ] }
続いてスイッチロール時にMFAを強制させるIAMポリシー例になります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<AWSアカウント番号(スイッチロール先)>:role/<IAMロール名(スイッチロール先)>", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "true" } } } ] }
運用ポリシー次第ではありますが、例えばMFAの有効化・無効化等はユーザー自身で実施させたい場合は、以下のようIAMポリシー等を追加で適用させます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowListActions", "Effect": "Allow", "Action": [ "iam:ListUsers", "iam:ListVirtualMFADevices" ], "Resource": "*" }, { "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA", "Effect": "Allow", "Action": [ "iam:ListMFADevices" ], "Resource": [ "arn:aws:iam::<AWSアカウント番号>:mfa/*", "arn:aws:iam::<AWSアカウント番号>:user/${aws:username}" ] }, { "Sid": "AllowIndividualUserToManageTheirOwnMFA", "Effect": "Allow", "Action": [ "iam:CreateVirtualMFADevice", "iam:DeleteVirtualMFADevice", "iam:EnableMFADevice", "iam:ResyncMFADevice" ], "Resource": [ "arn:aws:iam::<AWSアカウント番号>:mfa/*", "arn:aws:iam::<AWSアカウント番号>:user/${aws:username}" ] }, { "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA", "Effect": "Allow", "Action": [ "iam:DeactivateMFADevice" ], "Resource": [ "arn:aws:iam::<AWSアカウント番号>:mfa/*", "arn:aws:iam::<AWSアカウント番号>:user/${aws:username}" ], "Condition": { "Bool": { "aws:MultiFactorAuthPresent": "true" } } }, { "Sid": "BlockMostAccessUnlessSignedInWithMFA", "Effect": "Deny", "NotAction": [ "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:ListMFADevices", "iam:ListUsers", "iam:ListVirtualMFADevices", "iam:ResyncMFADevice", "iam:ChangePassword" ], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } } ] }
まとめ
今回は踏み台コンテナとしての利用について記載しましたが、通常の開発でもデバックや調査に非常に有用なECS Exec機能、この便利さを是非みなさまにもお試し頂きたいです。
参考 コマンド実行例
- Fargateコンテナ起動
利用時だけ、以下コマンドからコンテナ起動します。
> aws ecs run-task ` --cluster <クラスタ名> ` --enable-execute-command ` --launch-type FARGATE ` --platform-version 1.4.0 ` --task-definition arn:aws:ecs:ap-northeast-1:<AWSアカウント番号>:task-definition/<タスク定義名>:<リビジョン> ` --network-configuration "awsvpcConfiguration={subnets=[ subnet-aaaaaaaaaaaaaaaaa, subnet-ccccccccccccccccc, subnet-ddddddddddddddddd ],securityGroups=[sg-xxxxxxxxxxxxxxxxx],assignPublicIp=DISABLED}" ` --count 1 --profile <プロファイル名>
- ECS Execを使用してコマンド実行
IAMポリシーによりMFAの入力を促す例です。 オプション指定としては公式ドキュメント通りですがinteractiveフラグの指定が必要です。
> aws ecs execute-command --cluster <クラスタ名> --task <タスクID> --container <コンテナ名> --interactive --command "/bin/sh" --profile <プロファイル名> The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Enter MFA code for arn:aws:iam::<AWSアカウント番号>:mfa/<IAMユーザ名>: Starting session with SessionId: ecs-execute-command-xxxxxxxxxxxxxxxxx sh-4.2#