TOP>コラム一覧>Well-Architected コンテナアプリケーションレンズを作る試み -②実践編:製造工程-

Well-Architected コンテナアプリケーションレンズを作る試み
-②実践編:製造工程-

AWSで実装するSP800-190

前回の記事ではコンテナアプリケーションの有用性を紹介しましたが、一方でセキュリティについて満たすためにはユーザの対策が必要になることもお伝えしました。これを考える上で紹介していたのがSP800-190になります。このガイドラインで挙げられている観点を基にAWSでのセキュリティを考えていきます。

https://www.ipa.go.jp/security/reports/oversea/nist/ug65p90000019cp4-att/000085279.pdf

コンテナ技術は性質上アプリケーションとインフラの境界が曖昧な部分があります。一方、観点を変えるとコンテナは製造工程とリリース工程に分けることができます。まずは製造工程についてセキュリティを強化していきます。リリースと連携する箇所もあるため、完全に割り切れませんがリリースの準備と見ていただければと思います。

コンテナイメージリスク

コンテナイメージはコンテナアプリケーションにおける成果物であり、pip,npm,maven,gradleやrpm,debなどのパッケージ群と同じようなもの、またはこれらをさらに内包したものになります。そのため、アプリケーション開発として考えるべきリスクに対応する必要があります。

また、コンテナはWebサーバ,APサーバのようなミドルウェアを含んで構成を行う事ができ、稼働するホストOSに対しても操作範囲が及びます。そのため、デプロイをするためのミドルウェア設定、コンテナ設定についても考える必要があります。

イメージを作成するにあたり、考えられるリスクは下記の通りです。前回でも述べた通り、アプリケーション部分のため全てユーザ責任になります。3rdPartyのツールを用いる、他の機能で担保できるものもあるため必ずこの構成にする必要はありませんが、観点については満たすべきです。

イメージのリスク

項目 詳細 対象
イメージの脆弱性 脆弱性のあるコード記述、パッケージやライブラリを含んでしまうリスク ソースコード、ライブラリ、パッケージ、コンテナイメージ
イメージ設定の不具合 イメージビルドの設定(DockerFile)でセキュリティ情報を満たしていない DockerFile、ベースイメージ
埋め込まれたマルウェア マルウェアを含んだイメージが混入していないか コンテナイメージ
埋め込まれた平文の秘密情報 ソースコードにシークレット情報が含まれていたり、変数が使いまわされるなどのリスク ソースコード、認証情報を含んだファイル(Git上)
信頼できないイメージの使用 オープンソースの信頼できないイメージを無制限に扱ってしまうリスク コンテナイメージ

コンテナイメージリスクへの対策

上記のリスクについてユーザができる対策を見ていきましょう。確かにアプリケーション部分なので責任共有モデル上ユーザが責任を負うものですが、AWSのサービスを利用、組み合わせることでその負担を軽減する事ができます。

イメージの脆弱性対策1:CodeGuruを用いたSAST

https://aws.amazon.com/jp/codeguru/features/

CodeGuruのセキュリティスキャンによりコードに含まれる脆弱性情報を検出できます。Gitと統合してソースコードをスキャンしたり、ファイルをアップロードしてスキャンをかける事も可能です。

実際にサンプルコードでスキャンを行うと検出された脆弱性が一覧表示されました。危険性の説明から対策についても記載がされています。この検出と対策をCIパイプラインに組み込み承認フェーズを挟みSASTで合格した脆弱性のないコードだけが以降ビルドされていきます。

イメージの脆弱性対策2:ECR +Inspectorによるイメージスキャン

ソースコードで対策されていれば十分というわけでは必ずしもありません。というのも、既にビルドしてリリースされているイメージが新規の脆弱性を含んでしまった場合に対応できないためです。また、ソースコードでなくパッケージやライブラリなどビルド過程で初めて利用、混入するものについては捕捉しきれないためです。

ECRでは無償の基本スキャンと拡張スキャンが提供されています。前者はECRのみで実行され、後者はInspectorと統合されています。CodeGuruや3rdParty製品ではソースコードやビルド定義をスキャンしていましたが、ここでは最終成果物であるコンテナイメージに対してスキャンを実施しています。基本スキャンはOSパッケージに対してのみなので、パッケージやライブラリについても拡充するのであれば有償の拡張スキャンを利用する方がよいです。

実際に古いバージョンのNginxを拡張スキャンを有効にしたECRにPushしスキャンをかけてみました。するとInspector上のECR及びPushされたコンテナイメージに脆弱性情報が出力されました。CodeGuruと同様に脆弱性情報と対策が記載されています。

オープンソースやサードパーティのCWP(Cloud Workload Protection)ツールでも同様の機能が利用可能ですが、マネージドサービスとして提供されコンテナレジストリとセットで提供されているのは非常に有用です。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/image-scanning.html

https://docs.aws.amazon.com/ja_jp/inspector/latest/user/scanning-ecr.html

イメージ設定の不具合対策:3rdパーティー製品の力を借りてスキャンを行う

ソースコードの対策を行った後はDockerfileへの対策です。DockerFile、ビルド時のベストプラクティスは以下に提示されています。

https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html

Dockerfileやビルド時のセキュリティ対策についてはOSSが充実しているのもあり、CodeBuildや利用中のCIツール内でOSSによるスキャンを行うケースがAWSとしても紹介されています。

https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automatically-build-and-deploy-a-java-application-to-amazon-eks-using-a-ci-cd-pipeline.html

主なオープンソースとしてはTrivy、checkov、dockleなどがあります。他にも有償の製品内でカバーするものがあればそちらを利用しても良いでしょう。

また、DockerでないApp2Containerなどを利用の方は各サービス、ソフトのビルド時のベストプラクティスを適用しましょう。

https://docs.aws.amazon.com/ja_jp/app2container/latest/UserGuide/iam-a2c.html

埋め込まれたマルウェアの対策:GuardDuty Malware Protectionによる検知

開発段階で不審なライブラリやパッケージが入らないようにする。後述の署名付きのイメージのみ利用できるようにする事でほぼ防げますが、混入した場合に何も対処できないというのは心もとあないです。予防的統制ではなく発見的統制となりますが、GuardDutyのMalwareProtectionを用いることにより、不審な振る舞いを検出することができます。

MalwareProtectionではEBSのスナップショットを取得してそこからスキャンを行う事ができます。エージェントレスで対応できるのが魅力ですが、EBSを軸としているためFargateは対象外になります。また、リアルタイムでの検出までは行えませんのでその点は注意が必要です。

リリース工程でのセキュリティ対策、製造工程での混入を防げば基本的には問題ないですが、さらに対策を立てたい場合はMalwareProtectionまたは3rdParty製品を活用するのも手です。

埋め込まれた平文の秘密情報対策:脆弱性スキャンとシークレットの管理一元化

シークレットがソースコードやファイルにハードコードされて登録されている場合は上記のCodeGuruまたはECR/Inspectorのスキャンで検出する事が可能です。一方、シークレットをどう扱うかというとAWSとしてはやはりSecretManagerを用いる事が最善です。

Secretの自動更新と一元管理を行えるため、ファイルやGit上で管理するよりも効率よくかつ安全に管理ができます。

https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/manage-secrets.html

信頼できないイメージの使用への対策:イメージスキャンとSigner署名の実施

前述で試しに操作した通り、外部から取得したNginxのイメージをECR/Inspectorでスキャンし脆弱性診断を行う事ができました。一見するとこれで満たせるようにも思えますが、スキャンで脆弱性や脅威を見つけるまででPullについて制限は特にありません。そのため、脆弱性を含んでいてもPullする事ができてしまいます。これを防ぐために署名を活用します。

AWSではSigner/ECRを用いてECRのPushに合わせて署名を付与することができます。CNCF認定のオープンソースであるNotation(旧Nonary)と統合されており、Notationの署名をPush時に行う事で付与でき、その署名はSigner/ECRに保管、管理されます。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/image-signing.html

https://aws.amazon.com/jp/blogs/news/announcing-container-image-signing-with-aws-signer-and-amazon-eks/

また、この署名を持ったイメージだけをPullできるよう制限がないと足りません。リリース工程の話にはなりますが、K8sのAdmission Controller機能と連携したKyvernoなどポリシーエンジンをデプロイする事で署名されたイメージだけをデプロイさせる事が可能になります。

https://kyverno.io/docs/writing-policies/verify-images/

イメージのリスクと対策

ECRの拡張スキャン有効化により満たせる項目が多くありますが、全てを担保できません。開発工程で脆弱性が入り込まないように3rdParty製品を組み合わせたり、リリース後にGuardDutyで捕捉する事でより拡充できます。

しかし、完全に満たすためにはどうしても利用料が高額になります。ECRの基本スキャンやCIツール内でOSSのイメージスキャン、イメージ設定スキャンを行うツールの導入を行う事から始め、より自動化/安定化のフェーズに入ってから、本番環境から導入としても良いかと思います。

項目 詳細 AWSでの対策
イメージの脆弱性 脆弱性のあるコード記述、パッケージやライブラリを含んでしまうリスク CodeGuru,ECR/Inspector拡張スキャン
イメージ設定の不具合 イメージビルドの設定(DockerFile)でセキュリティ情報を満たしていない CodeBuild(他CIツールも可)にOSS,3rdParty製品のスキャン
埋め込まれたマルウェア マルウェアを含んだイメージが混入していないか CodeBuild(他CIツールも可)にOSS,3rdParty製品のスキャン
埋め込まれた平文の秘密情報 ソースコードにシークレット情報が含まれていたり、変数が使いまわされるなどのリスク ECR/Inspector拡張スキャン,SecretManager
信頼できないイメージの使用 オープンソースの信頼できないイメージを無制限に扱ってしまうリスク ECR/Inspector拡張スキャン,ECR/Signerによる署名,EKS上での署名付きイメージ判定

コンテナレジストリリスク

コンテナレジストリはコンテナイメージを格納するためのストレージまたはパッケージ管理ツールに該当するものです。レジストリへのアクセス管理と中身のイメージについて管理がなされているかを評価します。イメージのリスクでも触れた通り、レジストリの機能を利用する事で防げるリスクがある一方でレジストリ自体に危険が及ぶ事も考えないといけません。

コンテナレジストリを扱う上でのリスク

項目 詳細 対象
レジストリへのセキュアでない接続 暗号化されていない通信によるアクセス ネットワーク、レジストリ設定
レジストリ内の古いイメージ 過去作成・格納したイメージが削除または更新されず脆弱性を含んだままになっている コンテナイメージ、レジストリ設定
不十分な認証・認可制限 レジストリに対する認証認可の管理がなされておらずアクセス制限がない ImagePullSecret、レジストリ設定

コンテナレジストリリスクへの対策

せっかくセキュアなイメージを作成しても、それを保管するレジストリの管理がセキュアでないと不正なイメージを持ち込んだり、開発したイメージを持ち出されたり、脆弱性のあるイメージを放置してしまう可能性があります。ECRを使えば設定はユーザ責であるものの、レジストリ自体はAWS責になります。正しく設定をする事で担保ができます。

コンテナレジストリリスクへの対策:暗号化されていない通信によるアクセス

レジストリをPrivateネットワークで構成し、かつTLSを有効にした通信を行う事で担保できます。ECRを用いる事で解消可能です。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/Registries.html

一方、よりセキュアにするには、コンテナをPush/Pull/ReplicateするPrincipal(主体)が何でどの経路を通るのか見直す事です。インターネットを介さない閉域ネットワークまたはAWSに閉じた通信とするのか、インターネットを介した通信があるのかもポイントとなります。暗号化に加えて通信経路を制限したい場合はVPCエンドポイントを用いて通信を閉じる事で担保ができます。

経路についてはそこまで心配していない、エンドポイントの利用にお金をかけられないようなシステムであればECR利用をするだけでこのリスクは対策できます。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html

コンテナレジストリリスクへの対策:レジストリに対する認証認可の管理がなされておらずアクセス制限がない

通信でも触れましたが、”何”がECRにアクセスしてくるのかを考えます。

例えばコンテナを格納するPushをするのは原則CIツールのみ、コンテナを展開するPullをするのはCDツールのみ(GitOps対応であればArgoCD/FluxCD)、DRやイメージ配布用にReplicationしてくるのは別アカウントまたは別リージョンのECRのみとなります。

原則これらがPrincipalとして扱われるべきです。そして各Principalが操作できるAction範囲はその用途に限定されるべきです。つまり基本的には最小権限の原則に従うことになります。

ECRの認証認可の制御はアイデンティティベース(IAM)とリソースベース(ECR)の2つのポリシーが利用できます。前者はPrincipal側での許可、後者はリソース側でPrincipalやResourceを限定した許可を行うものになります。基本的にはS3のバケットポリシーとIAMでのS3操作と変わりません。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html#security_iam_service-with-iam-policy-best-practices

#CloudBuildだけにPushを許可するリソースベースポリシー
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowService",
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "codebuild.amazonaws.com"
            ]
          },
          "Action":[
                    "ecr:BatchCheckLayerAvailability",
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:GetRepositoryPolicy",
                    "ecr:DescribeRepositories",
                    "ecr:ListImages",
                    "ecr:DescribeImages",
                    "ecr:BatchGetImage",
                    "ecr:InitiateLayerUpload",
                    "ecr:UploadLayerPart",
                    "ecr:CompleteLayerUpload",
                    "ecr:PutImage"
          ],
        }
      ]
    }
    

また、GitOpsの場合、CDツールはK8sのクラスタ上にコンテナとして存在しています。そのため、EKS上のコンテナがアクセスしてくるためのリソースベースポリシーが必要となります。EKSのPodにIAMロールを持たせつつ、それが何なのかを限定します。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/service-accounts.html

一方、EKS上で動かす前にコンテナをローカルやEC2,Cloud9などでPullして挙動を確かめたい場合などもあると思います。その場合でも必ずPrincipalを特定して限定し他を許容しないようにします。

コンテナレジストリリスクへの対策:過去作成・格納したイメージが削除または更新されず脆弱性を含んだままになっている

ECRのライフサイクルポリシーの適用で実現が可能です。イメージ数の上限を決めて上限を超えた場合に消すパターンとPushからの期限を決めて期限を超過した場合に消すパターンの二つが実装可能です。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/lifecycle_policy_examples.html

誤って消してはいけないものを消してしまうリスクがあるため、どちらを採用するかどのように運用すべきかに注意すべきです。

最悪ソースコード,パッケージ,DockerFileなどイメージ作成に必要な資源は全てGit上に存在していればイメージは再作成が可能です。また、即時前のバージョンにロールバックを行う事も考えてイメージ数上限を使うのがおすすめと考えます。イメージ数上限を例えば2にしてしまえば1世代前までに限定でき、RollBackを可能にしつつ最新のイメージを原則参照できる最小数のためです。

また、本番用のタグがついたイメージはその運用にし、開発/リリース検証用のイメージは時間経過で消し残さない運用ができます。

コンテナレジストリのリスクと対策

ECRを利用し適切な設定を行うことでこれらリスクに対応可能です。しかし、S3と同じようにリソースベースのポリシーやライフサイクルルール、パブリック公開の有無などAWSとして適切な設定を行う必要があり、これはユーザ責です。ここを便利だから、楽だからと安易にワイルドカードで全許可する事を堪えてセキュアな設定を入れましょう。

項目 詳細 AWSでの対策
レジストリへのセキュアでない接続 暗号化されていない通信によるアクセス ECRをPrivateで構成
レジストリ内の古いイメージ 過去作成・格納したイメージが削除または更新されず脆弱性を含んだままになっている ECRのライフサイクルルールを設定
不十分な認証・認可制限 レジストリに対する認証認可の管理がなされておらずアクセス制限がない ECRのリソースベースポリシーとアイデンティティベースポリシーを最小権限で構成

まとめ

コンテナアプリケーションの開発工程で混入しうるセキュリティリスクを抑える対策について今回触れてきました。コンテナだからK8sだからだけでなく、非コンテナのパッケージ作成までのアプリケーションでも通用する内容でした。

他にもAWSのサービスを代替するOSSや3rdParty製品も多くあり、そちらと組み合わせて対策を実現することも可能です。AWSをメインで他のクラウドがサブ、AWS一本ということであればマネージドサービスを使わない手はないです。

コンテナは動かす土台さえあればラップトップ上でもクラウドでもオンプレミスでもどこでも動かせます。また、ダウンロードとアップロードが容易なために、ついオープンソースや開発中のコンテナを無制限にPush/Pullして稼働させてしまいがちです。せっかくの利便性を全て台無しにしないよう、まずは開発工程からセキュリティを考えてみてはいかがでしょうか?

CTCは、AWSのビジネス利活用に向けて、お客様のステージに合わせた幅広い構築・運用支援サービスを提供しています。
経験豊富なエンジニアが、ワンストップかつ柔軟にご支援します。
ぜひ、お気軽にお問い合わせください。

お問い合わせ



【著者プロフィール】

山下 大貴(やました だいき)

伊藤忠テクノソリューションズ株式会社 ITアーキテクト

インフラエンジニアとしてテレコム,Webサービス事業者様向けにプリセールス/導入に従事。
AWS/Azure/GCP Professional,Expertアーキテクト資格保有。近年はDevOps/K8s関連で設計/導入支援に注力。

山下 大貴(やました だいき)

TOP>コラム一覧>Well-Architected コンテナアプリケーションレンズを作る試み -②実践編:製造工程-

pagetop