1 - クラウドネイティブセキュリティの概要

この概要では、クラウドネイティブセキュリティにおけるKubernetesのセキュリティを考えるためのモデルを定義します。

クラウドネイティブセキュリティの4C

セキュリティは階層で考えることができます。クラウドネイティブの4Cは、クラウド、クラスター、コンテナ、そしてコードです。

クラウドネイティブセキュリティの4C

クラウドネイティブセキュリティモデルの各レイヤーは次の最も外側のレイヤー上に構築します。コードレイヤーは、強固な基盤(クラウド、クラスター、コンテナ)セキュリティレイヤーから恩恵を受けます。コードレベルのセキュリティに対応しても基盤レイヤーが低い水準のセキュリティでは守ることができません。

クラウド

いろいろな意味でも、クラウド(または同じ場所に設置されたサーバー、企業のデータセンター)はKubernetesクラスターのトラステッド・コンピューティング・ベースです。クラウドレイヤーが脆弱な(または脆弱な方法で構成されている)場合、この基盤の上に構築されたコンポーネントが安全であるという保証はありません。各クラウドプロバイダーは、それぞれの環境でワークロードを安全に実行させるためのセキュリティの推奨事項を作成しています。

クラウドプロバイダーのセキュリティ

Kubernetesクラスターを所有しているハードウェアや様々なクラウドプロバイダー上で実行している場合、セキュリティのベストプラクティスに関するドキュメントを参考にしてください。ここでは人気のあるクラウドプロバイダーのセキュリティドキュメントの一部のリンクを紹介します。

Cloud provider security
IaaSプロバイダーリンク
Alibaba Cloudhttps://www.alibabacloud.com/trust-center
Amazon Web Serviceshttps://aws.amazon.com/security/
Google Cloud Platformhttps://cloud.google.com/security/
Huawei Cloudhttps://www.huaweicloud.com/intl/ja-jp/securecenter/overallsafety.html
IBM Cloudhttps://www.ibm.com/cloud/security
Microsoft Azurehttps://docs.microsoft.com/en-us/azure/security/azure-security
Oracle Cloud Infrastructurehttps://www.oracle.com/security/
VMWare VSpherehttps://www.vmware.com/security/hardening-guides.html

インフラのセキュリティ

Kubernetesクラスターのインフラを保護するための提案です。

Infrastructure security
Kubernetesインフラに関する懸念事項推奨事項
API Server(コントロールプレーン)へのネットワークアクセスKubernetesコントロールプレーンへのすべてのアクセスは、インターネット上での一般公開は許されず、クラスター管理に必要なIPアドレスに制限するネットワークアクセス制御リストによって制御されます。
NodeへのネットワークアクセスNodeはコントロールプレーンの特定ポート のみ 接続(ネットワークアクセス制御リストを介して)を受け入れるよう設定し、NodePortとLoadBalancerタイプのKubernetesのServiceに関する接続を受け入れるよう設定する必要があります。可能であれば、それらのNodeはパブリックなインターネットに完全公開しないでください。
KubernetesからのクラウドプロバイダーAPIへのアクセス各クラウドプロバイダーはKubernetesコントロールプレーンとNodeに異なる権限を与える必要があります。最小権限の原則に従い、管理に必要なリソースに対してクラウドプロバイダーへのアクセスをクラスターに提供するのが最善です。KopsドキュメントにはIAMのポリシーとロールについての情報が記載されています。
etcdへのアクセスetcd(Kubernetesのデータストア)へのアクセスはコントロールプレーンのみに制限すべきです。設定によっては、TLS経由でetcdを利用する必要があります。詳細な情報はetcdドキュメントを参照してください。
etcdの暗号化可能な限り、保存時に全ドライブを暗号化することは良いプラクティスですが、etcdはクラスター全体(Secretを含む)の状態を保持しているため、そのディスクは特に暗号化する必要があります。

クラスター

Kubernetesを保護する為には2つの懸念事項があります。

  • 設定可能なクラスターコンポーネントの保護
  • クラスターで実行されるアプリケーションの保護

クラスターのコンポーネント

想定外または悪意のあるアクセスからクラスターを保護して適切なプラクティスを採用したい場合、クラスターの保護に関するアドバイスを読み従ってください。

クラスター内のコンポーネント(アプリケーション)

アプリケーションを対象にした攻撃に応じて、セキュリティの特定側面に焦点をあてたい場合があります。例:他のリソースとの連携で重要なサービス(サービスA)と、リソース枯渇攻撃に対して脆弱な別のワークロード(サービスB)が実行されている場合、サービスBのリソースを制限していないとサービスAが危険にさらされるリスクが高くなります。次の表はセキュリティの懸念事項とKubernetesで実行されるワークロードを保護するための推奨事項を示しています。

ワークロードセキュリティに関する懸念事項推奨事項
RBAC認可(Kubernetes APIへのアクセス)https://kubernetes.io/ja/docs/reference/access-authn-authz/rbac/
認証https://kubernetes.io/docs/concepts/security/controlling-access/
アプリケーションのSecret管理(およびetcdへの保存時に暗号化)https://kubernetes.io/ja/docs/concepts/configuration/secret/
https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
PodSecurityPolicyhttps://kubernetes.io/docs/concepts/policy/pod-security-policy/
Quality of Service (およびクラスターリソース管理)https://kubernetes.io/ja/docs/tasks/configure-pod-container/quality-service-pod/
NetworkPolicyhttps://kubernetes.io/ja/docs/concepts/services-networking/network-policies/
Kubernetes IngressのTLShttps://kubernetes.io/ja/docs/concepts/services-networking/ingress/#tls

コンテナ

コンテナセキュリティは本ガイドの範囲外になります。このトピックを検索するために一般的な推奨事項とリンクを以下に示します。

コンテナに関する懸念事項推奨事項
コンテナの脆弱性スキャンとOS依存のセキュリティイメージをビルドする手順の一部として、既知の脆弱性がないかコンテナをスキャンする必要があります。
イメージの署名と実施コンテナイメージを署名し、コンテナの中身に関する信頼性を維持します。
特権ユーザーを許可しないコンテナの構成時に、コンテナの目的を実行するために必要最低限なOS特権を持ったユーザーをコンテナ内部に作成する方法のドキュメントを参考にしてください。

コード

アプリケーションコードは、あなたが最も制御できる主要な攻撃対象のひとつです。アプリケーションコードを保護することはKubernetesのセキュリティトピックの範囲外ですが、アプリケーションコードを保護するための推奨事項を以下に示します。

コードセキュリティ

Code security
コードに関する懸念事項推奨事項
TLS経由のアクセスのみコードがTCP通信を必要とする場合は、事前にクライアントとのTLSハンドシェイクを実行してください。 いくつかの例外を除いて、全ての通信を暗号化してください。さらに一歩すすめて、サービス間のネットワークトラフィックを暗号化することはよい考えです。これは、サービスを特定した2つの証明書で通信の両端を検証する相互認証、またはmTLSして知られているプロセスを通じて実行できます。
通信ポートの範囲制限この推奨事項は一目瞭然かもしれませんが、可能なかぎり、通信とメトリクス収集に必要不可欠なサービスのポートのみを公開します。
サードパティに依存するセキュリティ既知の脆弱性についてアプリケーションのサードパーティ製ライブラリーを定期的にスキャンすることを推奨します。それぞれの言語は自動でこのチェックを実行するツールを持っています。
静的コード解析ほとんどの言語ではコードのスニペットを解析して、安全でない可能性のあるコーディングを分析する方法が提供しています。可能な限り、コードベースでスキャンして、よく起こるセキュリティエラーを検出できる自動ツールを使用してチェックを実行すべきです。一部のツールはここで紹介されています。 https://owasp.org/www-community/Source_Code_Analysis_Tools
動的プロービング攻撃よく知られているいくつかのサービス攻撃をサービスに対して試すことができる自動ツールがいくつかあります。これにはSQLインジェクション、CSRF、そしてXSSが含まれます。よく知られている動的解析ツールはOWASP Zed Attack proxytoolです。

次の項目

関連するKubernetesセキュリティについて学びます。

2 - Podセキュリティの標準

Podに対するセキュリティの設定は通常Security Contextを使用して適用されます。Security ContextはPod単位での特権やアクセスコントロールの定義を実現します。

クラスターにおけるSecurity Contextの強制やポリシーベースの定義はPod Security Policyによって実現されてきました。 Pod Security Policy はクラスターレベルのリソースで、Pod定義のセキュリティに関する設定を制御します。

しかし、PodSecurityPolicyを拡張したり代替する、ポリシーを強制するための多くの方法が生まれてきました。 このページの意図は、推奨されるPodのセキュリティプロファイルを特定の実装から切り離して詳しく説明することです。

ポリシーの種別

まず、幅広いセキュリティの範囲をカバーできる、基礎となるポリシーの定義が必要です。 それらは強く制限をかけるものから自由度の高いものまでをカバーすべきです。

  • 特権 - 制限のかかっていないポリシーで、可能な限り幅広い権限を提供します。このポリシーは既知の特権昇格を認めます。
  • ベースライン、デフォルト - 制限は最小限にされたポリシーですが、既知の特権昇格を防止します。デフォルト(最小の指定)のPod設定を許容します。
  • 制限 - 厳しく制限されたポリシーで、Podを強化するための現在のベストプラクティスに沿っています。

ポリシー

特権

特権ポリシーは意図的に開放されていて、完全に制限がかけられていません。この種のポリシーは通常、特権ユーザーまたは信頼されたユーザーが管理する、システムまたはインフラレベルのワークロードに対して適用されることを意図しています。

特権ポリシーは制限がないことと定義されます。gatekeeperのようにデフォルトで許可される仕組みでは、特権プロファイルはポリシーを設定せず、何も制限を適用しないことにあたります。 一方で、Pod Security Policyのようにデフォルトで拒否される仕組みでは、特権ポリシーでは全ての制限を無効化してコントロールできるようにする必要があります。

ベースライン、デフォルト

ベースライン、デフォルトのプロファイルは一般的なコンテナ化されたランタイムに適用しやすく、かつ既知の特権昇格を防ぐことを意図しています。 このポリシーはクリティカルではないアプリケーションの運用者または開発者を対象にしています。 次の項目は強制、または無効化すべきです。

ベースラインポリシーの定義
項目ポリシー
ホストのプロセス

Windows Podは、Windowsノードへの特権的なアクセスを可能にするHostProcessコンテナを実行する機能を提供します。ベースラインポリシーでは、ホストへの特権的なアクセスは禁止されています。HostProcess Podは、Kubernetes v1.22時点ではアルファ版の機能です。 ホストのネームスペースの共有は無効化すべきです。

制限されるフィールド

  • spec.securityContext.windowsOptions.hostProcess
  • spec.containers[*].securityContext.windowsOptions.hostProcess
  • spec.initContainers[*].securityContext.windowsOptions.hostProcess
  • spec.ephemeralContainers[*].securityContext.windowsOptions.hostProcess

認められる値

  • Undefined/nil
  • false
ホストのネームスペースホストのネームスペースの共有は無効化すべきです。

制限されるフィールド:
spec.hostNetwork
spec.hostPID
spec.hostIPC

認められる値: false, Undefined/nil
特権コンテナ特権を持つPodはほとんどのセキュリティ機構を無効化できるので、禁止すべきです。

制限されるフィールド:
spec.containers[*].securityContext.privileged
spec.initContainers[*].securityContext.privileged
spec.ephemeralContainers[*].securityContext.privileged

認められる値: false, undefined/nil
ケーパビリティーデフォルトよりも多くのケーパビリティーを与えることは禁止すべきです。

制限されるフィールド:
spec.containers[*].securityContext.capabilities.add
spec.initContainers[*].securityContext.capabilities.add
spec.ephemeralContainers[*].securityContext.capabilities.add

認められる値: Undefined/nil
AUDIT_WRITE
CHOWN
DAC_OVERRIDE
FOWNER
FSETID
KILL
MKNOD
NET_BIND_SERVICE
SETFCAP
SETGID
SETPCAP
SETUID
SYS_CHROOT
HostPathボリュームHostPathボリュームは禁止すべきです。

制限されるフィールド:
spec.volumes[*].hostPath

認められる値: undefined/nil
ホストのポートHostPortは禁止するか、最小限の既知のリストに限定すべきです。

制限されるフィールド:
spec.containers[*].ports[*].hostPort
spec.initContainers[*].ports[*].hostPort
spec.ephemeralContainers[*].ports[*].hostPort

認められる値: 0, undefined (または既知のリストに限定)
AppArmor(任意)サポートされるホストでは、AppArmorの'runtime/default'プロファイルがデフォルトで適用されます。デフォルトのポリシーはポリシーの上書きや無効化を防ぎ、許可されたポリシーのセットを上書きできないよう制限すべきです。

制限されるフィールド:
metadata.annotations['container.apparmor.security.beta.kubernetes.io/*']

認められる値: 'runtime/default', undefined, localhost/*
SELinux (任意)SELinuxのオプションをカスタムで設定することは禁止すべきです。

制限されるフィールド:
spec.securityContext.seLinuxOptions
spec.containers[*].securityContext.seLinuxOptions
spec.initContainers[*].securityContext.seLinuxOptions
spec.ephemeralContainers[*].securityContext.seLinuxOptions.type

認められる値:undefined/nil
Undefined/""
container_t
container_init_t
container_kvm_t


制限されるフィールド:
spec.securityContext.seLinuxOptions.user
spec.containers[*].securityContext.seLinuxOptions.user
spec.initContainers[*].securityContext.seLinuxOptions.user
spec.ephemeralContainers[*].securityContext.seLinuxOptions.user
spec.securityContext.seLinuxOptions.role
spec.containers[*].securityContext.seLinuxOptions.role
spec.initContainers[*].securityContext.seLinuxOptions.role
spec.ephemeralContainers[*].securityContext.seLinuxOptions.role

認められる値:undefined/nil
Undefined/""
/procマウントタイプ攻撃対象を縮小するため/procのマスクを設定し、必須とすべきです。

制限されるフィールド:
spec.containers[*].securityContext.procMount
spec.initContainers[*].securityContext.procMount
spec.ephemeralContainers[*].securityContext.procMount

認められる値:undefined/nil, 'Default'
Seccomp

Seccompプロファイルを明示的にUnconfinedに設定することはできません。

Restricted Fields

  • spec.securityContext.seccompProfile.type
  • spec.containers[*].securityContext.seccompProfile.type
  • spec.initContainers[*].securityContext.seccompProfile.type
  • spec.ephemeralContainers[*].securityContext.seccompProfile.type

Allowed Values

  • Undefined/nil
  • RuntimeDefault
  • Localhost
SysctlSysctlはセキュリティ機構を無効化したり、ホストの全てのコンテナに影響を与えたりすることが可能なので、「安全」なサブネットを除いては禁止すべきです。 コンテナまたはPodの中にsysctlがありネームスペースが分離されていて、同じノードの別のPodやプロセスから分離されている場合はsysctlは安全だと考えられます。

制限されるフィールド:
spec.securityContext.sysctls

認められる値:
kernel.shm_rmid_forced
net.ipv4.ip_local_port_range
net.ipv4.tcp_syncookies
net.ipv4.ping_group_range
undefined/空文字列

制限

制限ポリシーはいくらかの互換性を犠牲にして、Podを強化するためのベストプラクティスを強制することを意図しています。 セキュリティ上クリティカルなアプリケーションの運用者や開発者、また信頼度の低いユーザーも対象にしています。 下記の項目を強制、無効化すべきです。

制限ポリシーの定義
項目ポリシー
デフォルトプロファイルにある項目全て
VolumeタイプHostPathボリュームの制限に加え、制限プロファイルではコアでない種類のボリュームの利用をPersistentVolumeにより定義されたものに限定します。

制限されるフィールド:
spec.volumes[*].hostPath
spec.volumes[*].gcePersistentDisk
spec.volumes[*].awsElasticBlockStore
spec.volumes[*].gitRepo
spec.volumes[*].nfs
spec.volumes[*].iscsi
spec.volumes[*].glusterfs
spec.volumes[*].rbd
spec.volumes[*].flexVolume
spec.volumes[*].cinder
spec.volumes[*].cephfs
spec.volumes[*].flocker
spec.volumes[*].fc
spec.volumes[*].azureFile
spec.volumes[*].vsphereVolume
spec.volumes[*].quobyte
spec.volumes[*].azureDisk
spec.volumes[*].portworxVolume
spec.volumes[*].scaleIO
spec.volumes[*].storageos
spec.volumes[*].photonPersistentDisk

認められる値: undefined/nil
特権昇格特権昇格(ファイルモードのset-user-IDまたはset-group-IDのような方法による)は禁止すべきです。

制限されるフィールド:
spec.containers[*].securityContext.allowPrivilegeEscalation
spec.initContainers[*].securityContext.allowPrivilegeEscalation
spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation

認められる値: false
root以外での実行コンテナはroot以外のユーザーで実行する必要があります。

制限されるフィールド:
spec.securityContext.runAsNonRoot
spec.containers[*].securityContext.runAsNonRoot
spec.initContainers[*].securityContext.runAsNonRoot
spec.ephemeralContainers[*].securityContext.runAsNonRoot

認められる値: true
root以外のグループ (任意)コンテナをrootのプライマリまたは補助GIDで実行することを禁止すべきです。

制限されるフィールド:
spec.securityContext.runAsGroup
spec.securityContext.supplementalGroups[*]
spec.securityContext.fsGroup
spec.containers[*].securityContext.runAsGroup
spec.initContainers[*].securityContext.runAsGroup

認められる値:
0以外
undefined / nil (`*.runAsGroup`を除く)
SeccompSeccompのRuntimeDefaultを必須とする、または特定の追加プロファイルを許可することが必要です。

制限されるフィールド:
spec.securityContext.seccompProfile.type
spec.containers[*].securityContext.seccompProfile
spec.initContainers[*].securityContext.seccompProfile

認められる値:
'runtime/default'
undefined / nil
Capabilities (v1.22+)

コンテナはすべてのケイパビリティを削除する必要があり、NET_BIND_SERVICEケイパビリティを追加することだけが許可されています。

Restricted Fields

  • spec.containers[*].securityContext.capabilities.drop
  • spec.initContainers[*].securityContext.capabilities.drop
  • spec.ephemeralContainers[*].securityContext.capabilities.drop

Allowed Values

  • Any list of capabilities that includes ALL

Restricted Fields

  • spec.containers[*].securityContext.capabilities.add
  • spec.initContainers[*].securityContext.capabilities.add
  • spec.ephemeralContainers[*].securityContext.capabilities.add

Allowed Values

  • Undefined/nil
  • NET_BIND_SERVICE

ポリシーの実例

ポリシーの定義とポリシーの実装を切り離すことによって、ポリシーを強制する機構とは独立して、汎用的な理解や複数のクラスターにわたる共通言語とすることができます。

機構が成熟してきたら、ポリシーごとに下記に定義されます。それぞれのポリシーを強制する方法についてはここでは定義しません。

PodSecurityPolicy

FAQ

特権とデフォルトの間のプロファイルがないのはどうしてですか?

ここで定義されている3つのプロファイルは最も安全(制限)から最も安全ではない(特権)まで、直線的に段階が設定されており、幅広いワークロードをカバーしています。 ベースラインを超える特権が必要な場合、その多くはアプリケーションに特化しているため、その限られた要求に対して標準的なプロファイルを提供することはできません。 これは、このような場合に必ず特権プロファイルを使用すべきだという意味ではなく、場合に応じてポリシーを定義する必要があります。

将来、他のプロファイルの必要性が明らかになった場合、SIG Authはこの方針について再考する可能性があります。

セキュリティポリシーとセキュリティコンテキストの違いは何ですか?

Security Contextは実行時のコンテナやPodを設定するものです。 Security ContextはPodのマニフェストの中でPodやコンテナの仕様の一部として定義され、コンテナランタイムへ渡されるパラメーターを示します。

セキュリティポリシーはコントロールプレーンの機構で、Security Contextとそれ以外も含め、特定の設定を強制するものです。 2020年2月時点では、ネイティブにサポートされているポリシー強制の機構はPod Security Policyです。これはクラスター全体にわたってセキュリティポリシーを中央集権的に強制するものです。 セキュリティポリシーを強制する他の手段もKubernetesのエコシステムでは開発が進められています。例えばOPA Gatekeeperがあります。

WindowsのPodにはどのプロファイルを適用すればよいですか?

Kubernetesでは、Linuxベースのワークロードと比べてWindowsの使用は制限や差異があります。 特に、PodのSecurityContextフィールドはWindows環境では効果がありません。 したがって、現段階では標準化されたセキュリティポリシーは存在しません。

Windows Podに制限付きプロファイルを適用すると、実行時にPodに影響が出る場合があります。 制限付きプロファイルでは、Linux固有の制限(seccompプロファイルや特権昇格の不許可など)を適用する必要があります。 kubeletおよび/またはそのコンテナランタイムがこれらのLinux固有の値を無視した場合、Windows Podは制限付きプロファイル内で正常に動作します。 ただし、強制力がないため、Windows コンテナを使用するPodについては、ベースラインプロファイルと比較して追加の制限はありません。

HostProcess Podを作成するためのHostProcessフラグの使用は、特権的なポリシーに沿ってのみ行われるべきです。 Windows HostProcess Podの作成は、ベースラインおよび制限されたポリシーの下でブロックされているため、いかなるHostProcess Podも特権的であるとみなされるべきです。

サンドボックス化されたPodはどのように扱えばよいでしょうか?

現在のところ、Podがサンドボックス化されていると見なされるかどうかを制御できるAPI標準はありません。 サンドボックス化されたPodはサンドボックス化されたランタイム(例えばgVisorやKata Containers)の使用により特定することは可能ですが、サンドボックス化されたランタイムの標準的な定義は存在しません。

サンドボックス化されたランタイムに対して必要な保護は、それ以外に対するものとは異なります。 例えば、ワークロードがその基になるカーネルと分離されている場合、特権を制限する必要性は小さくなります。 これにより、強い権限を必要とするワークロードが隔離された状態を維持できます。

加えて、サンドボックス化されたワークロードの保護はサンドボックス化の実装に強く依存します。 したがって、全てのサンドボックス化されたワークロードに推奨される単一のポリシーは存在しません。

3 - Podのセキュリティアドミッション

FEATURE STATE: Kubernetes v1.23 [beta]

KubernetesのPodセキュリティの標準はPodに対して異なる分離レベルを定義します。 これらの標準によって、Podの動作をどのように制限したいかを、明確かつ一貫した方法で定義することができます。

ベータ版機能として、KubernetesはPodSecurityPolicyの後継である組み込みの Pod Security アドミッションコントローラーを提供しています。 Podセキュリティの制限は、Pod作成時に名前空間レベルで適用されます。

PodSecurityアドミッションプラグインの有効化

v1.23において、PodSecurityフィーチャーゲートはベータ版の機能で、デフォルトで有効化されています。 v1.22において、PodSecurityフィーチャーゲートはアルファ版の機能で、組み込みのアドミッションプラグインを使用するには、kube-apiserverで有効にする必要があります。

--feature-gates="...,PodSecurity=true"

代替案:PodSecurityアドミッションwebhookのインストール

クラスターがv1.22より古い、あるいはPodSecurity機能を有効にできないなどの理由で、ビルトインのPodSecurityアドミッションプラグインが使えない環境では、PodSecurityはアドミッションロジックはベータ版のvalidating admission webhookとしても提供されています。

ビルド前のコンテナイメージ、証明書生成スクリプト、マニフェストの例は、https://git.k8s.io/pod-security-admission/webhookで入手可能です。

インストール方法:

git clone git@github.com:kubernetes/pod-security-admission.git
cd pod-security-admission/webhook
make certs
kubectl apply -k .

Podのセキュリティレベル

Podのセキュリティアドミッションは、PodのSecurity Contextとその他の関連フィールドに、Podセキュリティの標準で定義された3つのレベル、privilegedbaselinerestrictedに従って要件を設定するものです。 これらの要件の詳細については、Podセキュリティの標準のページを参照してください。

Podの名前空間に対するセキュリティアドミッションラベル

この機能を有効にするか、Webhookをインストールすると、名前空間を設定して、各名前空間でPodセキュリティに使用したいadmission controlモードを定義できます。 Kubernetesは、名前空間に使用したい定義済みのPodセキュリティの標準レベルのいずれかを適用するために設定できるラベルのセットを用意しています。 選択したラベルは、以下のように違反の可能性が検出された場合にコントロールプレーンが取るアクションを定義します。

Podのセキュリティアドミッションのモード
モード説明
enforceポリシーに違反した場合、Podは拒否されます。
auditポリシー違反は、監査ログに記録されるイベントに監査アノテーションを追加するトリガーとなりますが、それ以外は許可されます。
warnポリシーに違反した場合は、ユーザーへの警告がトリガーされますが、それ以外は許可されます。

名前空間は、任意のまたはすべてのモードを設定することができ、異なるモードに対して異なるレベルを設定することもできます。

各モードには、使用するポリシーを決定する2つのラベルがあります。

# モードごとのレベルラベルは、そのモードに適用するポリシーレベルを示す。
#
# MODEは`enforce`、`audit`、`warn`のいずれかでなければならない。
# LEVELは`privileged`、`baseline`、`restricted`のいずれかでなければならない。
pod-security.kubernetes.io/<MODE>: <LEVEL>

# オプション: モードごとのバージョンラベルは、Kubernetesのマイナーバージョンに同梱される
# バージョンにポリシーを固定するために使用できる(例えばv1.29など)。
#
# MODEは`enforce`、`audit`、`warn`のいずれかでなければならない。
# VERSIONは有効なKubernetesのマイナーバージョンか`latest`でなければならない。
pod-security.kubernetes.io/<MODE>-version: <VERSION>

名前空間ラベルでのPodセキュリティの標準の適用で使用例を確認できます。

WorkloadのリソースとPodテンプレート

Podは、DeploymentJobのようなワークロードオブジェクトを作成することによって、しばしば間接的に生成されます。 ワークロードオブジェクトは_Pod template_を定義し、ワークロードリソースのコントローラーはそのテンプレートに基づきPodを作成します。 違反の早期発見を支援するために、auditモードとwarningモードは、ワークロードリソースに適用されます。 ただし、enforceモードはワークロードリソースには適用されず、結果としてのPodオブジェクトにのみ適用されます。

適用除外(Exemption)

Podセキュリティの施行から exemptions を定義することで、特定の名前空間に関連するポリシーのために禁止されていたPodの作成を許可することができます。 Exemptionはアドミッションコントローラーの設定で静的に設定することができます。

Exemptionは明示的に列挙する必要があります。 Exemptionを満たしたリクエストは、アドミッションコントローラーによって 無視 されます(enforceauditwarnのすべての動作がスキップされます)。Exemptionの次元は以下の通りです。

  • Usernames: 認証されていない(あるいは偽装された)ユーザー名を持つユーザーからの要求は無視されます。
  • RuntimeClassNames: Podとワークロードリソースで指定された除外ランタイムクラス名は、無視されます。
  • Namespaces: 除外された名前空間のPodとワークロードリソースは、無視されます。

以下のPodフィールドに対する更新は、ポリシーチェックの対象外となります。つまり、Podの更新要求がこれらのフィールドを変更するだけであれば、Podが現在のポリシーレベルに違反していても拒否されることはありません。

  • すべてのメタデータの更新(seccompまたはAppArmorアノテーションへの変更を除く)
    • seccomp.security.alpha.kubernetes.io/pod(非推奨)
    • container.seccomp.security.alpha.kubernetes.io/*(非推奨)
    • container.apparmor.security.beta.kubernetes.io/*
  • .spec.activeDeadlineSecondsに対する有効な更新
  • .spec.tolerationsに対する有効な更新

次の項目

4 - Kubernetes APIへのアクセスコントロール

このページではKubernetes APIへのアクセスコントロールの概要を説明します。

Kubernetes APIにはkubectlやクライアントライブラリ、あるいはRESTリクエストを用いてアクセスします。 APIアクセスには、人間のユーザーとKubernetesサービスアカウントの両方が認証可能です。 リクエストがAPIに到達すると、次の図のようにいくつかの段階を経ます。

Kubernetes APIリクエストの処理手順図

トランスポート層のセキュリティ

一般的なKubernetesクラスターでは、APIはTLSで保護された443番ポートで提供されます。 APIサーバーは証明書を提示します。 この証明書は、プライベート認証局(CA)を用いて署名することも、一般に認知されているCAと連携した公開鍵基盤に基づき署名することも可能です。

クラスターがプライベート認証局を使用している場合、接続を信頼し、傍受されていないと確信できるように、クライアント上の~/.kube/configに設定されたそのCA証明書のコピーが必要です。

クライアントは、この段階でTLSクライアント証明書を提示することができます。

認証

TLSが確立されると、HTTPリクエストは認証のステップに移行します。 これは図中のステップ1に該当します。 クラスター作成スクリプトまたはクラスター管理者は、1つまたは複数のAuthenticatorモジュールを実行するようにAPIサーバーを設定します。 Authenticatorについては、認証で詳しく説明されています。

認証ステップへの入力はHTTPリクエスト全体ですが、通常はヘッダとクライアント証明書の両方、またはどちらかを調べます。

認証モジュールには、クライアント証明書、パスワード、プレーントークン、ブートストラップトークン、JSON Web Tokens(サービスアカウントに使用)などがあります。

複数の認証モジュールを指定することができ、その場合、1つの認証モジュールが成功するまで、それぞれを順番に試行します。

認証できない場合、HTTPステータスコード401で拒否されます。 そうでなければ、ユーザーは特定のusernameとして認証され、そのユーザー名は後続のステップでの判断に使用できるようになります。 また、ユーザーのグループメンバーシップを提供する認証機関と、提供しない認証機関があります。

Kubernetesはアクセスコントロールの決定やリクエストログにユーザー名を使用しますが、Userオブジェクトを持たず、ユーザー名やその他のユーザーに関する情報をAPIはに保存しません。

認可

リクエストが特定のユーザーからのものであると認証された後、そのリクエストは認可される必要があります。 これは図のステップ2に該当します。

リクエストには、リクエスト者のユーザー名、リクエストされたアクション、そのアクションによって影響を受けるオブジェクトを含める必要があります。 既存のポリシーで、ユーザーが要求されたアクションを完了するための権限を持っていると宣言されている場合、リクエストは承認されます。

例えば、Bobが以下のようなポリシーを持っている場合、彼は名前空間projectCaribou内のPodのみを読むことができます。

{
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
        "user": "bob",
        "namespace": "projectCaribou",
        "resource": "pods",
        "readonly": true
    }
}

Bobが次のようなリクエストをした場合、Bobは名前空間projectCaribouのオブジェクトを読むことが許可されているので、このリクエストは認可されます。

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "resourceAttributes": {
      "namespace": "projectCaribou",
      "verb": "get",
      "group": "unicorn.example.org",
      "resource": "pods"
    }
  }
}

Bobが名前空間projectCaribouのオブジェクトに書き込み(createまたはupdate)のリクエストをした場合、承認は拒否されます。 また、もしBobがprojectFishのような別の名前空間にあるオブジェクトを読み込む(get)リクエストをした場合も、承認は拒否されます。

Kubernetesの認可では、組織全体またはクラウドプロバイダー全体の既存のアクセスコントロールシステムと対話するために、共通のREST属性を使用する必要があります。 これらのコントロールシステムは、Kubernetes API以外のAPIとやり取りする可能性があるため、REST形式を使用することが重要です。

Kubernetesは、ABACモード、RBACモード、Webhookモードなど、複数の認可モジュールをサポートしています。 管理者はクラスターを作成する際に、APIサーバーで使用する認証モジュールを設定します。 複数の認可モジュールが設定されている場合、Kubernetesは各モジュールをチェックし、いずれかのモジュールがリクエストを認可した場合、リクエストを続行することができます。 すべてのモジュールがリクエストを拒否した場合、リクエストは拒否されます(HTTPステータスコード403)。

サポートされている認可モジュールを使用したポリシー作成の詳細を含む、Kubernetesの認可については、認可を参照してください。

アドミッションコントロール

アドミッションコントロールモジュールは、リクエストを変更したり拒否したりすることができるソフトウェアモジュールです。 認可モジュールが利用できる属性に加えて、アドミッションコントロールモジュールは、作成または修正されるオブジェクトのコンテンツにアクセスすることができます。

アドミッションコントローラーは、オブジェクトの作成、変更、削除、または接続(プロキシ)を行うリクエストに対して動作します。 アドミッションコントローラーは、単にオブジェクトを読み取るだけのリクエストには動作しません。 複数のアドミッションコントローラーが設定されている場合は、順番に呼び出されます。

これは図中のステップ3に該当します。

認証・認可モジュールとは異なり、いずれかのアドミッションコントローラーモジュールが拒否した場合、リクエストは即座に拒否されます。

オブジェクトを拒否するだけでなく、アドミッションコントローラーは、フィールドに複雑なデフォルトを設定することもできます。

利用可能なアドミッションコントロールモジュールは、アドミッションコントローラーに記載されています。

リクエストがすべてのアドミッションコントローラーを通過すると、対応するAPIオブジェクトの検証ルーチンを使って検証され、オブジェクトストアに書き込まれます(図のステップ4に該当します)。

監査

Kubernetesの監査は、クラスター内の一連のアクションを文書化した、セキュリティに関連する時系列の記録を提供します。 クラスターは、ユーザー、Kubernetes APIを使用するアプリケーション、およびコントロールプレーン自身によって生成されるアクティビティを監査します。

詳しくは監査をご覧ください。

APIサーバーのIPとポート

これまでの説明は、APIサーバーのセキュアポートに送信されるリクエストに適用されます(典型的なケース)。 APIサーバーは、実際には2つのポートでサービスを提供することができます。

デフォルトでは、Kubernetes APIサーバーは2つのポートでHTTPを提供します。

  1. localhostポート:

    • テストとブートストラップ用で、マスターノードの他のコンポーネント(スケジューラー、コントローラーマネージャー)がAPIと通信するためのものです。
    • TLSは使用しません。
    • デフォルトポートは8080です。
    • デフォルトのIPはlocalhostですが、--insecure-bind-addressフラグで変更することができます。
    • リクエストは認証と認可のモジュールをバイパスします。
    • リクエストは、アドミッションコントロールモジュールによって処理されます。
    • ホストにアクセスする必要があるため、保護されています。
  2. “セキュアポート”:

    • 可能な限りこちらを使用してください。
    • TLSを使用します。証明書は--tls-cert-fileフラグで、鍵は--tls-private-key-fileフラグで設定します。
    • デフォルトポートは6443です。--secure-portフラグで変更することができます。
    • デフォルトのIPは、最初の非localhostのネットワークインターフェースです。--bind-addressフラグで変更することができます。
    • リクエストは、認証・認可モジュールによって処理されます。
    • リクエストは、アドミッションコントロールモジュールによって処理されます。
    • 認証・認可モジュールが実行されます。

次の項目

認証、認可、APIアクセスコントロールに関する詳しいドキュメントはこちらをご覧ください。

以下についても知ることができます。

  • PodがAPIクレデンシャルを取得するためにSecretsを使用する方法について。

5 - Kubernetes Secretの適切な使用方法

クラスター管理者とアプリケーション開発者向けの適切なSecret管理の原則と実践方法。

Kubernetesでは、Secretは次のようなオブジェクトです。 パスワードやOAuthトークン、SSHキーのような機密の情報を保持します。

Secretは、機密情報の使用方法をより管理しやすくし、偶発的な漏洩のリスクを減らすことができます。Secretの値はbase64文字列としてエンコードされ、デフォルトでは暗号化されずに保存されますが、保存時に暗号化するように設定することもできます。

Podは、ボリュームマウントや環境変数など、さまざまな方法でSecretを参照できます。Secretは機密データ用に設計されており、ConfigMapは非機密データ用に設計されています。

以下の適切な使用方法は、クラスター管理者とアプリケーション開発者の両方を対象としています。 これらのガイドラインに従って、Secretオブジェクト内の機密情報のセキュリティを向上させ、Secretの効果的な管理を行ってください。

クラスター管理者

このセクションでは、クラスター管理者がクラスター内の機密情報のセキュリティを強化するために使用できる適切な方法を提供します。

データ保存時の暗号化を構成する

デフォルトでは、Secretオブジェクトはetcd内で暗号化されていない状態で保存されます。 etcd内のSecretデータを暗号化するように構成する必要があります。 手順については、機密データ保存時の暗号化を参照してください。

Secretへの最小特権アクセスを構成する

Kubernetesのロールベースアクセス制御 (RBAC)などのアクセス制御メカニズムを計画する際、Secretオブジェクトへのアクセスに関する以下のガイドラインを考慮してください。 また、RBACの適切な使用方法の他のガイドラインにも従ってください。

  • コンポーネント: watchまたはlistアクセスを、最上位の特権を持つシステムレベルのコンポーネントのみに制限してください。コンポーネントの通常の動作が必要とする場合にのみ、Secretへのgetアクセスを許可してください。
  • ユーザー: Secretへのgetwatchlistアクセスを制限してください。etcdへのアクセスはクラスター管理者にのみ許可し、読み取り専用アクセスも許可してください。特定の注釈を持つSecretへのアクセスを制限するなど、より複雑なアクセス制御については、サードパーティの認証メカニズムを検討してください。

Secretを使用するPodを作成できるユーザーは、そのSecretの値も見ることができます。 クラスターのポリシーがユーザーにSecretを直接読むことを許可しない場合でも、同じユーザーがSecretを公開するPodを実行するアクセスを持つかもしれません。 このようなアクセスを持つユーザーによるSecretデータの意図的または偶発的な公開の影響を検出または制限することができます。 いくつかの推奨事項には以下があります:

  • 短寿命のSecretを使用する
  • 特定のイベントに対してアラートを出す監査ルールを実装する(例:単一ユーザーによる複数のSecretの同時読み取り)

etcdの管理ポリシーを改善する

使用しなくなった場合には、etcdが使用する永続ストレージを削除するかシュレッダーで処理してください。

複数のetcdインスタンスがある場合、インスタンス間の通信を暗号化されたSSL/TLS通信に設定して、転送中のSecretデータを保護してください。

外部Secretへのアクセスを構成する

外部のSecretストアプロバイダーを使用して機密データをクラスターの外部に保存し、その情報にアクセスするようにPodを構成できます。 Kubernetes Secrets Store CSI Driverは、kubeletが外部ストアからSecretを取得し、データにアクセスすることを許可された特定のPodにSecretをボリュームとしてマウントするDaemonSetです。

サポートされているプロバイダーの一覧については、Secret Store CSI Driverのプロバイダーを参照してください。

開発者

このセクションでは、Kubernetesリソースの作成と展開時に機密データのセキュリティを向上させるための開発者向けの適切な使用方法を提供します。

特定のコンテナへのSecretアクセスを制限する

Pod内で複数のコンテナを定義し、そのうち1つのコンテナだけがSecretへのアクセスを必要とする場合、他のコンテナがそのSecretにアクセスできないようにボリュームマウントや環境変数の設定を行ってください。

読み取り後にSecretデータを保護する

アプリケーションは、環境変数やボリュームから機密情報を読み取った後も、その値を保護する必要があります。 例えば、アプリケーションは機密情報を平文でログに記録したり、信頼できない第三者に送信したりしないようにする必要があります。

Secretマニフェストの共有を避ける

Secretをマニフェストを介して設定し、秘密データをBase64でエンコードしている場合、このファイルを共有したりソースリポジトリにチェックインしたりすると、その秘密はマニフェストを読むことのできる全員に公開されます。