Azure Policy の割り当て
Azure Policy のアドオンを有効にした状態は、あくまでもポリシーの機能を展開した状態です。ポリシーを割り当てるまでは、Azure Policy による監査や制約は受けません。Azure Policy は、イニシアティブ定義とポリシー定義から構成されており、イニシアティブ定義は、ポリシー定義をまとめたものです。一つ一つのポリシーを割り当てていくのは大変なため、あらかじめ用意されたイニシアティブ定義を使用することをお勧めします。
Azure Policy では、AKS のイニシアティブ定義として、以下の2つの定義があります。
- Linux ベースのワークロードの Kubernetes クラスターポッドのセキュリティ ベースライン標準イニシアティブ定義
- Linux ベースのワークロードに対する Kubernetes クラスター ポッド セキュリティの制限付き標準イニシアティブ定義
この2つの定義は含まれるポリシーが違います。「Linux ベースのワークロードの Kubernetes クラスターポッドのセキュリティ ベースライン標準」は緩いポリシー、「Linux ベースのワークロードに対する Kubernetes クラスター ポッド セキュリティの制限付き標準」は厳しいポリシーです。以下の表にそれぞれのポリシーをまとめました。
星マークが付いているポリシーは、明示的な指定が必要(指定しない場合展開が拒否される)ポリシーです。
監査モードと拒否モード
ポリシーは、割り当て時に「ポリシーの適用」で有効と無効を切り替えられます。
無効にした場合、Azure Policy によるリクエストの拒否はされず評価が行われるのみのためテスト時や既存環境に対する評価に使用できます。
評価で違反が確認された場合、Azure ポータル上で対象のポリシーや状態が確認できます。
詳細を確認すると対象の Pod が確認できます。
次に、いくつかのポリシーの意味と拒否モードにしている場合の展開時の動きを見てみましょう。
Kubernetes クラスターで特権コンテナーを許可しない
このポリシーは、特権コンテナを拒否します。特権コンテナは Linux のさまざまな特権を持ち、ホスト環境に対する操作も可能とします。例えば、ホストのデバイスの情報やマウントも可能です。特権コンテナは privileged を true にすると設定できます。
なお、privileged を true にした場合どのような特権が付与されるかまとめられたドキュメントが以下にあります。
Runtime privilege and Linux capabilities
以下は、特権コンテナ内からホストにアクセスするさまざまな操作をした例です。
root@nginx-privileged:/# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 100M 0 loop
sda 8:0 0 128G 0 disk
|-sda1 8:1 0 127.9G 0 part /etc/resolv.conf
|-sda14 8:14 0 4M 0 part
`-sda15 8:15 0 106M 0 part
sdb 8:16 0 8G 0 disk
`-sdb1 8:17 0 8G 0 part
root@nginx-privileged:/# mount /dev/sda1 /mnt
root@nginx-privileged:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 124G 22G 103G 18% /
tmpfs 64M 0 64M 0% /dev
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 124G 22G 103G 18% /mnt
shm 64M 0 64M 0% /dev/shm
tmpfs 2.0G 12K 2.0G 1% /run/secrets/kubernetes.io/serviceaccount
root@nginx-privileged:/# ls -l /mnt/
total 3840
-r--r--r-- 1 root root 3815996 Feb 24 04:17 NOTICE.txt
drwxr-xr-x 2 root root 4096 Feb 24 04:20 bin
drwxr-xr-x 4 root root 4096 Mar 18 06:46 boot
drwxr-xr-x 4 root root 4096 Jan 29 15:57 dev
drwxr-x--- 2 root root 4096 Mar 24 13:49 disk
以下は、このポリシーが適用されている環境で privileged が true となっているコンテナを展開した場合のメッセージ例です。
[azurepolicy-k8sazurecontainernoprivilegees-96719ae8867cc605f4ad] Privilege escalation container is not allowed: nginx-tsunomur): error when creating "nginx-tsunomur.yaml": admission webhook "validation.gatekeeper.sh" denied the request:
Kubernetes クラスターでコンテナーの特権エスカレーションを許可しない
このポリシーは、特権エスカレーションを許可しているコンテナを拒否します。具体的には allowPrivilegeEscalation が true となっているコンテナです。特権昇格が可能な場合、ping や sudo 等 setuid フラグの付いたプログラムが実行できるため、特定のシナリオにおいては便利なこともありますが、その反面プログラムの権限を広くすることを許してしまいます。
以下は、特権エスカレーションを拒否しているコンテナの挙動の例です。ping や sudo を実行できないことが確認できます。
test@nginx-disallowprivilegeescalation:~$ ping localhost
ping: socket: Operation not permitted
test@nginx-disallowprivilegeescalation:~$ sudo ls
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?
以下は、このポリシーが適用されている環境で allowPrivilegeEscalation が true となっているコンテナを展開した場合のメッセージ例です。
[azurepolicy-k8sazurecontainernoprivilegees-96719ae8867cc605f4ad] Privilege escalation container is not allowed: nginx-tsunomur
Kubernetes クラスター ポッドは許可されているボリュームの種類のみを使用する
これは、Pod から外部のボリュームへアクセスするための設定を制限するポリシーです。例えば、hostPath のようなボリュームは、コンテナのホストのファイルシステムをマウントできるためホストに対してファイルの参照や作成、削除ができてしまいます。そのようなアクションは攻撃の足がかりとして悪用できることがあるため、慎重に利用する必要があります。
以下は、hostpath でホストの /var/log をマウントしたマニフェストの例です。
apiVersion: v1
kind: Pod
metadata:
name: nginx-tsunomur
annotations:
seccomp.security.alpha.kubernetes.io/pod: runtime/default
spec:
containers:
- name: nginx-tsunomur
image: tsubasaxzzz/nonsecure-nginx:v0.0.1
command: ["sleep", "infinity"]
imagePullPolicy: Always
securityContext:
runAsUser: 101
runAsGroup: 101
allowPrivilegeEscalation: false
resources:
requests:
cpu: 1m
memory: 100Mi
limits:
cpu: 1m
memory: 100Mi
volumeMounts:
- name: data
mountPath: /data
- name: hostpath
mountPath: /hostpath
securityContext:
fsGroup: 101
supplementalGroups: [101]
volumes:
- name: data
emptyDir:
- name: hostpath
hostPath:
path: /var/log
type: Directory
terminationGracePeriodSeconds: 0
以下のようにコンテナ内からホストの /var/log へアクセスできます。
nginx@nginx-tsunomur:/$ ls -l /hostpath/
total 8756
-rw-r----- 1 root root 6105 Jun 29 05:01 alternatives.log
drwxr-xr-x 2 root root 4096 Jul 19 06:37 apt
-rw-r----- 1 102 adm 79647 Jul 20 03:35 auth.log
drwx------ 6 root root 4096 Jul 18 16:32 azure
-rw-r----- 1 root root 0 Jun 29 05:01 azure-cnimonitor.log
-rw-r----- 1 root root 43941 Jul 20 03:43 azure-vnet-ipam.log
-rw-r----- 1 root root 1617 Jul 18 16:32 azure-vnet-telemetry.log
-rw-r----- 1 root root 118353 Jul 20 03:43 azure-vnet.log
-rw-r----- 1 root root 0 Jun 29 05:01 blobfuse-driver.log
tail_buf_maxsize_megabytes = "1"
以下は、このポリシーが適用されている環境で hostpath を利用してマウントしている例です。
[azurepolicy-k8sazurevolumetypes-036fa302b1f45ea71594] The volume type hostPath is not allowed, pod: nginx-tsunomur. Allowed volume types: ["configMap", "emptyDir", "projected", "secret", "downwardAPI", "persistentVolumeClaim"]
ポリシーによる制限を考える
ポリシーによる制限は、コンテナに対して細かく機能を制限できるため、便利な機能です。しかし、制限できるからと言ってその制限に頼り切ることはあまりお勧めできません。コンテナのしくみは、あくまでも OS 上での分離をベースとした技術であり、ハイパーバイザーレベルの分離は提供できないということを念頭に置いておく必要があります。たとえば複数の組織が同じクラスタを利用する場合、1 つの組織のアプリケーションの動きがほかの組織のアプリケーションに影響を与える可能性があることを意味します。ポリシーによる制限で機能を制約することでセキュアに保つこともできますが、万が一 OS やポリシーのしくみに不具合や脆弱性があった場合、その境界が崩れる可能性も考えられます。
従って、複数の関係の薄い組織が機密度の高いデータを扱う場合等では、あえてクラスタを別けるという選択肢もあります。ポリシーはあくまでもガードレールの役割としてガバナンスを提供する一部の機能と考えると良いでしょう。
著者プロフィール
野村総合研究所 湯川勇太(ゆかわ ゆうた)
前職で大手家電量販店のECモールの立ち上げとECサイトの刷新プロジェクトを経験。NRI入社後は製造業の商品検索システムを担当した。現在は大手物流企業向けの基幹システムの方式設計や技術検証、トラブル対応を行っている。
Microsoft 乃村 翼 (のむら つばさ)
前職はコールセンターシステムを展開するスタートアップ企業で、Asterisk を用いたPBXシステムの構築、RailsやPHP等のOSSスタックを用いたWeb アプリケーションの開発を経験。アプリケーション基盤でLXCを使用していたことがきっかけで、コンテナ技術に興味を持つ。現在は、Microsoft CorporationのFastTrack for Azure のカスタマーエンジニアとして、Azureインフラを中心に設計・導入の支援を行っている。