ECSでECR利用監査するAWS Configをrdkを使って適用

コンテナセキュリティを検討していると、ECSで利用されているイメージはECRから取得されているかチェックしたいという要望はあると思います。

EKSの場合はこちらの記事で書かせていただいたOPA などを利用すると良いですが、ECSの場合はAWS Configを使うことで検査できます。

事前準備

動作内容の確認

2021年2月末にAWS Configがコンテナ関連のサービスをサポートしたので、こちらを使ってみようと思います。

aws.amazon.com

リソースの定義にはECS関連のものが追加されています。

f:id:yomon8:20210403102202p:plain:w500

ただし、マネージドルールはEKSのみが準備されていて、残念ながらECSのものはまだありません。(2021/04/03時点)

f:id:yomon8:20210403094041p:plain:w500

自分でゼロから作らないといけないと考えそうですが、もう一つ探す場所があります。それがこちらのawslabsのリポジトリです。

github.com

ここには色々なルールが纏まっていて、更に aws-config-rdk ( Rule Development Kit )というツールを使うと簡単に自分の環境にもデプロイできるようになっています。

ここに正にやりたかった ECS_ECRIMAGE_CHECK というルールがあるので、こちらを利用します。

f:id:yomon8:20210403094250p:plain:w500

監査対象のタスク登録

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 の中身を調整しておきます。(後からマネジメントコンソールからも変更できます)

変更したのは以下の点です。

f:id:yomon8:20210403111130p:plain:w500

後ほど用意するタスク名を監査対象として設定しています、 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が正常終了しています。

f:id:yomon8:20210403092211p:plain:w500

AWS Configに新たにルールが追加されているのが確認できます。

f:id:yomon8:20210403091825p:plain:w500

ルールの編集からパラメータの項目を見ると先程 json側で設定したパラメータが設定されています。JSONで設定しなくてもこちらで変更することも可能です。

f:id:yomon8:20210403111300p:plain:w500

動作確認

動作確認をしてみます。

nginx-from-dockerhubのコンプライアンス違反の確認

ここまでの作業をして暫くすると、AWS Configの画面から、今回登録した ECS_ECRIMAGE_CHECK のコンプライアンス違反が確認できます。

f:id:yomon8:20210403113025p:plain:w500

f:id:yomon8:20210403113053p:plain:w500

nginx-from-dockerhubの修正

違反となっていたnginx-from-dockerhubのタスク定義のイメージをECRのモノに書き換えてみます。

f:id:yomon8:20210403113236p:plain:w500

準拠とグリーンマークになりました。

nginx-from-ecrの修正

元々ECRからイメージを取得していて、準拠していた nginx-from-ecr のイメージ取得元をdockerhubに変更してみます。

f:id:yomon8:20210403113334p:plain:w500

暫くするとコンプライアンス違反とステータスが変わったことが確認できます。

f:id:yomon8:20210403113426p:plain:w500

f:id:yomon8:20210403125307p:plain:w500

最後に

今回はツールであるrdkを使ってAWS Configのルールをデプロイしてみました。

今後要件によってパラメータが変更になれば、parameters.jsonを修正してrdsでデプロイすれば裏でCloudformationで適用してくれます。Git管理もしやすいですね。

中身を見てみるとわかるのですが、シンプルな構造なので自分で調整することも可能です。

github.com

EKSを触ってきてOPAのルール書くよりはいくらか簡単な気もします。AWS標準サービス同士という安心感もあって使い易いです。