Techfirm Cloud Architect Blog

テックファーム株式会社クラウドインフラグループのブログ

Prisma CloudでAWS Fargateのランタイムを保護してみる

はじめに

最近コンテナをプロジェクトで使う機会も増えてきましたが、コンテナのセキュリティ対策で悩むことも多いのではないでしょうか。
今回はPalo Alt NetworksのPrisma Cloudを導入する機会がありましたので、Prisma CloudでAWS Fargateのコンテナランタイムの保護する際の設定と使い勝手をご紹介致します。

構成

AWS構成

今回は、AWS上に以下のような構成で構築します。
ランタイムを保護する対象はPHPコンテナで、Prisma CloudのDefenderコンテナがPHPコンテナの動作を監視してくれます。 AWS構成図

コンテナ定義

Prisma CloudのDefenderコンテナは、公式イメージを利用するためDockerfileは作成しません。
また、PHPコンテナについてもDefenderコンテナと通信するための設定は必要ないためここでは割愛します。

タスク定義

AWS FargateにPrisma Cloudを導入するには、Prisma Cloudコンソールから「コンピュート」→「Defender」に移動し、「Manual deploy」を開きます。

prismacloud-setting-1

以下のようなページに移ります。
今回は「File system monitoring」を利用するため、「Enable file system runtime protection」を有効にします。
次に、「Insert task definition」にPrisma Cloudを導入予定のタスク定義を貼り付けると必要な設定を組み込んでくれます。

prismacloud-setting-2 prismacloud-setting-3

例えば以下のようなタスク定義を貼り付けると

{
    "containerDefinitions": [
        {
            "name": "web",
            "image": "nginx",
            "entryPoint": [
                "/http_server"
            ]
        }
    ],
    "cpu": "256",
    "executionRoleArn": "arn:aws:iam::112233445566:role/ecsTaskExecutionRole",
    "family": "webserver",
    "memory": "512",
    "networkMode": "awsvpc",
    "requiresCompatibilities": [
        "FARGATE"
    ]
}

変換後のタスク定義は以下のようになります。

{
  "containerDefinitions": [
    {
      "dependsOn": [
        {
          "condition": "HEALTHY",
          "containerName": "TwistlockDefender"
        }
      ],
      "entryPoint": [
        "/var/lib/twistlock/fargate/defender",
        "fargate",
        "entrypoint",
        "/http_server"
      ],
      "environment": [
        {
          "name": "TW_IMAGE_NAME",
          "value": "nginx"
        },
        {
          "name": "TW_CONTAINER_NAME",
          "value": "web"
        },
        {
          "name": "DEFENDER_TYPE",
          "value": "fargate"
        },
        {
          "name": "FARGATE_TASK",
          "value": "webserver"
        },
        {
          "name": "FILESYSTEM_MONITORING",
          "value": "false"
        },
        {
          "name": "FIPS_ENABLED",
          "value": "false"
        }
      ],
      "image": "nginx",
      "linuxParameters": {
        "capabilities": {
          "add": [
            "SYS_PTRACE"
          ]
        }
      },
      "name": "web",
      "volumesFrom": [
        {
          "readOnly": false,
          "sourceContainer": "TwistlockDefender"
        }
      ]
    },
    {
      "entryPoint": [
        "/usr/local/bin/defender",
        "fargate",
        "sidecar"
      ],
      "environment": [
        {
          "name": "INSTALL_BUNDLE",
          "value": "<Defenderブートストラップに必要なシークレットデータ>"
        },
        {
          "name": "DEFENDER_TYPE",
          "value": "fargate"
        },
        {
          "name": "FARGATE_TASK",
          "value": "webserver"
        },
        {
          "name": "WS_ADDRESS",
          "value": "wss://australia-southeast1.cloud.twistlock.com:443"
        },
        {
          "name": "FILESYSTEM_MONITORING",
          "value": "false"
        },
        {
          "name": "FIPS_ENABLED",
          "value": "false"
        }
      ],
      "essential": true,
      "healthCheck": {
        "command": [
          "/usr/local/bin/defender",
          "fargate",
          "healthcheck"
        ],
        "interval": 5,
        "retries": 3,
        "startPeriod": 1,
        "timeout": 5
      },
      "image": "<defender image uri>",
      "logConfiguration": null,
      "name": "TwistlockDefender",
      "portMappings": []
    }
  ],
  "cpu": "256",
  "executionRoleArn": "arn:aws:iam::112233445566:role/ecsTaskExecutionRole",
  "family": "webserver",
  "memory": "512",
  "networkMode": "awsvpc",
  "requiresCompatibilities": [
    "FARGATE"
  ]
}

※プライベート値のような箇所は<>で伏字にしています

Defenderコンテナの定義が追加されていたり、監視対象のコンテナ定義にDefenderコンテナ動作に必要な環境変数や、entryPointの実行方法が変更されていたりします。
また、Defenderコンテナがstraceを使うためか、監視対象コンテナのcapabilitiesSYS_PTRACEが追加されていますね。

上記変更を例に、今回の構成は以下のようなタスク定義で実行しました。
Prisma Cloudを導入する上で必要な設定の一部抜粋となります。

  {
      "entryPoint": [
        "/usr/local/bin/defender",
        "fargate",
        "sidecar"
      ],
      "environment": [
        {
          "name": "INSTALL_BUNDLE",
          "value": "<Prisma Cloudコンソールから取得するアクセスキー>"
        },
        {
          "name": "DEFENDER_TYPE",
          "value": "fargate"
        },
        {
          "name": "FARGATE_TASK",
          "value": "php"
        },
        {
          "name": "WS_ADDRESS",
          "value": "wss://australia-southeast1.cloud.twistlock.com:443"
        },
        {
          "name": "FILESYSTEM_MONITORING",
          "value": "true"
        },
        {
          "name": "FIPS_ENABLED",
          "value": "false"
        }
      ],
      "essential": true,
      "healthCheck": {
        "command": [
          "/usr/local/bin/defender",
          "fargate",
          "healthcheck"
        ],
        "interval": 5,
        "retries": 3,
        "startPeriod": 1,
        "timeout": 5
      },
      "image": "<defender image uri>",
      "logConfiguration": null,
      "name": "TwistlockDefender",
      "portMappings": []
    },
    {
      "dnsSearchDomains": null,
      "environmentFiles": null,
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "secretOptions": null,
        "options": null
      },
      "entryPoint": null,
      "portMappings": [
        {
          "hostPort": 9000,
          "protocol": "tcp",
          "containerPort": 9000
        }
      ],
      "command": [
        "/bin/sh", "-c", "/var/lib/twistlock/fargate/defender fargate entrypoint php-fpm"
      ],
      "linuxParameters": {
        "capabilities": {
          "add": [
            "SYS_PTRACE"
          ]
        }
      },
      "cpu": 0,
      "environment": [
        {
          "name": "TW_IMAGE_NAME",
          "value": "<PHPイメージURI>"
        },
        {
          "name": "TW_CONTAINER_NAME",
          "value": "<PHPコンテナ名>"
        },
        {
          "name": "DEFENDER_TYPE",
          "value": "fargate"
        },
        {
          "name": "FARGATE_TASK",
          "value": "php"
        },
        {
          "name": "FILESYSTEM_MONITORING",
          "value": "true"
        },
        {
          "name": "FIPS_ENABLED",
          "value": "false"
        }
      ],
      "resourceRequirements": null,
      "ulimits": null,
      "dnsServers": null,
      "mountPoints": [],
      "workingDirectory": null,
      "secrets": [],
      "dockerSecurityOptions": null,
      "memory": null,
      "memoryReservation": null,
      "volumesFrom": [
        {
          "readOnly": false,
          "sourceContainer": "TwistlockDefender"
        }
      ],
      "stopTimeout": null,
      "image": "<PHPイメージURI>",
      "startTimeout": null,
      "firelensConfiguration": null,
      "dependsOn": [
        {
          "containerName": "TwistlockDefender",
          "condition": "HEALTHY"
        }
      ],
      "disableNetworking": null,
      "interactive": null,
      "healthCheck": null,
      "essential": true,
      "links": null,
      "hostname": null,
      "extraHosts": null,
      "pseudoTerminal": null,
      "user": null,
      "readonlyRootFilesystem": true,
      "dockerLabels": null,
      "systemControls": null,
      "privileged": null,
      "name": "php"
    },

タスク定義が作成し終えましたら、前手順で作成したタスク定義をAWS側に登録し、Amazon ECS サービスからタスクが起動していることを確認します。
Prisma Cloudコンソールから「コンピュート」→「Defenders」に移動し、「Deployed defenders」にDefenderステータスが表示されていればデプロイ完了です。

prismacloud-setting-4

PrismaCloudコンソールの設定

WildFire

マルウェアを検知したいためWildFireを有効化します。
Prisma Cloudコンソールから「コンピュート」→「System」に移動し、「WildFire」タブを開きます。
ページ内の「Enable runtime protection」を「On」に変更します。

prismacloud-setting-5

App-Embedded runtime policy

Prisma Cloudコンソールから「コンピュート」→「DEFEND:Runtime」に移動し、「App-Embedded policy」タブを開きます。
ページ内の「Add rule」ボタンからランタイムポリシーを定義できます。

prismacloud-setting-6

ルール定義画面が開きますが、まずは「Scope」からルールを動作させる対象を定義します。 prismacloud-setting-7-1

「Scope」欄を押下すると以下のような画面が開きますので、「Add Collection」からコレクションを定義します。 prismacloud-setting-8

コレクション定義画面が開きますので、ここでルールを動作させるスコープを定義します。
特定イメージ毎に動作させるなら「Images」欄にコンテナイメージ名を入力したり、ECSクラスター毎に動作させるなら「Clusters」欄にクラスター名を記入したりします。 prismacloud-setting-9

コレクション定義が完了したら、スコープ設定からコレクション定義を選択します。
ランタイムポリシーは以下のように各Type毎に分かれていれ個別に動作を設定していきます。
各詳細設定は公式ドキュメントを参考にしてください。

Processes

以下が「Processes」タブの設定内容です。

prismacloud-setting-7-2

Networking

以下が「Networking」タブの設定内容です。

prismacloud-setting-10

File system

以下が「File system」タブの設定内容です。 ECSタスク定義の「FILESYSTEM_MONITORING」を「true」に設定していることで設定可能になります。 prismacloud-setting-11

Custom rules

「Custom rules」からカスタムルールを定義できます。 prismacloud-setting-12

「Add rule」を押下すると以下のような画面が表示されます。
公式ドキュメントを参考に、必要に応じて各Type毎のルールが設定します。 prismacloud-setting-13

通知

上記でランタイムポリシーが定義できましたので、定義に従ってDefenderコンテナが動作するようになります。
Prisma Cloudコンソールで修正されたランタイムポリシーは、設定したタイミングで即時Defenderコンテナへ反映されるようです。

今回はランタイム保護で検知された結果を、メール、及びSlackへアラートを通知してみます。
Prisma Cloudコンソールから「コンピュート」→「Alerts」に移動し「Manage」の「Add profile」を押下します。
メールへの通知設定は以下のような項目を設定しました。

画面に従い各項目を設定するだけで特に難しい点はないかと思います。
今回は、ランタイム保護を対象としているので、通知対象となる「Triggers」は「App-Embedded Defender runtime」と「Defender health」のみとしました。 alert-setting-1

Slackへの通知設定は以下です。
通知先のSlack Webhook URLを別途用意して、「Settings」ステップで設定します。 alert-setting-2

アラート

次に意図的にアラートを発生させ、どのような形式で通知されるのか確認してみます。

メール

メールには以下のような形式で通知されました。 アラートを判断する上で必要な情報は一通り通知されるようですが、HTML形式で通知されるのは注意が必要ですね。 alert-mail-01

また短時間で大量のアラートが発生すると、以下のようにアラートがまとめられてしまうようです。 alert-mail-02

Slack

Slackには以下のような形式で通知されました。 通知される項目はメールと同じですね。 alert-slack-01

またメールの時と同様に、Slackでもアラートがまとめられて通知されました。 alert-slack-02

まとめ

今回は、Prisma CloudでAWS Fargateのランタイム保護する上での手順や使用感をご紹介しました。
動作設定がPrisma Cloudコンソールだけでできたり、カスタムルール設定やアラート通知等の機能面も備えていて使い勝手が良いなと感じています。
Prisma Cloudに興味をお持ちの方や、これから導入される方の参考になれば幸いです。

参考

Deploy App-Embedded Defender for Fargate