LoginSignup
1
0

Microsoft Defender for Containers の活用 - クラスターに Azure ポリシーを適用してベストプラクティスを理解する

Last updated at Posted at 2023-07-25

1. はじめに

Microsoft Defender for Containers では Kubernetes 用の Azure ポリシーをクラスター環境に適用することで、Microsoft Defender for Cloud の推奨事項にクラスター構成のセキュリティベストプラクティスのチェックを行うことが出来るようになっています。
設定方法やチューニングなどが若干必要になっており、見方などが分かり難いので本記事でまとめています。詳細は以下公式 Docs を参照してください。

2. 事前準備 - AKS クラスターに Azure ポリシーを適用する

AKS クラスターに Azure ポリシーを適用する方法は 2 つありますが、前者の設定が簡単なのでお勧めです。

  1. Microsoft Defender for Cloud の「環境設定」で Azure ポリシー適用を有効にしておく

    • Microsoft Defender for Containers の有効化時にオプションとして定義する設定で有効化することが出来ます。
    • 初期構成で設定を無効にした場合でも、後で手動で有効にすることができます。
    • image.png
  2. 特定のクラスターに関する推奨事項を使用して、アドオンをクラスターに手動でデプロイする

    • 複数のクラスターが存在しており、特定のクラスターに対して有効化する場合は、以下の推奨事項より、手動で設定することが出来ます。
      1. Azure Kubernetes Service クラスターには Kubernetes 用の Azure Policy アドオンがインストールされている必要がある
      2. Azure Policy add-on for Kubernetes should be installed and enabled on your clusters
      3. Azure policy extension for Kubernetes should be installed and enabled on your clusters
      4. image.png

3. Kubernetes 向け推奨事項を理解する

3.1 クラスター向け Azure ポリシーのリスト

Kubernetes クラスターに提供されている Azure ポリシーはパラメータチューニング不要で動くものと、自社環境に合ったパラメータを入れて成立する推奨事項が提供されています。ケースによっては自社環境にとって監視不要な項目も判断して、必要な推奨事項を採択しましょう。

推奨事項の名前 重大度 セキュリティ制御 パラメータ構成が必要
コンテナーの CPU とメモリの制限を強制する必要がある DDoS 攻撃からのアプリケーションの保護 必要
コンテナー イメージは信頼されたレジストリからのみデプロイする必要がある 脆弱性の修復 必要
コンテナーで最小限の特権を持つ Linux 機能を適用する必要がある アクセスおよびアクセス許可の管理 必要
コンテナーでは、許可されている AppArmor プロファイルのみを使用する セキュリティ構成の修復 必要
サービスは許可されたポートでのみリッスンする必要がある 承認されていないネットワーク 必要
ホストネットワークとポートの使用を制限する必要がある 承認されていないネットワークアクセスの制限 必要
ポッド HostPath ボリューム マウントの使用は既知のリストに制限する必要がある アクセスおよびアクセス許可の管理 必要
特権エスカレーションを含むコンテナーは避ける必要がある アクセスおよびアクセス許可の管理 不要
機密性の高いホストの名前空間を共有するコンテナーは避ける必要がある アクセスおよびアクセス許可の管理 不要
コンテナーで不変 (読み取り専用) のルートファイル システムを適用する必要がある アクセスおよびアクセス許可の管理 不要
Kubernetes クラスターは HTTPS 経由でのみアクセス可能である必要がある 転送中のデータを暗号化する 不要
Kubernetes クラスターで API 資格情報の自動マウントを無効にする必要がある アクセスおよびアクセス許可の管理 不要
Kubernetes クラスターでは既定の名前空間を使用しない セキュリティのベストプラクティスを実装する 不要
Kubernetes クラスターでは CAPSYSADMIN セキュリティ機能を許可しない アクセスおよびアクセス許可の管理 不要
特権コンテナーの使用を避ける アクセスおよびアクセス許可の管理 不要
コンテナーをルート ユーザーとして実行しない アクセスおよびアクセス許可の管理 不要

3.2 推奨事項をテストするためのテンプレート

Azure ポリシーの推奨事項を判定するためのサンプルの YAML テンプレートが公開されています。
実際に検知した際の動作や、自社環境で検知する理由の原因分析・判定に利用しましょう。

  • 正常なデプロイのサンプル.yaml ファイル
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-healthy-deployment
  labels:
    app: redis
spec:
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
      annotations:
        container.apparmor.security.beta.kubernetes.io/redis: runtime/default
    spec:
      containers:
      - name: redis
        image: <customer-registry>.azurecr.io/redis:latest
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 100m
            memory: 250Mi
        securityContext:
          privileged: false
          readOnlyRootFilesystem: true
          allowPrivilegeEscalation: false
          runAsNonRoot: true
          runAsUser: 1000
---
apiVersion: v1
kind: Service
metadata:
  name: redis-healthy-service
spec:
  type: LoadBalancer
  selector:
    app: redis
  ports:
  - port: 80
    targetPort: 80

  • 異常なデプロイのサンプル.yaml ファイル (構成に以下が含まれています)
    • レポジトリを用いていない
    • Pod 側での CPU / Memory 制限を用いていない
    • apparmor 未使用
    • 特権コンテナー privileged: true
    • ReadOnly ではない readOnlyRootFilesystem: false
    • 特権エスカレーションが含まれる allowPrivilegeEscalation: true
    • root ユーザーでの実行 runAsUser: 0
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-unhealthy-deployment
  labels:
    app: redis
spec:
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:      
      labels:
        app: redis
    spec:
      hostNetwork: true
      hostPID: true 
      hostIPC: true
      containers:
      - name: redis
        image: redis:latest
        ports:
        - containerPort: 9001
          hostPort: 9001
        securityContext:
          privileged: true
          readOnlyRootFilesystem: false
          allowPrivilegeEscalation: true
          runAsUser: 0
          capabilities:
            add:
              - NET_ADMIN
        volumeMounts:
        - mountPath: /test-pd
          name: test-volume
          readOnly: true
      volumes:
      - name: test-volume
        hostPath:
          # directory location on host
          path: /tmp
---
apiVersion: v1
kind: Service
metadata:
  name: redis-unhealthy-service
spec:
  type: LoadBalancer
  selector:
    app: redis
  ports:
  - port: 6001
    targetPort: 9001

3.3 詳細

個々の推奨事項の詳細は公式 Docs を参照ください。

コンテナーの CPU とメモリの制限を強制する必要がある

        resources:
          limits:
            cpu: 100m     # Pod の CPU を制限
            memory: 250Mi # Pod の Memory を制限

コンテナーの起動に対して制限をかけるパラメータ項目です。
CPU とメモリの制限を適用することでリソース枯渇攻撃 (サービス拒否攻撃の一種) を防ぐことができます。
コンテナーに制限を設定し、設定された制限を超えてリソースがコンテナーで使用されないように、ランタイムによって防ぐことをお勧めします。
パラメータとしては以下項目を設定する必要がありますので、自社環境に合ったパラメータを検討しましょう。

パラメータ 説明 デフォルト値
Max allowed CPU units in Kubernetes cluster コンテナーに許可される最大 CPU ユニット数を定義します。詳細については、https://aka.ms/k8s-policy-pod-limits を参照してください。 32
Max allowed memory bytes in Kubernetes cluster Kubernetes クラスターで許可される最大メモリ バイト数 64Gi
Kubernetes namespaces to exclude from monitoring of memory and CPU limits 評価から除外する Kubernetes 名前空間のリスト。 複数の名前空間をリストするには、セミコロン (;) を使用して名前空間を区切ります。 システム名前空間「kube-system」、「gatekeeper-system」、および「azure-arc」は、設計により常に除外されます。 [ "kube-system", "gatekeeper-system", "azure-arc", "azuredefender", "mdc", "azure-extensions-usage-system"]
Kubernetes image to exclude from monitoring of all container related polices Kubernetes コンテナ関連のポリシー評価から除外する InitContainers とコンテナのリスト。 これは、「コンテナ イメージは信頼できるレジストリからのみデプロイする必要がある」と「Kubernetes クラスタは脆弱なイメージのデプロイをゲートする必要がある」を除く、すべてのコンテナ関連のポリシーに適用されます。 []

Defender for Cloud のポリシー画面からは以下設定画面が表示されます。
image.png

コンテナー イメージは信頼されたレジストリからのみデプロイする必要がある

    spec:
      containers:
        image: <customer-registry>.azurecr.io/redis:latest # レジストリ指定

Azure Container Registory (ACR) からの AKS クラスターへ Pod デプロイする際に「信頼された」レジストリーからのみに限定するようにポリシーを適用することが出来ます。
Kubernetes クラスターで実行されているイメージは、監視対象になっている既知のコンテナー イメージ レジストリのものである必要があります。信頼できるレジストリにより、不明な脆弱性、セキュリティの問題、悪意のあるイメージが持ち込まれる可能性が制限され、クラスターが危険にさらされるリスクが減ります
正規表現 (regex) を用いて、ACR の名称を定義する設定が必要になります。

パラメータ 説明 デフォルト値
Allowed registry or registries regex Kubernetes クラスターで許可されているコンテナー イメージ フィールドと一致するために使用される正規表現。
たとえば、部分パスを一致させることで任意の Azure Container Registry イメージを許可するには: ^[^\/]+\.azurecr\.io\/.+$、複数のレジストリの場合: ^([^\/]+\.azurecr\.io|registry\.io)\/.+$
^(.+){0}$
Kubernetes namespaces to exclude from monitoring of allowed container images 評価から除外する Kubernetes 名前空間のリスト。 複数の名前空間をリストするには、セミコロン (;) を使用して名前空間を区切ります。 システム名前空間「kube-system」、「gatekeeper-system」、および「azure-arc」は、設計により常に除外されます。 [ "kube-system", "gatekeeper-system", "azure-arc", "azuredefender", "mdc", "azure-extensions-usage-system"]

Defender for Cloud のポリシー画面からは以下設定画面が表示されます。
image.png

コンテナーで最小限の特権を持つ Linux 機能を適用する必要がある

コンテナーの攻撃面を減らすには、Linux の機能を制限し、ルート ユーザーのすべての特権をコンテナーに付与するのではなく、特定の特権を付与してください。
パラメータとしては以下項目を設定する必要があります。

パラメータ 説明 デフォルト値
Kubernetes namespaces to exclude from monitoring of containers use only allowed capabilities Kubernetes クラスターで許可された機能のみを使用するコンテナーの評価から監視から除外する Kubernetes 名前空間のリスト。 複数の名前空間をリストするには、セミコロン (;) を使用して名前空間を区切ります。 システム名前空間「kube-system」、「gatekeeper-system」、および「azure-arc」は、設計により常に除外されます。 [ "kube-system", "gatekeeper-system", "azure-arc", "azuredefender", "mdc", "azure-extensions-usage-system"]
Allowed capabilities コンテナへの追加が許可されている機能のリスト。 すべてをブロックするには、入力として空のリストを指定します。 []
Required drop capabilities コンテナーによって削除される必要がある機能のリスト。 []
Kubernetes image to exclude from monitoring of all container related polices 評価から除外する InitContainers とコンテナのリスト。 これは、「コンテナ イメージは信頼できるレジストリからのみデプロイする必要がある」と「Kubernetes クラスタは脆弱なイメージのデプロイをゲートする必要がある」を除く、すべてのコンテナ関連のポリシーに適用されます。 識別子はコンテナのイメージです。 接頭辞一致は「*」で表すことができます。 例: myregistry.azurecr.io/istio:*。 信頼できないリポジトリからイメージが予期せず除外されることを避けるために、ユーザーは完全修飾された Docker イメージ名 (ドメイン名で始まるなど) を使用することをお勧めします。 []

Defender for Cloud のポリシー画面からは以下設定画面が表示されます。
image.png

コンテナーでは、許可されている AppArmor プロファイルのみを使用する

# AppArmor プロファイルの例
      annotations:
        container.apparmor.security.beta.kubernetes.io/redis: runtime/default 

Kubernetes クラスターで実行されているコンテナーは、許可されている AppArmor プロファイルのみに制限してください。AppArmor (Application Armor) は、オペレーティング システムとそのアプリケーションをセキュリティの脅威から保護する Linux セキュリティ モジュールです。これを使用するには、システム管理者が AppArmor セキュリティ プロファイルを各プログラムに関連付けます。

サービスは許可されたポートでのみリッスンする必要がある

  ports:
  - port: 80
    targetPort: 80 # サービスのポート指定例

Kubernetes クラスターの攻撃面を減らすために、サービスのアクセスを構成済みポートに制限して、クラスターへのアクセスを制限します。事前にパラメータ設定が必要です。

パラメータ 説明 デフォルト値
Allowed service ports list in Kubernetes cluster Kubernetes クラスターで許可されるサービス ポートのリスト。 配列は文字列のみを受け入れます。 例: ["443", "80"] 初期値は無効状態
[ "-1"]
Kubernetes namespaces to exclude from monitoring of allowed service ports 対象外とする名前区間 [ "kube-system", "gatekeeper-system", "azure-arc", "azure-extensions-usage-system"]

Defender for Cloud のポリシー画面からは以下設定画面が表示されます。
image.png

ホストネットワークとポートの使用を制限する必要がある

        ports:
        - containerPort: 80

ポッドのアクセスを、Kubernetes クラスター内のホスト ネットワークおよび許容されるホスト ポート範囲に制限します。 hostNetwork 属性を有効にして作成されたポッドの間では、ノードのネットワーク領域が共有されます。 セキュリティ侵害を受けたコンテナーによってネットワーク トラフィックがスニッフィングされるのを防ぐため、ホスト ネットワークにはポッドを配置しないことをお勧めします。

コンテナー ポートをノード ネットワークに公開する必要があり、Kubernetes Service ノード ポートを使用してもニーズが満たされない場合は、ポッド仕様のコンテナーに対して hostPort を指定することもできます。

パラメータ 説明 デフォルト値
Kubernetes namespaces to exclude from monitoring of containers host networking and ports 除外対象とする名前空間 [ "kube-system", "gatekeeper-system", "azure-arc", "azure-extensions-usage-system"]
Allow host network usage ポッドがホスト ネットワークの使用を許可されている場合はこの値を true に設定し、それ以外の場合は false に設定します。 false
Min host port for pod in Kubernetes cluster ポッドがホスト ネットワーク名前空間で使用できる、許容されるホスト ポート範囲の最小値。 0
Max host port for pod in Kubernetes cluster ポッドがホスト ネットワーク名前空間で使用できる、許容されるホスト ポート範囲の最大値。 0
Kubernetes image to exclude from monitoring of all container related polices Kubernetes コンテナ関連のポリシー評価から除外する InitContainers とコンテナのリスト。 これは、「コンテナ イメージは信頼できるレジストリからのみデプロイする必要がある」と「Kubernetes クラスタは脆弱なイメージのデプロイをゲートする必要がある」を除く、すべてのコンテナ関連のポリシーに適用されます。 識別子はコンテナのイメージです。 接頭辞一致は「*」で表すことができます。 例: myregistry.azurecr.io/istio:*。 信頼できないリポジトリからイメージが予期せず除外されることを避けるために、ユーザーは完全修飾された Docker イメージ名 (ドメイン名で始まるなど) を使用することをお勧めします。 []

Defender for Cloud のポリシー画面からは以下設定画面が表示されます。
image.png

ポッド HostPath ボリューム マウントの使用は既知のリストに制限する必要がある

      volumes:
      - name: test-volume
        hostPath:
          # directory location on host
          path: /tmp

Kubernetes クラスター内のポッドの HostPath ボリューム マウントを、構成済みの許可されているホスト パスに制限することをお勧めします。 侵害を受けた場合は、コンテナーからのコンテナー ノード アクセスを制限する必要があります。

特権エスカレーションを含むコンテナーは避ける必要がある

        securityContext:
          allowPrivilegeEscalation: false # 特権昇格は利用させない

Kubernetes クラスター内のポッドの HostPath ボリューム マウントを、構成済みの許可されているホスト パスに制限することをお勧めします。 侵害を受けた場合は、コンテナーからのコンテナー ノード アクセスを制限する必要があります。

機密性の高いホストの名前空間を共有するコンテナーは避ける必要がある

Kubernetes クラスター内のポッドの HostPath ボリューム マウントを、構成済みの許可されているホスト パスに制限することをお勧めします。 侵害を受けた場合は、コンテナーからのコンテナー ノード アクセスを制限する必要があります。

コンテナーで不変 (読み取り専用) のルートファイル システムを適用する必要がある

        securityContext:
          readOnlyRootFilesystem: true # Pod のルートファイルシステムを読み取り専用にする

お使いの Kubernetes クラスターでは、読み取り専用のルート ファイル システムを使用してコンテナーを実行してください。 不変のファイル システムは、PATH に追加された悪意のあるバイナリによる実行時の変更から、コンテナーを保護します。

Kubernetes クラスターは HTTPS 経由でのみアクセス可能である必要がある

HTTPS を使用すると、認証が確実に実行され、転送中のデータがネットワーク層の傍受攻撃から保護されます。

Kubernetes クラスターで API 資格情報の自動マウントを無効にする必要がある

侵害された可能性のある Pod リソースが Kubernetes クラスターに対して API コマンドを実行するのを防ぐために、API 資格情報の自動マウントを無効にします。

Kubernetes クラスターでは既定の名前空間を使用しない

ConfigMap、Pod、Secret、Service、および ServiceAccount という種類のリソースを無許可アクセスから保護するために、Kubernetes クラスターで既定 (Default) の名前空間を使用しないようにします。

Kubernetes クラスターでは CAPSYSADMIN セキュリティ機能を許可しない

コンテナーに対する攻撃面を縮小するには、Linux 機能 CAP_SYS_ADMIN を制限します。CAP_SYS_ADMIN は最も特権のある機能であり、常に回避する必要があります。

特権コンテナーの使用を避ける

        securityContext:
          privileged: false

無制限のホスト アクセスを制限するには、できる限り特権コンテナーは使わないようにします。
特権コンテナーには、ホスト マシンのすべてのルート機能が含まれています。 これらは攻撃のエントリ ポイントとして使用されたり、侵害されたアプリケーション、ホスト、ネットワークに悪意のあるコードやマルウェアを拡散させるために使用されたりする可能性があります。

コンテナーをルート ユーザーとして実行しない

          runAsNonRoot: true
          runAsUser: 1000

お使いの Kubernetes クラスターでは、ルート ユーザーとしてコンテナーを実行しないでください。 コンテナー内でプロセスをルート ユーザーとして実行すると、それはホスト上のルートとして実行されます。 侵害を受けた場合、攻撃者はコンテナーのルート権限を持つことになり、構成ミスを悪用しやすくなります。

システム系の namespace はパラメータで除外されていますが、誤検知するようであればパラメータ設定を見直してみてください。

パラメータ 説明 デフォルト値
Kubernetes namespaces to exclude from monitoring of containers host networking and ports 除外対象とする名前空間 [ "kube-system", "gatekeeper-system", "azure-arc", "azure-extensions-usage-system"]
Kubernetes image to exclude from monitoring of all container related polices Kubernetes コンテナ関連のポリシー評価から除外する InitContainers とコンテナのリスト。 これは、「コンテナ イメージは信頼できるレジストリからのみデプロイする必要がある」と「Kubernetes クラスタは脆弱なイメージのデプロイをゲートする必要がある」を除く、すべてのコンテナ関連のポリシーに適用されます。 識別子はコンテナのイメージです。 接頭辞一致は「*」で表すことができます。 例: myregistry.azurecr.io/istio:*。 信頼できないリポジトリからイメージが予期せず除外されることを避けるために、ユーザーは完全修飾された Docker イメージ名 (ドメイン名で始まるなど) を使用することをお勧めします。 []

image.png

参考情報など

4. まとめ

以上、Microsoft Defender for Containers 適用時に設定可能な Azure ポリシーのまとめでした。K8s のセキュリティベストプラクティスが基準になっており、仕組みや内容を理解して推奨事項の判断を適切に行う必要がありますが、自社の AKS 環境のチェックにうまくご活用いただければと思います。本記事がどなたかの参考になれば幸いです。

*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0