組み込みの Linux セキュリティ機能を使用したリソースへのセキュリティ コンテナー アクセス
この記事では、Azure Kubernetes Service (AKS) ワークロードのリソースへのコンテナー アクセスをセキュリティで保護する方法について説明します。
概要
ユーザーまたはグループに必要最小限の特権を付与するのと同様に、コンテナーも必要なアクションとプロセスのみに制限するようにします。 攻撃のリスクを最小限に抑えるには、昇格された特権またはルート アクセスを必要とするアプリケーションとコンテナーを構成しないようにします。
組み込みの Kubernetes ポッドのセキュリティ コンテキストを使用して、実行するユーザーやグループ、公開する Linux 機能、ポッド マニフェストでの allowPrivilegeEscalation: false
の設定など、より多くのアクセス許可を定義できます。 その他のベスト プラクティスについては、リソースへのポッドのアクセスをセキュリティで保護する方法に関する記事を参照してください。
コンテナー アクションをさらに細かく制御するには、AppArmor や seccomp などの組み込みの Linux セキュリティ機能を使用できます。
- ノード レベルで Linux セキュリティ機能を定義します。
- ポッド マニフェストを使用して機能を実装します。
組み込みの Linux セキュリティ機能は、Linux ノードとポッドに対してのみ使用できます。
Note
現在、Kubernetes 環境は悪意のあるマルチテナントの使用に対して完全に安全ではありません。 Microsoft Defender for Containers、AppArmor、seccomp、Pod Security Admission、ノードの Kubernetes RBAC などの追加のセキュリティ機能は、悪用を効果的にブロックします。
悪意のあるマルチテナント ワークロードを実行する場合の真のセキュリティを実現するために、ハイパーバイザーのみを信頼してください。 Kubernetes 用のセキュリティ ドメインは、個々のノードではなく、クラスター全体になります。
この種の悪意のあるマルチテナント ワークロードでは、物理的に分離されたクラスターを使用する必要があります。
App Armor
コンテナー アクションを制限するために、AppArmor Linux カーネル セキュリティ モジュールを使用できます。 AppArmor は基となる AKS ノード OS に含まれており、既定で有効です。 読み取り、書き込み、実行のアクション、またはファイルシステムのマウントなどのシステム機能を制限する AppArmor プロファイルを作成します。 既定の AppArmor プロファイルでは、さまざまな /proc
と /sys
の場所へのアクセスが制限されており、基となるノードからコンテナーを論理的に分離する手段が用意されています。 AppArmor は、Kubernetes ポッドだけでなく、Linux 上で動作するあらゆるアプリケーションに対応しています。
AppArmor の動作を確認するために、次の例ではファイルへの書き込みを防止するプロファイルを作成します。
AKS ノードに SSH を接続します。
deny-write.profile という名前のファイルを作成します。
次のコンテンツをコピーして貼り付けます。
#include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, }
apparmor_parser
コマンドを使用して AppArmor プロファイルが追加されます。
プロファイルを AppArmor に追加します。
前の手順で作成したプロファイルの名前を指定します。
sudo apparmor_parser deny-write.profile
プロファイルが正しく解析され、AppArmor に適用された場合、出力は表示されず、コマンド プロンプトに戻ります。
ローカル コンピューターから、aks-apparmor.yaml という名前のポッド マニフェストを作成します。 このマニフェストにより:
container.apparmor.security.beta.kubernetes
の注釈を定義します。- 前の手順で作成した deny-write プロファイルを参照します。
apiVersion: v1 kind: Pod metadata: name: hello-apparmor annotations: container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write spec: containers: - name: hello image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
ポッドがデプロイされたら、次のコマンドを実行して、hello-apparmor ポッドに Running 状態が表示されていることを確認します。
kubectl get pods NAME READY STATUS RESTARTS AGE aks-ssh 1/1 Running 0 4m2s hello-apparmor 0/1 Running 0 50s
AppArmor の詳細については、Kubernetes の AppArmor プロファイルに関する記事を参照してください。
セキュア コンピューティング (seccomp)
AppArmor は任意の Linux アプリケーションで機能しますが、seccomp (secure computing) はプロセス レベルで機能します。 seccomp は Linux カーネルのセキュリティ モジュールでもあり、AKS ノードで使用される containerd
ランタイムでネイティブにサポートされています。 seccomp を使用してコンテナーのシステム コールを制限できます。 seccomp は、悪意のあるアクターが悪用する一般的なシステム コールの脆弱性に対して追加の保護レイヤーを確立し、ノード内のすべてのワークロードに既定のプロファイルを指定できるようにします。
既定の seccomp プロファイルを構成する (プレビュー)
新しい Linux ノード プールを作成する際に、カスタム ノード構成を使用して、既定の seccomp プロファイルを適用できます。 AKS では、 RuntimeDefault
と Unconfined
の 2 つの値がサポートされています。 ワークロードによっては、他のワークロードよりも低い数の syscall 制限が必要となる場合があります。 つまり、'RuntimeDefault' プロファイルを使用すると実行時に失敗する可能性が生じます。 Unconfined
プロファイルを指定すると、このような失敗を軽減することができます。 ワークロードでカスタム プロファイルが必要な場合は、「カスタム seccomp プロファイルを構成する」を参照してください。
制限事項
- SeccompDefault は、Windows ノード プールでサポートされているパラメーターではありません。
- SeccompDefault は、2024-09-02-preview API 以降で使用できます。
重要
AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は、運用環境での使用を意図していません。 詳細については、次のサポート記事を参照してください。
KubeletDefaultSeccompProfilePreview
機能フラグを登録する
az feature register
コマンドを使用して、KubeletDefaultSeccompProfilePreview
機能フラグを登録します。az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
状態が [登録済み] と表示されるまでに数分かかります。
az feature show
コマンドを使用して、登録の状態を確認します。az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
状態が Registered と表示されたら、
az provider register
コマンドを使用して Microsoft.ContainerService リソース プロバイダーの登録を最新の情報に更新します。az provider register --namespace Microsoft.ContainerService
seccomp を使用してコンテナーのシステム コールを制限する
1."seccompDefault": "RuntimeDefault"
を指定して、kubelet 構成に seccomp プロファイルを適用する手順に従います。
RuntimeDefault
は containerd の既定の seccomp プロファイルを使用し、特定のシステム呼び出しを制限してセキュリティを強化します。 制限付きの syscall は失敗します。 詳細については、「containerD の既定の seccomp プロファイル」を参照してください。
2.構成が適用されたことを確認します。
ホストに接続し、構成の変更がファイル システムで行われていることを確認すれば、ノードに設定が適用されたことを確認できます。
3.ワークロード エラーのトラブルシューティング。
SeccompDefault が有効になっている場合、コンテナー ランタイムの既定の seccomp プロファイルが、ノードでスケジュールされているすべてのワークロードに既定で使用されます。 その結果、ブロックされた syscall が原因でワークロードにエラーが発生する可能性があります。 ワークロード エラーが発生した場合は、次のようなエラーが表示されることがあります。
- 機能が有効になった後に想定外のワークロードが存在すると、「アクセス許可が拒否されました」というエラーが表示されます。
- seccomp のエラー メッセージは、既定のプロファイルで SCMP_ACT_ERRNO を SCMP_ACT_LOG に置き換えれば、auditd または syslog でも表示できます。
上記のエラーが発生した場合は、seccomp プロファイルを Unconfined
に変更することをお勧めします。 Unconfined
では syscall に制限はなく、すべてのシステム コールが許可され、セキュリティが低下します。
カスタム seccomp プロファイルを構成する
カスタム seccomp プロファイルを使用すると、制限付き syscall をより細かく制御できます。 次の方法で、実行する最小限のアクセス許可のみをコンテナーに付与するというベスト プラクティスに従います。
- フィルターを使用して、どのアクションを許可または拒否するかを定義する。
- ポッドの YAML マニフェスト内に、seccomp フィルターに関連付けるための注釈を付ける。
seccomp の動作を確認するには、ファイルに対するアクセス許可の変更を防止するフィルターを作成します。
AKS ノードに SSH を接続します。
/var/lib/kubelet/seccomp/prevent-chmod という名前の seccomp フィルターを作成します。
次のコンテンツをコピーして貼り付けます。
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO" }, { "name": "fchmodat", "action": "SCMP_ACT_ERRNO" }, { "name": "chmodat", "action": "SCMP_ACT_ERRNO" } ] }
バージョン 1.19 以降では、以下を構成する必要があります。
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "names": ["chmod","fchmodat","chmodat"], "action": "SCMP_ACT_ERRNO" } ] }
ローカル コンピューターから、aks-seccomp.yaml という名前のポッド マニフェストを作成し、次の内容を貼り付けます。 このマニフェストにより:
seccomp.security.alpha.kubernetes.io
の注釈を定義します。- 前の手順で作成した prevent-chmod フィルターを参照します。
apiVersion: v1 kind: Pod metadata: name: chmod-prevented annotations: seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod spec: containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
バージョン 1.19 以降では、以下を構成する必要があります。
apiVersion: v1 kind: Pod metadata: name: chmod-prevented spec: securityContext: seccompProfile: type: Localhost localhostProfile: prevent-chmod containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
kubectl apply コマンドを使用してサンプル ポッドを展開します。
kubectl apply -f ./aks-seccomp.yaml
kubectl get pods コマンドを使用して、ポッドの状態を確認します。
- ポッドからはエラーが報告されています。
- 出力例に示すように、
chmod
コマンドは seccomp フィルターでは実行されません。
kubectl get pods NAME READY STATUS RESTARTS AGE chmod-prevented 0/1 Error 0 7s
seccomp セキュリティ プロファイル のオプション
seccomp セキュリティ プロファイルは、許可また制限された定義済みの syscall がまとめられたものです。 ほとんどのコンテナー ランタイムには既定の seccomp プロファイルがあり、Docker で使用されているものと同じではありませんが類似しています。 使用可能なプロファイルの詳細については、「Docker または containerD の既定の seccomp プロファイル」を参照してください。
AKS では、カスタム ノード構成を使用して seccomp を構成する場合、RuntimeDefault 用に containerD の既定の seccomp プロファイルを使用します。
既定のプロファイルでブロックされた重要な syscall
Docker と containerD の両方で、安全な syscall の許可リストを管理します。 次の表に、許可リストになく、効果的にブロックされる重要な syscall の一部を示します。 ブロックされた syscall のいずれかがワークロードで必要な場合は、RuntimeDefault
seccomp プロファイルを使用しないでください。
Docker と containerD に変更が加えられた場合、AKS は既定の構成と一致するように更新します。 このリストを更新すると、ワークロード エラーが発生する可能性があります。 リリースの最新情報については、「AKS リリース ノート」を参照してください。
ブロックされた syscall | 説明 |
---|---|
acct |
コンテナーが独自のリソース制限を無効にしたり、アカウンティングを処理したりできるアカウンティング syscall。 また、CAP_SYS_PACCT によって制限されます。 |
add_key |
コンテナーで名前空間が設定されていないカーネル キーリングを使用できないようにします。 |
bpf |
永続的な可能性がある bpf プログラムをカーネルに読み込むのを拒否します。CAP_SYS_ADMIN によって制限済みです。 |
clock_adjtime |
時刻と日付は名前空間には含まれません。 また、CAP_SYS_TIME によって制限されます。 |
clock_settime |
時刻と日付は名前空間には含まれません。 また、CAP_SYS_TIME によって制限されます。 |
clone |
新しい名前空間の複製を拒否します。 また、CLONE_NEWUSER を除き、CAP_SYS_ADMIN for CLONE_* フラグによって制限されます。 |
create_module |
カーネル モジュールの操作と関数を拒否します。 互換性のために残されています。 また、CAP_SYS_MODULE によって制限されます。 |
delete_module |
カーネル モジュールの操作と関数を拒否します。 また、CAP_SYS_MODULE によって制限されます。 |
finit_module |
カーネル モジュールの操作と関数を拒否します。 また、CAP_SYS_MODULE によって制限されます。 |
get_kernel_syms |
エクスポートされたカーネル シンボルとモジュール シンボルの取得を拒否します。 互換性のために残されています。 |
get_mempolicy |
カーネル メモリと NUMA 設定を変更する Syscall。 CAP_SYS_NICE によって制限済みです。 |
init_module |
カーネル モジュールの操作と関数を拒否します。 また、CAP_SYS_MODULE によって制限されます。 |
ioperm |
コンテナーがカーネル I/O 特権レベルを変更できないようにします。 CAP_SYS_RAWIO によって制限済みです。 |
iopl |
コンテナーがカーネル I/O 特権レベルを変更できないようにします。 CAP_SYS_RAWIO によって制限済みです。 |
kcmp |
CAP_SYS_PTRACE を削除して既にブロックされているプロセス検査機能を制限します。 |
kexec_file_load |
同じ処理を実行するが一部の引数が異なる kexec_load の類似 syscall。 また、CAP_SYS_BOOT によって制限されます。 |
kexec_load |
後で実行される新しいカーネルの読み込みを拒否します。 また、CAP_SYS_BOOT によって制限されます。 |
keyctl |
コンテナーで名前空間が設定されていないカーネル キーリングを使用できないようにします。 |
lookup_dcookie |
ホスト上の情報が漏洩する可能性のあるトレース / プロファイリング syscall。 また、CAP_SYS_ADMIN によって制限されます。 |
mbind |
カーネル メモリと NUMA 設定を変更する Syscall。 CAP_SYS_NICE によって制限済みです。 |
mount |
マウントを拒否します。CAP_SYS_ADMIN によって制限済みです。 |
move_pages |
カーネル メモリと NUMA 設定を変更する Syscall。 |
nfsservctl |
カーネル nfs デーモンとの相互作用を拒否します。 Linux 3.1 以降は廃止されました。 |
open_by_handle_at |
以前のコンテナー ブレークアウトの原因。 また、CAP_DAC_READ_SEARCH によって制限されます。 |
perf_event_open |
ホスト上の情報が漏洩する可能性のあるトレース / プロファイリング syscall。 |
personality |
コンテナーが BSD エミュレーションを有効にできないようにします。 それ自体が危険なものではありませんが、テストが不十分で、カーネルに脆弱性が生じる可能性があります。 |
pivot_root |
特権操作であるべき pivot_root を拒否します。 |
process_vm_readv |
CAP_SYS_PTRACE を削除して既にブロックされているプロセス検査機能を制限します。 |
process_vm_writev |
CAP_SYS_PTRACE を削除して既にブロックされているプロセス検査機能を制限します。 |
ptrace |
syscall のトレース / プロファイリング。 seccomp のバイパスを避けるために、4.8 より前の Linux カーネル バージョンでブロックされました。 任意のプロセスのトレース / プロファイリングは、ホスト上の情報が漏洩する可能性があるため、CAP_SYS_PTRACE を削除してブロック済みです。 |
query_module |
カーネル モジュールの操作と関数を拒否します。 互換性のために残されています。 |
quotactl |
コンテナーが独自のリソース制限やプロセス アカウンティングを無効にできるクォータ syscall。 また、CAP_SYS_ADMIN によって制限されます。 |
reboot |
コンテナーがホストを再起動しないようにします。 また、CAP_SYS_BOOT によって制限されます。 |
request_key |
コンテナーで名前空間が設定されていないカーネル キーリングを使用できないようにします。 |
set_mempolicy |
カーネル メモリと NUMA 設定を変更する Syscall。 CAP_SYS_NICE によって制限済みです。 |
setns |
スレッドと名前空間の関連付けを拒否します。 また、CAP_SYS_ADMIN によって制限されます。 |
settimeofday |
時刻と日付は名前空間には含まれません。 また、CAP_SYS_TIME によって制限されます。 |
stime |
時刻と日付は名前空間には含まれません。 また、CAP_SYS_TIME によって制限されます。 |
swapon |
ファイル / デバイスへのスワップの開始 / 停止を拒否します。 また、CAP_SYS_ADMIN によって制限されます。 |
swapoff |
ファイル / デバイスへのスワップの開始 / 停止を拒否します。 また、CAP_SYS_ADMIN によって制限されます。 |
sysfs |
廃止された syscall。 |
_sysctl |
廃止され、/proc/sys に置き換えられました。 |
umount |
特権操作である必要があります。 また、CAP_SYS_ADMIN によって制限されます。 |
umount2 |
特権操作である必要があります。 また、CAP_SYS_ADMIN によって制限されます。 |
unshare |
プロセスの新しい名前空間の複製を拒否します。 また、--user の共有を解除する場合を除き、CAP_SYS_ADMIN によって制限されます。 |
uselib |
長期間使用されていない共有ライブラリに関連する以前の syscall。 |
userfaultfd |
主にプロセスの移行に必要なユーザースペースのページ フォールトの処理。 |
ustat |
廃止された syscall。 |
vm86 |
カーネル x86 リアルモードの仮想マシン。 また、CAP_SYS_ADMIN によって制限されます。 |
vm86old |
カーネル x86 リアルモードの仮想マシン。 また、CAP_SYS_ADMIN によって制限されます。 |
次のステップ
関連付けられているベスト プラクティスについては、AKS でのクラスターのセキュリティとアップグレードに関するベスト プラクティスのページと、AKS でのポッドのセキュリティに関するベスト プラクティスのページを参照してください。
Azure Kubernetes Service