1 - Podセキュリティの標準
Podに対するセキュリティの設定は通常Security Contextを使用して適用されます。Security ContextはPod単位での特権やアクセスコントロールの定義を実現します。
クラスターにおけるSecurity Contextの強制やポリシーベースの定義はPod Security Policyによって実現されてきました。 Pod Security Policy はクラスターレベルのリソースで、Pod定義のセキュリティに関する設定を制御します。
しかし、PodSecurityPolicyを拡張したり代替する、ポリシーを強制するための多くの方法が生まれてきました。 このページの意図は、推奨されるPodのセキュリティプロファイルを特定の実装から切り離して詳しく説明することです。
ポリシーの種別
まず、幅広いセキュリティの範囲をカバーできる、基礎となるポリシーの定義が必要です。 それらは強く制限をかけるものから自由度の高いものまでをカバーすべきです。
- 特権 - 制限のかかっていないポリシーで、可能な限り幅広い権限を提供します。このポリシーは既知の特権昇格を認めます。
- ベースライン、デフォルト - 制限は最小限にされたポリシーですが、既知の特権昇格を防止します。デフォルト(最小の指定)のPod設定を許容します。
- 制限 - 厳しく制限されたポリシーで、Podを強化するための現在のベストプラクティスに沿っています。
ポリシー
特権
特権ポリシーは意図的に開放されていて、完全に制限がかけられていません。この種のポリシーは通常、特権ユーザーまたは信頼されたユーザーが管理する、システムまたはインフラレベルのワークロードに対して適用されることを意図しています。
特権ポリシーは制限がないことと定義されます。gatekeeperのようにデフォルトで許可される仕組みでは、特権プロファイルはポリシーを設定せず、何も制限を適用しないことにあたります。 一方で、Pod Security Policyのようにデフォルトで拒否される仕組みでは、特権ポリシーでは全ての制限を無効化してコントロールできるようにする必要があります。
ベースライン、デフォルト
ベースライン、デフォルトのプロファイルは一般的なコンテナ化されたランタイムに適用しやすく、かつ既知の特権昇格を防ぐことを意図しています。 このポリシーはクリティカルではないアプリケーションの運用者または開発者を対象にしています。 次の項目は強制、または無効化すべきです。
項目 | ポリシー |
ホストのネームスペース |
ホストのネームスペースの共有は無効化すべきです。 制限されるフィールド: spec.hostNetwork spec.hostPID spec.hostIPC 認められる値: false |
特権コンテナ |
特権を持つPodはほとんどのセキュリティ機構を無効化できるので、禁止すべきです。 制限されるフィールド: spec.containers[*].securityContext.privileged spec.initContainers[*].securityContext.privileged 認められる値: false, undefined/nil |
ケーパビリティー |
デフォルトよりも多くのケーパビリティーを与えることは禁止すべきです。 制限されるフィールド: spec.containers[*].securityContext.capabilities.add spec.initContainers[*].securityContext.capabilities.add 認められる値: 空 (または既知のリストに限定) |
HostPathボリューム |
HostPathボリュームは禁止すべきです。 制限されるフィールド: spec.volumes[*].hostPath 認められる値: undefined/nil |
ホストのポート |
HostPortは禁止するか、最小限の既知のリストに限定すべきです。 制限されるフィールド: spec.containers[*].ports[*].hostPort spec.initContainers[*].ports[*].hostPort 認められる値: 0, undefined (または既知のリストに限定) |
AppArmor (任意) |
サポートされるホストでは、AppArmorの'runtime/default'プロファイルがデフォルトで適用されます。デフォルトのポリシーはポリシーの上書きや無効化を防ぎ、許可されたポリシーのセットを上書きできないよう制限すべきです。 制限されるフィールド: metadata.annotations['container.apparmor.security.beta.kubernetes.io/*'] 認められる値: 'runtime/default', undefined |
SELinux (任意) |
SELinuxのオプションをカスタムで設定することは禁止すべきです。 制限されるフィールド: spec.securityContext.seLinuxOptions spec.containers[*].securityContext.seLinuxOptions spec.initContainers[*].securityContext.seLinuxOptions 認められる値: undefined/nil |
/procマウントタイプ |
攻撃対象を縮小するため/procのマスクを設定し、必須とすべきです。 制限されるフィールド: spec.containers[*].securityContext.procMount spec.initContainers[*].securityContext.procMount 認められる値: undefined/nil, 'Default' |
Sysctl |
Sysctlはセキュリティ機構を無効化したり、ホストの全てのコンテナに影響を与えたりすることが可能なので、「安全」なサブネットを除いては禁止すべきです。
コンテナまたは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[*].csi 認められる値: undefined/nil |
特権昇格 |
特権昇格(ファイルモードのset-user-IDまたはset-group-IDのような方法による)は禁止すべきです。 制限されるフィールド: spec.containers[*].securityContext.allowPrivilegeEscalation spec.initContainers[*].securityContext.allowPrivilegeEscalation 認められる値: false |
root以外での実行 |
コンテナはroot以外のユーザーで実行する必要があります。 制限されるフィールド: spec.securityContext.runAsNonRoot spec.containers[*].securityContext.runAsNonRoot spec.initContainers[*].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`を除く) |
Seccomp |
SeccompのRuntimeDefaultを必須とする、または特定の追加プロファイルを許可することが必要です。 制限されるフィールド: spec.securityContext.seccompProfile.type spec.containers[*].securityContext.seccompProfile spec.initContainers[*].securityContext.seccompProfile 認められる値: 'runtime/default' undefined / nil |
ポリシーの実例
ポリシーの定義とポリシーの実装を切り離すことによって、ポリシーを強制する機構とは独立して、汎用的な理解や複数のクラスターにわたる共通言語とすることができます。
機構が成熟してきたら、ポリシーごとに下記に定義されます。それぞれのポリシーを強制する方法についてはここでは定義しません。
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環境では効果がありません。 したがって、現段階では標準化されたセキュリティポリシーは存在しません。
サンドボックス化されたPodはどのように扱えばよいでしょうか?
現在のところ、Podがサンドボックス化されていると見なされるかどうかを制御できるAPI標準はありません。 サンドボックス化されたPodはサンドボックス化されたランタイム(例えばgVisorやKata Containers)の使用により特定することは可能ですが、サンドボックス化されたランタイムの標準的な定義は存在しません。
サンドボックス化されたランタイムに対して必要な保護は、それ以外に対するものとは異なります。 例えば、ワークロードがその基になるカーネルと分離されている場合、特権を制限する必要性は小さくなります。 これにより、強い権限を必要とするワークロードが隔離された状態を維持できます。
加えて、サンドボックス化されたワークロードの保護はサンドボックス化の実装に強く依存します。 したがって、全てのサンドボックス化されたワークロードに推奨される単一のポリシーは存在しません。
2 - クラウドネイティブセキュリティの概要
この概要では、クラウドネイティブセキュリティにおけるKubernetesのセキュリティを考えるためのモデルを定義します。
クラウドネイティブセキュリティの4C
セキュリティは階層で考えることができます。クラウドネイティブの4Cは、クラウド、クラスター、コンテナ、そしてコードです。
クラウドネイティブセキュリティモデルの各レイヤーは次の最も外側のレイヤー上に構築します。コードレイヤーは、強固な基盤(クラウド、クラスター、コンテナ)セキュリティレイヤーから恩恵を受けます。コードレベルのセキュリティに対応しても基盤レイヤーが低い水準のセキュリティでは守ることができません。
クラウド
いろいろな意味でも、クラウド(または同じ場所に設置されたサーバー、企業のデータセンター)はKubernetesクラスターのトラステッド・コンピューティング・ベースです。クラウドレイヤーが脆弱な(または脆弱な方法で構成されている)場合、この基盤の上に構築されたコンポーネントが安全であるという保証はありません。各クラウドプロバイダーは、それぞれの環境でワークロードを安全に実行させるためのセキュリティの推奨事項を作成しています。
クラウドプロバイダーのセキュリティ
Kubernetesクラスターを所有しているハードウェアや様々なクラウドプロバイダー上で実行している場合、セキュリティのベストプラクティスに関するドキュメントを参考にしてください。ここでは人気のあるクラウドプロバイダーのセキュリティドキュメントの一部のリンクを紹介します。
IaaSプロバイダー | リンク |
---|---|
Alibaba Cloud | https://www.alibabacloud.com/trust-center |
Amazon Web Services | https://aws.amazon.com/security/ |
Google Cloud Platform | https://cloud.google.com/security/ |
IBM Cloud | https://www.ibm.com/cloud/security |
Microsoft Azure | https://docs.microsoft.com/en-us/azure/security/azure-security |
Oracle Cloud Infrastructure | https://www.oracle.com/security/ |
VMWare VSphere | https://www.vmware.com/security/hardening-guides.html |
インフラのセキュリティ
Kubernetesクラスターのインフラを保護するための提案です。
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/ |
PodSecurityPolicy | https://kubernetes.io/docs/concepts/policy/pod-security-policy/ |
Quality of Service (およびクラスターリソース管理) | https://kubernetes.io/ja/docs/tasks/configure-pod-container/quality-service-pod/ |
NetworkPolicy | https://kubernetes.io/ja/docs/concepts/services-networking/network-policies/ |
Kubernetes IngressのTLS | https://kubernetes.io/ja/docs/concepts/services-networking/ingress/#tls |
コンテナ
コンテナセキュリティは本ガイドの範囲外になります。このトピックを検索するために一般的な推奨事項とリンクを以下に示します。
コンテナに関する懸念事項 | 推奨事項 |
---|---|
コンテナの脆弱性スキャンとOS依存のセキュリティ | イメージをビルドする手順の一部として、既知の脆弱性がないかコンテナをスキャンする必要があります。 |
イメージの署名と実施 | コンテナイメージを署名し、コンテナの中身に関する信頼性を維持します。 |
特権ユーザーを許可しない | コンテナの構成時に、コンテナの目的を実行するために必要最低限なOS特権を持ったユーザーをコンテナ内部に作成する方法のドキュメントを参考にしてください。 |
コード
アプリケーションコードは、あなたが最も制御できる主要な攻撃対象のひとつです。アプリケーションコードを保護することはKubernetesのセキュリティトピックの範囲外ですが、アプリケーションコードを保護するための推奨事項を以下に示します。
コードセキュリティ
コードに関する懸念事項 | 推奨事項 |
---|---|
TLS経由のアクセスのみ | コードがTCP通信を必要とする場合は、事前にクライアントとのTLSハンドシェイクを実行してください。 いくつかの例外を除いて、全ての通信を暗号化してください。さらに一歩すすめて、サービス間のネットワークトラフィックを暗号化することはよい考えです。これは、サービスを特定した2つの証明書で通信の両端を検証する相互認証、またはmTLSして知られているプロセスを通じて実行できます。 |
通信ポートの範囲制限 | この推奨事項は一目瞭然かもしれませんが、可能なかぎり、通信とメトリクス収集に必要不可欠なサービスのポートのみを公開します。 |
サードパティに依存するセキュリティ | 既知の脆弱性についてアプリケーションのサードパーティ製ライブラリーを定期的にスキャンすることを推奨します。それぞれの言語は自動でこのチェックを実行するツールを持っています。 |
静的コード解析 | ほとんどの言語ではコードのスニペットを解析して、安全でない可能性のあるコーディングを分析する方法が提供しています。可能な限り、コードベースでスキャンして、よく起こるセキュリティエラーを検出できる自動ツールを使用してチェックを実行すべきです。一部のツールはここで紹介されています。 https://owasp.org/www-community/Source_Code_Analysis_Tools |
動的プロービング攻撃 | よく知られているいくつかのサービス攻撃をサービスに対して試すことができる自動ツールがいくつかあります。これにはSQLインジェクション、CSRF、そしてXSSが含まれます。よく知られている動的解析ツールはOWASP Zed Attack proxytoolです。 |
次の項目
関連するKubernetesセキュリティについて学びます。
- Podセキュリティの標準
- [Podのネットワークポリシー]](/ja/docs/concepts/services-networking/network-policies/)
- Kubernetes APIへのアクセスを制御する
- クラスターの保護
- コントロールプレーンとの通信時のデータ暗号化
- 保存時のデータ暗号化
- Kubernetes Secret
3 - Podのセキュリティアドミッション
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つのレベル、privileged
、baseline
、restricted
に従って要件を設定するものです。
これらの要件の詳細については、Podセキュリティの標準のページを参照してください。
Podの名前空間に対するセキュリティアドミッションラベル
この機能を有効にするか、Webhookをインストールすると、名前空間を設定して、各名前空間でPodセキュリティに使用したいadmission controlモードを定義できます。 Kubernetesは、名前空間に使用したい定義済みのPodセキュリティの標準レベルのいずれかを適用するために設定できるラベルのセットを用意しています。 選択したラベルは、以下のように違反の可能性が検出された場合にコントロールプレーンが取るアクションを定義します。
モード | 説明 |
---|---|
enforce | ポリシーに違反した場合、Podは拒否されます。 |
audit | ポリシー違反は、監査ログに記録されるイベントに監査アノテーションを追加するトリガーとなりますが、それ以外は許可されます。 |
warn | ポリシーに違反した場合は、ユーザーへの警告がトリガーされますが、それ以外は許可されます。 |
名前空間は、任意のまたはすべてのモードを設定することができ、異なるモードに対して異なるレベルを設定することもできます。
各モードには、使用するポリシーを決定する2つのラベルがあります。
# モードごとのレベルラベルは、そのモードに適用するポリシーレベルを示す。
#
# MODEは`enforce`、`audit`、`warn`のいずれかでなければならない。
# LEVELは`privileged`、`baseline`、`restricted`のいずれかでなければならない。
pod-security.kubernetes.io/<MODE>: <LEVEL>
# オプション: モードごとのバージョンラベルは、Kubernetesのマイナーバージョンに同梱される
# バージョンにポリシーを固定するために使用できる(例えばv1.23など)。
#
# MODEは`enforce`、`audit`、`warn`のいずれかでなければならない。
# VERSIONは有効なKubernetesのマイナーバージョンか`latest`でなければならない。
pod-security.kubernetes.io/<MODE>-version: <VERSION>
名前空間ラベルでのPodセキュリティの標準の適用で使用例を確認できます。
WorkloadのリソースとPodテンプレート
Podは、DeploymentやJobのようなワークロードオブジェクトを作成することによって、しばしば間接的に生成されます。 ワークロードオブジェクトは_Pod template_を定義し、ワークロードリソースのコントローラーはそのテンプレートに基づきPodを作成します。 違反の早期発見を支援するために、auditモードとwarningモードは、ワークロードリソースに適用されます。 ただし、enforceモードはワークロードリソースには適用されず、結果としてのPodオブジェクトにのみ適用されます。
適用除外(Exemption)
Podセキュリティの施行から exemptions を定義することで、特定の名前空間に関連するポリシーのために禁止されていたPodの作成を許可することができます。 Exemptionはアドミッションコントローラーの設定で静的に設定することができます。
Exemptionは明示的に列挙する必要があります。
Exemptionを満たしたリクエストは、アドミッションコントローラーによって 無視 されます(enforce
、audit
、warn
のすべての動作がスキップされます)。Exemptionの次元は以下の通りです。
- Usernames: 認証されていない(あるいは偽装された)ユーザー名を持つユーザーからの要求は無視されます。
- RuntimeClassNames: Podとワークロードリソースで指定された除外ランタイムクラス名は、無視されます。
- Namespaces: 除外された名前空間のPodとワークロードリソースは、無視されます。
system:serviceaccount:kube-system:replicaset-controller
など)は通常、除外してはいけません。そうした場合、対応するワークロードリソースを作成できるすべてのユーザーを暗黙的に除外してしまうためです。
以下の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
に対する有効な更新