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

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

はじめに

前回はコンテナアプリケーションを扱う上でのリスクと対策を製造工程の観点で見てきました。一部リリース工程について触れる点もありましたが、今回はリリースそして運用に関わるリスクとその対策を考えていきます。

リリース工程、つまりデプロイとデプロイされる先、コンテナの稼働に関わる内容となります。オーケストレータベースのコンテナ基盤ではオーケストレータ→コンテナランタイム→ホストOSの順番で稼働する層が形成されています。そのため、それぞれの層でリスクを認識し対策を講じる必要があります。

オーケストレータのリスク

オーケストレータ(コンテナオーケストレータ)はコンテナを動かすホストマシン群をクラスタ化します。さらにコンテナをどのホストで動かすか、ホスト障害時にどこに退避させるか、スケールアウト/スケールインを自動で管理するものでコンテナ技術を支えるコア技術です。AWSではオーケストレータとしてECSとEKSが提供されていますが、今回はEKS(Kubernetes)を扱うことをメインで考えます。観点や一部対策についてはECSにも適用できます。

項目 詳細 対象
制限のない管理者アクセス オーケストレータはインフラ基盤とアプリデリバリー両方を操作管理するが、この管理・操作権限が制限されていないリスク EKS/K8s,IAM
許可されていないアクセス ActiveDirectoryやLDAPなどで管理されるアカウントとは別もので管理され、組織の統制から外れ管理が及ばない可能性があるリスク EKS/K8s,IAM
コンテナ間ネットワークトラフィックの不十分な分離 コンテナはホスト及びクラスタの仮想ネットワーク(=オーバレイネットワーク)上で稼働するが、この通信制御が行われず、コンテナ間で無制限に通信できてしまうリスク EKS/CNI,VPC
ワークロードの機微性レベルの混合 共有テナント上にセキュリティレベルの異なるコンテナを稼働させることによるリスク EKS/K8s,VPC
オーケストレータノードの信頼 ControlPlaneとWorkerNode間の設定不備によりクラスタ自体を危険な状態にするリスク EKS/K8s

制限のない管理者アクセスへの対策

管理者権限はK8sクラスタの設定更新、削除、ワーカーノードへの操作、APIサーバへの機能追加、操作を行う事ができる最高権限です。この権限があればクラスタ自体の操作だけでなくコンテナに対する操作権限も有するため慎重に扱う必要があります。これに対しては最小権限の原則を適用する、または人手を介した操作自体を制限することも対策になります。

IAMと紐づけて管理する

EKSはAWSのマネージドサービスだからこそIAMロール,ユーザとEKSの操作権限を紐づける事ができます。EKSではクラスタを作成したIAMプリンシパル(ユーザ、ロール)にクラスタ操作権限が付与されます。管理権限を有するメンバーを特定、制限し全関係者に管理者ロールの付与は行いません。

#IAMとK8s Userの紐付け
eksctl create iamidentitymapping --cluster my-cluster --region=region-code \\
    --arn arn:aws:iam::111122223333:user/my-user --username my-user --group eks-console-dashboard-restricted-access-group \\
    --no-duplicate-arns  

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

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/add-user-role.html

GitOpsで手動操作を減らす

また、これを強化するものとしてGitOpsを活用することが挙げられます。GitOps対応のCDツール(ArgoCD,FluxCD)を用いる事でK8sクラスタへのコンテナデプロイがCDツールのみが行うことになります。一方、CDツールにアクセスされると元も子も無くなってしまうため、後述のコンテナレベルでのアクセス制御を適用していきます。さらにCDツールもAzure EntraIDやLDAPなどSSO連携してユーザの一元管理を行う事でアクセスリスクを減らせます。

許可されていないアクセスへの対策

無制限の管理者アクセスと同様に、K8sクラスタ内のユーザとAWSのIAMプリンシパルを紐付ける、さらにIAMのConditionと多要素認証を用いてアクセス制限を行う事でより強化されたアクセス制御が可能になります。

また、これによってユーザがAWSアカウント毎、EKSクラスタ毎に点在することを防ぎ管理を一元化する、シークレット情報が流出してもアクセスを制限できる、全ての操作を追跡可能にする事ができるといったメリットを享受できます。

IAMと連携しより制限を強化する方法

  • IAMプリンシパルを外部IDサービスと連携し一元管理する
  • IAMプリンシパルに対してMFAを強制化する
  • IAMプリンシパルに対してCondition句でIpAddress,NotIpAddressを指定しアクセス元を制限する
  • CloudTrailを有効化しIAMプリンシパルの操作を監視、追跡できるようにする

GuardDutyと連携しK8sレベルでも監視

さらに、GuardDutyのEKS監査ログを用いる事でより一層EKSの監視を行う事ができます。IAMレベルだけでなくEKS内部でのAPI操作も記録化されるため、K8sレベルで何が行われたのかも監視し追跡可能となります。アドオンを導入することで利用可能です。

https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/features-kubernetes-protection.html#guardduty_k8s-audit-logs

コンテナ間ネットワークトラフィックの不十分な分離への対策

異なるセキュリティレベルのワークロード(コンテナ)が同じネットワーク上に存在する場合、通信が行えたり、通信を傍受する事が起こり得ます。VPC(EKS)単位で分ける方法とクラスタ内で制限をかける方法があります。

ネットワーク分離方法:VPC(EKS)単位で分離する

EKS及びワーカーノードを構成するVPCを共用クラスタとして利用しない事が一つ対策になります。同じVPCやクラスタで異なるシステムを混在させて動かすとアクセス制御が複雑化し管理が大変になります。分離をしてしまえば、このような懸念から解放されます。

ネットワーク分離方法:NetworkPolicy機能を用いる

一方、EKSはワーカーノードを動かさずクラスタを構成しただけでも課金が発生していきます。開発チームごとにEKSクラスタを準備すると費用も管理も課題になりえます。そういった事情から開発環境は共有化しつつ、開発チーム間でアクセスが行えないようにしたいというケースがありえます。また、VPC(EKS)単位で分離してもWeb層とデータベースアクセス層がダイレクトに通信できるのは避けたい場合もあると思います。これを解消するにはNetworkPolicyを用います。

NetworkPolicyはK8sオブジェクトでコンテナ間のファイアウォールとして機能します。EKSでは”CNI plugins for Amazon ECS and EKS”を適用したクラスタでこれを利用できます。なお、Fargateで唯一利用できるCNIのためEKSでは特別な事情がない限りはこちらを使う事が最善です。

https://github.com/aws/amazon-vpc-cni-plugins

#NetworkPolicyサンプル
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  namespace: stars
  name: frontend-policy
spec:
#ClientラベルのコンテナだけがFrontendラベルのコンテナにアクセス可能
  podSelector:
    matchLabels:
      role: frontend 
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              role: client
      ports:
        - protocol: TCP
          port: 80  

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/cni-network-policy.html#cni-network-policy-setup

他にも3rdPartyのCWP/CWPP製品を用いる事でNetworkPolicyに準ずる機能やネットワークトポロジーの可視化を行うこともできます。クラスタ数が多い場合に有用です。

ワークロードの機微性レベルの混合への対策

コンテナは仮想化と異なり、OSのカーネルをコンテナ間で共有して稼働します。そのため、ホストOSにアクセスしたりコンテナを介して攻撃、侵入されるリスクを持っています。ネットワークの分離と同様にOSホストをコンテナのワークロードに合わせて分離する必要があります。オーケストレータとして出来る対策は以下があります。

ワークロード分離方法:VPC(EKS)単位で分離する

ネットワークと同じく、VPCやEKS自体をシステム毎、アクセス制限毎に分けてしまいます。そもそもクラスタが違うため異なるシステム間でアクセスする事がクラスタレベル、ホストOSレベルでは不可となります。また、クラスタ間でネットワークアクセスができないのであれば、それもまた制限となります。

ワークロード分離方法:pinning機能を使用しワークロードの実行先を制限する

K8sの機能としてToleration/Taintというコンテナと実行先Nodeを紐づける事ができます。K8sのネイティブ機能であるためEKSでも勿論こちらを利用できます。

https://kubernetes.io/ja/docs/concepts/scheduling-eviction/taint-and-toleration/

Taintsはワーカーノードに対して設定する事ができる条件句です。tolerationはコンテナ(Deployment/Pod)に対して設定できるもので、Taints条件句を満たすものがTaintsに設定されたワーカーノードでのみ起動できます。

#K8sワーカーノード側
kubectl taint nodes node1 key1=value1:NoSchedule

#コンテナ側
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"  

https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/place-kubernetes-pods-on-amazon-eks-by-using-node-affinity-taints-and-tolerations.html

しかし、これはあくまで条件句でコンテナの実行先を絞るだけで条件句を知っていればコンテナを対象ノードにデプロイできてしまいます。後述のホストOS側でこれを防ぐ方が有効性は高いので補助としての利用がおすすめです。

オーケストレータノードの信頼への対策

オーケストレータ(EKS/K8s)の設定不備やノード間の信頼性に問題がある場合、オーケストレータの侵害や、不正なノードが追加され、システム全体が危険にさらされる可能性があります。

EKSではオーケストレータノード(コントロールプレーン)はマネージドサービス化されユーザからはAPIサーバにアクセスできる、設定をAddOnベースで追加できるだけです。通常のK8sのようにAPI ServerやControllerManagerなどのコントロールプレーンの設定ファイル自体を変更したりコンテナ自体に操作を加える事はできません。
また、ワーカーノードの追加もユーザが手動で行うものではなくAutoScaleGroupと紐づいて行われノード間の設定も自動で行われるため懸念点は少なく済みます。

kube-bench +SecurityHubによる定期診断

一方、EKSの設定についてはOSSであるkube-benchを使ってオーケストレータ自体の脆弱性を診断できます。特にEKSバージョンが古くなっていないか最新でも脆弱性を含むものがないか、前述のCNIプラグインに対しても脆弱性がないかを確認できます。

https://github.com/aquasecurity/kube-bench

kube-benchをK8s Jobとして定義し定期的に実行し続けることが可能です。さらにSecurityHubと統合し、kube-benchが持つServiceAccountにSecurityHub操作のIAM権限を付与する事で、実行結果をAWSに連携する事が可能です。他にもCWP/CWPP製品でも同様にスキャンできるものもあるのでそちらで代用も可能です。

https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster

https://github.com/aquasecurity/kube-bench/blob/main/docs/asff.md

オーケストレータのリスクと対策

オーケストレータはEKSだから安心というわけではなく、AWS観点とK8s観点でそれぞれ出来る対策があります。K8sで出来る対策は有用ではあるものの、クラスタ内部の管理を行う必要がありクラスタ数が増えると煩雑となります。なるべくAWS側の機能に委任していく、人手が介する要素を減らす事で手間を減らせます。

項目 詳細 AWSでの対策
制限のない管理者アクセス オーケストレータはインフラ基盤とアプリデリバリー両方を操作管理するが、この管理・操作権限が制限されていないリスク
  • IAMプリンシパルとEKS操作を最小限に紐づける。
  • GitOpsで操作範囲を狭める。
許可されていないアクセス ActiveDirectoryやLDAPなどで管理されるアカウントとは別もので管理され、組織の統制から外れ管理が及ばない可能性があるリスク
  • EKSを操作するIAMプリンシパルに対してSSO,MFA,アクセス元制限する。
  • GuardDuty EKS監査ログでK8s操作も監視する。
コンテナ間ネットワークトラフィックの不十分な分離 コンテナはホスト及びクラスタの仮想ネットワーク(=オーバレイネットワーク)上で稼働するが、この通信制御が行われず、コンテナ間で無制限に通信できてしまうリスク
  • VPC/EKSを分割する。
  • CNIのNetworkPolicyを用いてファイアウォールを設ける。(もしくはCWP/CWPP製品)
ワークロードの機微性レベルの混合 共有テナント上にセキュリティレベルの異なるコンテナを稼働させることによるリスク
  • VPC/EKSを分割する。
  • Taints/Tolerationで実行先を制限する。
オーケストレータノードの信頼 ControlPlaneとWorkerNode間の設定不備によりクラスタ自体を危険な状態にするリスク
  • kube-benchを定期実行しSecurityHubに連携する。(もしくはCWP/CWPP製品)

コンテナのリスク

コンテナ基盤においてワークロードの実行最小単位はコンテナになります。コンテナをホストマシン上で実際に動かしているのはランタイムと呼ばれるミドルウェアです。コンテナを複数台同じホスト上で実行し、それぞれを仮想的に隔てホストOSと連携するものです。このランタイムとして考える必要のあるリスクは下記の通りです。

項目 詳細 対象
ランタイムソフトウェア内の脆弱性 コンテナを動かすランタイム自体に脆弱性が含まれており攻撃/侵入されるリスク ランタイム
コンテナからの無制限ネットワークアクセス コンテナ同士がネットワークを通じてアクセスでき攻撃/侵入されるリスク EKS/K8s,ランタイム
セキュアでないコンテナランタイムの設定 コンテナを動かすランタイム自体の設定不備が原因で脆弱性を含んでしまうリスク ランタイム
アプリの脆弱性 稼働しているコンテナに脆弱性が含まれており、コンテナに対して攻撃/侵入されるリスク コンテナ
未承認コンテナ 外部から取得したコンテナイメージや脆弱性診断をクリアしていないコンテナがデプロイされるリスク EKS/K8s,ランタイム

ランタイムソフトウェア内の脆弱性の対策

Docker,containerdなどコンテナを動かすためのランタイムはワーカーノード(EC2,Fargate)上で稼働しています。このランタイムはミドルウェアとして動作しており、ランタイム自体にも脆弱性が含まれる可能性があります。これを防ぐ、監視する対策として以下があります。

Falco +CloudWatchによる検知

Falcoはランタイムの脆弱性診断を行えるOSSです。Falcoを用いてランタイム自体に含まれる脆弱性をスキャンする事が可能です。ランタイムを最新版へアップグレードする事で解消が図れます。また、FalcoはCloudwatchと連携でき診断結果を通知する事が可能です。Falcoの開発元であるSysdig社の製品など3rdPartyのCWP/CWPP製品でも提供されているものもあります。

https://aws.amazon.com/jp/blogs/news/implementing-runtime-security-in-amazon-eks-using-cncf-falco/

https://sysdig.jp/blog/intro-runtime-security-falco/

GuardDuty Runtimeによるモニタリング

GuardDutyでもランタイムの監視機能を提供しています。Runtime監視用のエージェントをアドオンとして導入します。EKSのランタイムに対する操作を記録する事ができます。

https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/runtime-monitoring.html

https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/how-runtime-monitoring-works-eks.html

コンテナからの無制限ネットワークアクセスへの対策

コンテナの通信に制限がない場合、1つのコンテナを侵入した後、他のコンテナへの侵入に利用するバックドアとなり得てしまいます。さらにコンテナはIPアドレスを動的に割り当てられ、常に起動/停止が発生される前提で稼働しています。この制御をかけるのはEKS/K8sのネイティブ機能だけでは限りがあります。

Detectiveを用いたVPCフローログとの統合

Detectiveの機能を用いる事でEKS内のワークロードのAPIコールやネットワークの可視化を行う事ができます。あくまで検出を軸としたものなので対策は別途必要ですがAWSで可視化する事ができます。

https://docs.aws.amazon.com/ja_jp/detective/latest/userguide/profile-panel-drilldown-kubernetes-api-volume.html

NetworkPolicyとサービスメッシュを用いる

Istioを代表としたサービスメッシュと呼ばれるコンテナ通信制御を束ねて管理する機能を用いる事での解消があります。点在したコンテナ同士の通信制御を一元管理するだけでなく、その通信はMTLSでアプリケーションレベルで暗号化されています。前述のNetworkPolicyと併用する事で制限をかける事ができます。

https://aws.amazon.com/jp/blogs/opensource/getting-started-with-istio-on-amazon-eks/

https://istio.io/

CWP/CWPP製品を用いて可視化と防御を実現する

サービスメッシュはどちらかといえば、マイクロサービスアーキテクチャを実現し信頼性/可用性を向上させるのが主たる目的です。セキュリティは副次的なものなので、特化した対策はセキュリティ製品を用いる事が有効です。CWP/CWPP提供のパートナー製品を用いる事でより高度な対策が可能です。

セキュアでないコンテナランタイムの設定への対策

コンテナ及びランタイムの設定に不備がある場合、特権への昇格やホストOSのファイルシステムのマウント等による侵害を受ける可能性があります。これを防ぐ機能としてK8sではSecurityContextでの制限をクラスタに設ける事ができます。

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

コンテナが実行時に割り当てられるシステムレベルの機能、システムコールを制限(Seccomp)

seccompは Linux のセキュリティ機能で Linux カーネルに対して行うシステムコール(syscall)を制限するものです。EKSのワーカーノードを構成するKubelet引数にseccompを利用するよう指定しコンテナに制約を設ける事ができます。

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-seccomp-profile-for-a-container

https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/

-kubelet-extra-args "-seccomp-default"

securityContext:
  seccompProfile:
    type: RuntimeDefault

コンテナが特定のファイルパス,プロセス,およびソケットにのみアクセスするよう制限(SELinux,AppArmor)

SELinux,AppArmorはLinuxカーネルで利用できるセキュリティ機能です。Linuxではプロセスもデバイスも全てファイルシステムの一部として扱われます。このファイルシステムに対するアクセス制限を設ける事でOSレベルでセキュリティを担保できます。

SELinuxはRHEL/CentOS/Bottlerocket/Amazon Linux 2023で、AppArmorはDebian/Ubuntuでサポートされます。

https://aws.github.io/aws-eks-best-practices/security/docs/runtime/#apparmor-and-selinux

https://kubernetes.io/docs/tutorials/security/apparmor/

また、ランタイム保護機能を3rdPartyのCWP/CWPP製品でも提供されています。OS,クラスタレベルだけでは個別管理となりますが、製品を用いる事で一元管理や最新の脆弱性に合った対策を打つことが可能です。

アプリの脆弱性への対策

コンテナ内で実行されるアプリケーションに脆弱性がある場合、アプリケーションレベルでの攻撃や侵入が行われる可能性があります。これを防ぐために前回紹介した開発工程での対策があります。一方、NIST SP800-190では下記について指摘があります。

    [想定される操作、攻撃]

  • 無効な、または予期せぬプロセス / システムコールの実行
  • 保護された、または予期せぬ設定ファイルとバイナリの変更
  • 予期せぬネットワークの宛先に送信されたトラフィック

これらについては前述のSecurityContextである程度防ぐこともできますが、リアルタイムで不審な操作があった場合には対応しきれません。これを防ぐために3rdPartyのCWP/CWPP製品を活用することが有用です。

未承認コンテナへの対策

開発者がテストのために利用するコンテナや外部から取得したコンテナなどセキュリティ診断を受けていないコンテナがデプロイされるリスクがあります。こちらは前回記事のイメージリスクでも紹介した通り、イメージへの署名を用いる事で対策が取れます。

Signer/ECRを用いてECRのPushに合わせて署名

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/

Kyvernoを用いたデプロイ制限

署名を持ったイメージだけをPullできるKyvernoで制限をかける事が可能です。ClusterPolicyをEKSに適用する事ができ、承認したイメージだけをデプロイさせるよう設定できます。また、Kyvernoで定義されたポリシーはk8sオブジェクト(CRD含む)であるためGitOpsのCDツールでクラスタに適用、管理する事も可能です。

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

https://aws.amazon.com/jp/blogs/news/easy-as-one-two-three-policy-management-with-kyverno-on-amazon-eks/

apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
  name: check-image-notary
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  failurePolicy: Fail  
  rules:
    - name: verify-signature-notary
      match:
        any:
        - resources:
            kinds:
              - Pod
      verifyImages:
      - type: Notary
        imageReferences:
        - "ghcr.io/kyverno/test-verify-image*"
        attestors:
        - count: 1
          entries:
          - certificates:
              cert: |-
                -----BEGIN CERTIFICATE-----
                -----END CERTIFICATE-----

コンテナのリスクと対策

AWSサービスとOSSの組み合わせで稼働するコンテナやランタイムに対する脆弱性の検出や対策が行える事が分かりました。一方、OSSベースである事、K8sの設定に依存する項目があり、サポートがない中、ユーザ責で対策を立てる箇所が多い項目ともいえます。有償の3rdParty製品を用いる事でリアルタイム検出やマイクロセグメンテーションなどの機能を使えるだけでなく、サポートも得る事が出来ます。CWP/CWPP製品を利用する事も検討に入れてよいでしょう。

項目 詳細 AWSでの対策
ランタイムソフトウェア内の脆弱性 コンテナを動かすランタイム自体に脆弱性が含まれており攻撃/侵入されるリスク
  • Falco +CloudWatchによる脆弱性監視
  • GuardDuty Runtime Monitoingによる監視
コンテナからの無制限ネットワークアクセス コンテナ同士がネットワークを通じてアクセスでき攻撃/侵入されるリスク
  • DetectiveによるNW可視化
  • CWP/CWPP製品による可視化、NWアクセス管理
セキュアでないコンテナランタイムの設定 コンテナを動かすランタイム自体の設定不備が原因で脆弱性を含んでしまうリスク
  • Seccompによるシステムコール制限
  • SELinux,AppArmorによるアクセス制限
  • CWP/CWPP製品によるランタイム保護
アプリの脆弱性 稼働しているコンテナに脆弱性が含まれており、コンテナに対して攻撃/侵入されるリスク
  • 製造工程での脆弱性対策
  • SecurityContextでの操作制限
  • CWP/CWPP製品による振る舞い検知
未承認コンテナ 外部から取得したコンテナイメージや脆弱性診断をクリアしていないコンテナがデプロイされるリスク
  • イメージ署名とKyvernoを用いたPull制限

ホストOSのリスク

コンテナが稼働するためにはランタイム、それを管理するためにはオーケストレータが必要になりますが、さらにこれらが稼働するために必要なのがホストマシンとOSになります。

コンテナ技術は仮想マシンベースでの仮想化技術とは異なり、単一のマシン上でOSのライブラリレベルで仮想化したものになります。そのため、仮想マシンのようにカーネルやその下位のハードウェアレベルまで分断されておらず、OSをコンテナ間で共有する形となります。

こうしたコンテナの仕様からホストOS側で考えないといけないリスクは以下になります。

項目 詳細 対象
大きなアタックサーフェース 攻撃者がアクセス可能な範囲が広いほど、攻撃を受け、侵害を受けるリスク EC2/Fargate及びOS
共有カーネル 仮想化に比べると分離レベルが低く、攻撃を受けるリスクが高くなる EC2/Fargate及びOS
ホスト OS コンポーネントの脆弱性 ホストOSで稼働しているコンポーネントに脆弱性が存在する場合、攻撃を受けるリスク EC2/Fargate及びOS
不適切なユーザアクセス権 直接ホストOSにログインする場合、オーケストレータ経由で操作を行うよりも権限が大きくなるリスク EC2/Fargate及びOS
ホストファイルシステムの改ざん ホストOSのファイルを操作できる場合、ホストOS経由での攻撃を受けるリスク EC2/Fargate及びOS

大きなアタックサーフェースへの対策

ホストOSに便利だからとソフトウェアをapt,yumでインストールしたり、監視をしたいからとエージェントをOSにインストールするなどOSに足し算で機能を追加する事は危険です。なぜなら、脆弱性を含む余地を自ら増やしているからです。コンテナ基盤のホストOSに求められているのはワーカーノードとしてオーケストレータと連携が取れる事、ランタイムを稼働しコンテナを動かす事です。それ以外の機能は必須ではありません。

BottleRocketの利用

AWSではコンテナ機能に必要なものだけを含めたOSであるBottleRocketが提供されています。これにより攻撃対象を減らすだけではなく、コンテナ稼働にリソースを集中できるため性能面でもメリットがあります。一方、AddOnやエージェントを導入したい場合はコンテナをDaemonSetでデプロイする事でこれが可能になっています。この場合、OSには何も変更を加えません。他にもコンテナ用OSはありますが、AWSではBottleRocketを無償利用できるので他を選ぶ必要は特にないです。

https://aws.amazon.com/jp/bottlerocket/

https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

Fargateの利用

そもそもOS、ランタイムすらマネージドサービスであるFargateを使ってしまう事でアタックサーフェースを減らすだけでなく責任部分をAWS側に委任してしまう事も可能です。どうしてもEC2を利用する必要がないのであればFargate利用で特に問題ないです。

共有カーネルへの対策

コンテナは仮想マシンと異なり、OSのカーネルをコンテナ間で共有します。そのため、カーネルを介して別のコンテナに操作を加えたり、アクセスする余地があります。SecurityContextでの制御も可能ですが、カーネルをそもそも分割する、カーネル操作であるシステムコール制限をかける事が可能です。

Firecrackerによる制限

FirecrackerはLambda,Fargateの裏で使用されているランタイムです。

FirecrackerはMicroVMと呼ばれる極小の仮想マシンとして提供されています。つまりハイパーバイザーとコンテナランタイムの中間または組み合わせに近い構成で分割し孤立化させています。Fargateを用いる事で実質Firecrackerを利用する事ができます。

https://aws.amazon.com/jp/blogs/news/firecracker-lightweight-virtualization-for-serverless-computing/

近いアプローチとしてOSSのKataContainersがあります。また、カーネルへのシステムコールを制限するgVisorによるアプローチもあります。EKS利用であればFirecracker(≒Fargate)を利用で特に問題ないですが、他のOSを利用する場合はこのようなランタイムorハイパーバイザーを利用しましょう。

https://katacontainers.io/

https://gvisor.dev/

ホスト OS コンポーネントの脆弱性への対策

ホストOSで利用するソフトウェアコンポーネントを減らしても、必須となるコンポーネントについては引き続きアップデート、管理が必要です。このコンポーネントの脆弱性が放置されてしまえばリスクが発生するので対策が必要です。

BottleRocketの利用

ここでもBottleRocketを利用する事で対策が可能です。BottleRocketではOS更新が自動で行われます。必須コンポーネントについて脆弱性の解消が行われるのは有用です。

Fargateの利用

同じくFargate利用でここも対策をAWS側に委任することができます。一方、Fargate自体のアップデートやEKSのアップデート対応によりコンテナが一時的に停止し再起動されるため、過信はいけません。オーケストレータの更新に追従して更新するだけでなくメンテナンス時に停止する事を加味してRollingUpdateやEC2の退避先、Blue/Greenデプロイメントによる環境冗長化など対策を考えましょう。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/update-cluster.html

SystemsManagerによるアップデート

通常のEC2と同様にOSについてはSystemsManagerを使い、RunCommandやPatchManagerを利用しOSに対するアップデート対応を行う事が出来ます。BottleRocketやFargateでないOSを利用する場合には用いましょう。

不適切なユーザアクセス権への対策

直接ホストOSにログインする場合、オーケストレータ経由で操作を行うよりも強い権限で操作が行えてしまいます。root権限を取れれば、OSだけでなくランタイムやオーケストレータと連携するKubeletにまで操作ができます。

BottleRocketの利用

ここでもBottleRocketでの利用でこのリスクを回避できます。OSに直接SSHしてアクセスする事は原則行えません。どうしてもデバッグ確認を行いたい場合は管理コンテナ(busybox等)をデプロイしてコンテナから調査する事を推奨されています。

https://aws.amazon.com/jp/bottlerocket/faqs/

Fargateの利用

ここでも・・・Fargateのメリットが活きてきます。OSに対して操作できないからこそアクセスされる危険性がありません。一方、FargateはEC2に比べ性能が若干低減し利用料が増えます。コストパフォーマンスの点では見劣りしますが、管理をしなくてよい脆弱性を減らせる点では強いです。他の製品やサービスのライセンス利用料を払うよりもFargateを利用した方が実質のコストは安くなります。

SystemsManager SessionManagerによるアクセス

通常のEC2と同様にSessionManagerを用いて直接SSHせずIAMと紐づけてアクセスする事が可能になります。SSHキー管理やパブリックIPの付与や22番ポートの解放をセキュリティグループで行う必要もありません。BottleRocket,FargateでないAmazonLinuxや他のOSを利用する場合はSessionManagerを利用しましょう。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html

ホストファイルシステムの改ざんへの対策

ホストOSのファイルを操作できる場合、ホストOS経由での攻撃を受けるリスクが高くなります。OSに直接アクセスしての操作もそうですが、コンテナ経由でファイルシステムを操作されてしまう事についても対策が必要です。

BottleRocket,Fargateの利用

もはや言うまでなくありつつありますが・・・笑。OSに対して操作が行えなければこれらで対策も取れます。一方、コンテナ経由での操作については注意が必要です。コンテナが特権でOSに対して操作が行えてしまえば結果は変わらないからです。前述のコンテナリスクで触れたSecurityContextでrootでファイルシステムに対しての操作を行えないようにすることはここでも適用します。

https://docs.aws.amazon.com/ja_jp/whitepapers/latest/security-practices-multi-tenant-saas-applications-eks/forbid-running-tenant-containers-as-root.html

ホストOSのリスクと対策

こちらについてFargateを利用するだけでほぼ全てのリスクに対応できる事が分かります。一方で、Fargateは運用性が優れている反面、料金と性能の面でEC2に若干劣ります。EC2+セキュリティ製品/サービスの利用料と比較して最適なものを選択しましょう。また、過信もいけません。コンテナ経由での侵入や攻撃については別途対策は必要です。

そしてEC2を使うのであればBottleRocketを利用しコンテナを動かすだけの役割をOSに任せ、それ以外の機能はコンテナとして稼働させて対応します。それ以外のOSではSystemsManagerを活用しましょう。

項目 詳細 AWSでの対策
大きなアタックサーフェス 攻撃者がアクセス可能な範囲が広いほど、攻撃を受け、侵害を受けるリスク
  • BottleRocketの利用
  • Fargateの利用
共有カーネル 仮想化に比べると分離レベルが低く、攻撃を受けるリスクが高くなる
  • Firecrackerの利用
  • Fargateの利用
ホスト OS コンポーネントの脆弱性 ホストOSで稼働しているコンポーネントに脆弱性が存在する場合、攻撃を受けるリスク
  • BottleRocketの利用
  • Fargateの利用
  • SystemManagerでのアップデート
不適切なユーザアクセス権 直接ホストOSにログインする場合、オーケストレータ経由で操作を行うよりも権限が大きくなるリスク
  • BottleRocketの利用
  • Fargateの利用
  • SSMでのSSH
ホストファイルシステムの改ざん ホストOSのファイルを操作できる場合、ホストOS経由での攻撃を受けるリスク
  • BottleRocketの利用
  • Fargateの利用
  • SecurityContextの使用

まとめ

コンテナアプリケーションとそれを支えるコンテナオーケストレータの技術、そしてAWSのマネージドサービスでこれを実装することで強力なアプリケーションサービス提供が可能になります。

信頼性、運用性、コスト最適化、性能面での優位性を実現できる一方でセキュリティについてはユーザ責です。メリット以上の損失を生み出さないためにもセキュリティを満たした上でこの基盤を利用することを目指してみましょう。

AWSではこれを実現するために有用なサービスや機能が備わっておりますが、WellArchitectedFrameworkのレンズに明言されておらず、従来のIaaS/PaaSにはない観点での対策が求められます。

NIST SP800-190をベースに対策を立て最強のアプリケーションプラットフォームでビジネスを加速させましょう!

まずはSandbox/開発環境を用意する

そもそもK8sの扱い方がわからない、EKSのアップデートによって影響がないか確認したいといった場合にはSandbox環境(開発環境)を別に提供する事がおすすめです。本番クラスタに対しては上記の最小権限の原則とGitOpsを用いる事でセキュリティを担保できますが、問題発生時や経験の浅いメンバーが対応するには運用性は下がります。別の小規模環境を用意しこれを防ぐことも検討しましょう。

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

お問い合わせ



【著者プロフィール】

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

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

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

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

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

pagetop