コンテナセキュリティを検討していると、ECSで利用されているイメージはECRから取得されているかチェックしたいという要望はあると思います。
EKSの場合はこちらの記事で書かせていただいたOPA などを利用すると良いですが、ECSの場合はAWS Configを使うことで検査できます。
事前準備
動作内容の確認
2021年2月末にAWS Configがコンテナ関連のサービスをサポートしたので、こちらを使ってみようと思います。
リソースの定義にはECS関連のものが追加されています。
ただし、マネージドルールはEKSのみが準備されていて、残念ながらECSのものはまだありません。(2021/04/03時点)
自分でゼロから作らないといけないと考えそうですが、もう一つ探す場所があります。それがこちらのawslabsのリポジトリです。
ここには色々なルールが纏まっていて、更に aws-config-rdk ( Rule Development Kit )というツールを使うと簡単に自分の環境にもデプロイできるようになっています。
ここに正にやりたかった ECS_ECRIMAGE_CHECK
というルールがあるので、こちらを利用します。
監査対象のタスク登録
Cloudformationで以下のように2つのTaskDefinitionを登録してみます。正しく動けば片方だけ監査にかかるはずです。
タスク定義名 | 説明 | 期待される監査結果 |
---|---|---|
nginx-from-dockerhub | Dockerhubからnginxイメージを取得するタスク定義 | NG |
nginx-from-ecr | ECRからnginxイメージを取得するタスク定義 | OK |
--- AWSTemplateFormatVersion: "2010-09-09" Description: AWS Config Test Resources: ECSTaskExecutionRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy ECSTaskDefinitionFromDockerhub: Type: AWS::ECS::TaskDefinition Properties: Family: nginx-from-dockerhub ExecutionRoleArn: !Ref ECSTaskExecutionRole Cpu: 256 Memory: 512 NetworkMode: awsvpc RequiresCompatibilities: - FARGATE ContainerDefinitions: - Name: nginx-from-dockerhub Image: nginx ECSTaskDefinitionFromECR: Type: AWS::ECS::TaskDefinition Properties: Family: nginx-from-ecr ExecutionRoleArn: !Ref ECSTaskExecutionRole Cpu: 256 Memory: 512 NetworkMode: awsvpc RequiresCompatibilities: - FARGATE ContainerDefinitions: - Name: nginx-from-ecr Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/nginx
AWS Configルールのデプロイ
では早速 ECS_ECRIMAGE_CHECK
をデプロイしていきます。
aws-config-rdkのインストール
Rule Development Kitをインストールします。pipで簡単にインストール可能です。
pip install rdk
リポジトリのClone
まずは、 awslabs/aws-config-rules
のリポジトリをCLONEしてきます。
git clone --depth 1 https://github.com/awslabs/aws-config-rules
今回関連するファイルはこちらになります。
$ cd aws-config-rules/python $ ls ./ECS_ECRIMAGE_CHECK ECS_ECRIMAGE_CHECK.py ECS_ECRIMAGE_CHECK.zip parameters.json
設定ファイルの調整
aws-config-rules/python/ECS_ECRIMAGE_CHECK /parameters.json
の中身を調整しておきます。(後からマネジメントコンソールからも変更できます)
変更したのは以下の点です。
後ほど用意するタスク名を監査対象として設定しています、 Dockerhubからイメージを取得する nginx-from-dockerhub
と ECRからイメージを取得する nginx-from-ecr
を設定しています。
また、トリガーとして新機能である AWS::ECS::TaskDefinition
イベントを設定しています。
変更後のJSONは以下の通りです。
{ "Version": "1.0", "Parameters": { "RuleName": "ECS_ECRIMAGE_CHECK", "SourceRuntime": "python3.7", "CodeKey": "ECS_ECRIMAGE_CHECK.zip", "InputParameters": "{\"TaskDefinition\": \"nginx-from-dockerhub,nginx-from-ecr\",\"RegionName\": \"ap-northeast-1\"}", "OptionalParameters": "{}", "SourceEvents": "AWS::ECS::TaskDefinition" }, "Tags": "[]" }
ルールのデプロイ
引続き aws-config-rules/python
ディレクトリで作業していきます。
rdkのデプロイ用にS3バケットだけ準備して以下のように実行していきます。
CODE_BUCKET=YOUR_CODE_BUCKETNAME rdk deploy --custom-code-bucket ${CODE_BUCKET} ECS_ECRIMAGE_CHECK
デプロイ処理が走るので暫く待ちます。
Running deploy! Found Custom Rule. Zipping ECS_ECRIMAGE_CHECK Uploading ECS_ECRIMAGE_CHECK Upload complete. Creating CloudFormation Stack for ECS_ECRIMAGE_CHECK Waiting for CloudFormation stack operation to complete... Waiting for CloudFormation stack operation to complete... #--省略 Waiting for CloudFormation stack operation to complete... CloudFormation stack operation complete. Config deploy complete.
Cloudformationが正常終了しています。
AWS Configに新たにルールが追加されているのが確認できます。
ルールの編集からパラメータの項目を見ると先程 json側で設定したパラメータが設定されています。JSONで設定しなくてもこちらで変更することも可能です。
動作確認
動作確認をしてみます。
nginx-from-dockerhubのコンプライアンス違反の確認
ここまでの作業をして暫くすると、AWS Configの画面から、今回登録した ECS_ECRIMAGE_CHECK
のコンプライアンス違反が確認できます。
nginx-from-dockerhubの修正
違反となっていたnginx-from-dockerhubのタスク定義のイメージをECRのモノに書き換えてみます。
準拠とグリーンマークになりました。
nginx-from-ecrの修正
元々ECRからイメージを取得していて、準拠していた nginx-from-ecr
のイメージ取得元をdockerhubに変更してみます。
暫くするとコンプライアンス違反とステータスが変わったことが確認できます。
最後に
今回はツールであるrdkを使ってAWS Configのルールをデプロイしてみました。
今後要件によってパラメータが変更になれば、parameters.jsonを修正してrdsでデプロイすれば裏でCloudformationで適用してくれます。Git管理もしやすいですね。
中身を見てみるとわかるのですが、シンプルな構造なので自分で調整することも可能です。
EKSを触ってきてOPAのルール書くよりはいくらか簡単な気もします。AWS標準サービス同士という安心感もあって使い易いです。