我尝试整理关于Kubernetes安全性的事宜
首先
2019年1月14日,在CNCF(云原生计算基金会)的博客上发布了以下文章。
九个Kubernetes安全最佳实践,大家都必须遵循:
https://www.cncf.io/blog/2019/01/14/9-kubernetes-security-best-practices-everyone-must-follow/
(Translation:
九个 Kubernetes 安全最佳实践,每个人都必须遵循。)
这篇博客文章标题直译过来是“大家应该遵循的9个Kubernetes安全最佳实践”,但是根据我对Kubernetes及其相关技术的经验,我认为仅仅涵盖在这里提到的内容是不够的。因此,我想整理一下在我能调查范围内为保证Kubernetes安全所必需的事项。
加强集群的安全性。
控制对Kubernetes API的访问
由于Kubernetes是通过API进行操作的,因此需要对API进行身份验证,以控制(授权)经过身份验证的用户可以执行的操作。以下是确保Kubernetes API安全所需的三个步骤。
-
- すべてのAPIへのアクセスにTLS(Transport Level Security)を利用
-
- API認証
- API認可
您可以使用现有的OIDC服务器或LDAP服务器进行API认证,建议使用基于角色的访问控制(RBAC)进行API授权。有关这些的详细信息将在后面进行说明。
此外,2018年12月发现了Kubernetes的首个重大漏洞(CVE-2018-1002105),该漏洞可通过Kubernetes API从外部进行攻击。重要的是要控制只能从可信网络访问Kubernetes API。
控制对kubelet的访问
kubeletはノードとコンテナを制御するHTTPSエンドポイントを公開しています。
デフォルトでは、kubeletはAPIで認証されていないアクセスを許可してしまうため、プロダクション環境ではkubeletの認証・認可を有効する必要があります。
また、インターネットからの攻撃を防ぐため、信頼できるネットワークからのみアクセス可能なように制御しましょう。
控制工作负载的功能
通过对像Pod等的各个对象进行资源限制等措施,可以提高安全性。
クラスタのリソース使用量を制御しよう
ResourceQuotaを指定することにより、Namespaceに付与されるリソース数を制御することができます。この機能は、Namespaceに割り当てることのできるCPU・メモリ・PV(Persistent Volume)の量を制限することができますし、Pod・Service・PVC(Persistent Volume Claim)数なども制御することができます。
また、LimitRangeを指定することにより、Podなどに対してCPUやメモリのリソースの最大値・最小値を制限することができます。これにより、ユーザが不当に高い値を要求することを防ぐことができます。
どのような権限をコンテナに持たせるか制御しよう
Podの定義にSecurityContextを設定することにより、個々のコンテナに対して、特定のユーザでの実行や特権コンテナの作成などを制御することができます。また、PodSecurityPolicyを設定することにより、クラスタに対してセキュリティポリシーによる制限を行うこともできます。
例えば、これらの機能を利用することにより、rootユーザでの実行やノードに対してのアクセスなどを制御することができるようになります。
参考までに、PodSecurityPolicyで設定可能な項目は以下の通りです。
-
- privileged: Running of privileged containers
-
- hostPID, hostIPC: Usage of host namespaces
-
- hostNetwork, hostPorts: Usage of host networking and ports
-
- volumes: Usage of volume types
-
- allowedHostPaths: Usage of the host filesystem
allowedFlexVolumes: White list of Flexvolume drivers
fsGroup: Allocating an FSGroup that owns the pod’s volumes
readOnlyRootFilesystem: Requiring the use of a read only root file system
runAsUser, runAsGroup, supplementalGroups: The user and group IDs of the container
allowPrivilegeEscalation, defaultAllowPrivilegeEscalation: Restricting escalation to root privileges
defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities: Linux capabilities
seLinux: The SELinux context of the container
以下是一个在中国母语中的释义:
参考:https://kubernetes.io/docs/concepts/policy/pod-security-policy/
コンテナのネットワークアクセスを制御しよう
Namespaceに対してNetworkPolicyを設定することにより、他のNamespaceのPodからのアクセスを制御することができます。NetworkPolicyを有効化するには、CalicoなどのNetworkPolicyをサポートするネットワークプラグイン(CNIプラグイン)を利用して、クラスタを事前に構築しておく必要があります。
使用Calico的Kubernetes网络:
NetworkPolicyはIngressとEgressから成り立っており、インバウンド/アウトバウンドの通信を制御することができます。
控制对云服务元数据的API访问
AWS・Azure・GCEなどのクラウドサービスでは、メタデータをインスタンスとインスタンスで実行されているPodから参照することができます。メタデータにクラスタの認証情報が含まれている場合、同一クラスタ上でマルチテナントしているような環境では、この認証情報を悪用して攻撃される可能性があります。このため、クラウドサービス上でKubernetesを利用している場合、インスタンスの認証情報に付与されるアクセス権の制限や、NetworkPolicyを使用してメタデータAPIへのPodアクセスの制御などを実施する必要があります。
让我们控制将Pod部署在哪个节点上。
Podが配置されているノードを介して、機密情報を持ったPodから情報を抜かれることを防ぐため、機密情報を持ったPodは専用のノードに配置されるようにしましょう。KubernetesにはPodがどのノードに配置するか制御するため、ノードに対してTaints(汚れ)を着けておき、それを許容できるPodのみスケジューリングすることも可能です。
让我们保护集群组件免受未经授权的访问
etcdへのアクセスを制限しよう
Kubernetes APIと同様に、クラスタの構成情報を保持しているetcdへのアクセスも制御しましょう。Kubernests APIとのクライアント証明書による相互認証や、Kubernetes APIからのみアクセス可能なようにネットワーク通信を制御する必要があります。
激活审计日志
異常なAPI呼び出しがないか確認するため、監査ログ機能を有効化し、取得した監査ファイルを安全なサーバへアーカイブするようにしましょう。
限制使用Alpha版和Beta版的功能。
Kubernetesは頻繁に開発されているため、アルファ版やベータ版の機能がいくつか存在しており、これらはセキュリティ脆弱性をもたらすリスクがあります。このため、アルファ版やベータ版を利用することに懸念がある場合には、これらの機能を無効にするようにしましょう。
经常更换机密信息
Kubernetesでは、証明書に短い有効期間を設定し、自動的にローテートするように設定することが可能です。これにより、攻撃者が証明書を盗んで攻撃することが難しくなります。また、Kubernetes APIのAPI認証に、外部認証プロバイダの認証トークンを利用する場合には、トークンを頻繁に更新するようにしましょう。
導入する前にサードパーティーのプラグインを確認しよう
Kubernetesへのサードパーティーの統合は、クラスタのセキュリティ設定を変更する可能性があります。このため、サードパーティーを統合する前に、要求されたアクセス許可の内容を確認するようにしましょう。
etcdに格納された秘密情報を暗号化しよう
etcdデータベースには、Kubernetes APIを介してアクセス可能なあらゆる情報が含まれています。このため、暗号化ソリューションを活用してetcdのデータのバックアップを暗号化することや、EncryptionConfigurationを利用してデータを暗号化することが可能です。
証明書のローテート機能を活用しよう
kubeletは、Kubernetes APIへの認証に証明書を利用しています。デフォルトでは、これらの証明書の有効期限は1年に設定されているため、あまり頻繁に更新する必要はありません。
Kubernetes 1.8から、現在の証明書の有効期限が近づくと自動的に新しいキーを生成し、Kubernetes APIに新しい証明書を要求する、ベータ機能のkubelet証明書ローテーション機能がを利用することが可能です。2018年末に証明書更新漏れによる通信障害が記憶に新しいと思いますが、証明書を自動的にローテーションしてくれるとこういった障害がなくなるので便利ですね。
認証・認可の設定をしよう
認証プラグインを利用して認証しよう
Kubernetesは、クライアント証明書・bearerトークン・認証プロキシ・HTTP Basic認証などを利用して、認証プラグインを通じてAPI認証を要求することができます。利用可能な認証プラグインは以下の通りです。
-
- X509 Client Certs
-
- Static Token File
-
- Bootstrap Tokens
-
- Static Password File
-
- Service Account Tokens
-
- OpenID Connect Tokens
-
- Webhook Token Authentication
- Authenticating Proxy
请参考以下链接:https://kubernetes.io/zh/docs/reference/access-authn-authz/authentication/
使用基于角色的访问控制(RBAC)来对API进行授权。
Kubernetes APIに対して、Role-Based Access Control(RBAC)を使用して、アクセスを制限するようにしましょう。RABCには、Namespaceレベルのリソースとクラスタレベルのリソースの2種類が用意されていますが、Namespaceレベルのロール(Role)を利用して、クラスタレベルのロール(ClusterRole)の利用はなるべく避けるようにしましょう。(出展はCNCFのブログです)
请利用入场控制模块。
当Kubernetes API接收到请求时,将通过身份验证/授权/准入控制的阶段来注册资源。在准入控制阶段,可以对请求的内容进行判断,决定是否允许以及对接收到的资源进行修改,然后进行注册。
引用: https://kubernetes.io/docs/reference/access-authn-authz/controlling-access/
以下是可以通过Admission Control进行控制的项目。
-
- AlwaysAdmit (DEPRECATED)
-
- AlwaysPullImages
-
- AlwaysDeny (DEPRECATED)
-
- DefaultStorageClass
-
- DefaultTolerationSeconds
-
- DenyExecOnPrivileged (deprecated)
-
- DenyEscalatingExec
-
- EventRateLimit (alpha)
-
- ExtendedResourceToleration
-
- ImagePolicyWebhook
-
- Initializers (alpha)
-
- LimitPodHardAntiAffinityTopology
-
- LimitRanger
-
- MutatingAdmissionWebhook (beta in 1.9)
-
- NamespaceAutoProvision
-
- NamespaceExists
-
- NamespaceLifecycle
-
- NodeRestriction
-
- OwnerReferencesPermissionEnforcement
-
- PersistentVolumeLabel (DEPRECATED)
-
- PodNodeSelector
-
- PersistentVolumeClaimResize
-
- PodPreset
-
- PodSecurityPolicy
-
- PodTolerationRestriction
-
- Priority
-
- ResourceQuota
-
- SecurityContextDeny
-
- ServiceAccount
-
- Storage Object in Use Protection
- ValidatingAdmissionWebhook (alpha in 1.8; beta in 1.9)
参考:https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
请参考上述链接。
让Pod配置Service Account。
Podのコンテナ内のプロセスからKubernetes APIに対してアクセスが必要な場合には、Service Accountを利用してアクセスするようにしましょう。
加强容器镜像的安全性
使用可信的容器映像
2018年11月にDocker Hubに仮想通貨を発掘する不正なコンテナが公開されていたことがニュースになりました。
不正なコンテナがDocker Hubに登場し、仮想通貨を採掘する活動が行われています。これにはKubernetesの悪用も懸念されています。
このような脅威を防ぐため、信頼できる提供元からコンテナイメージを取得する必要性が出てきますが、Red Hatでは以下のURLの「Red Hat Container Catalog」からコンテナイメージを取得することができます。
Red Hat Container Catalog:
https://access.redhat.com/containers/
在使用在Docker Hub上发布的容器时,我们要确保这些容器是可信赖的。
コンテナイメージの脆弱性スキャンをしよう
様々なコンテナレジストリのプロダクトが存在していますが、コンテナレジストリには脆弱性スキャンを行う機能を持っているものがあります。脆弱性スキャンの機能を持っている主なコンテナレジストリは以下の通りです。
港口:https://harbor.com/
红帽 Quay:https://www.openshift.com/products/quay
除了Clair之外,还存在其他可以扫描容器漏洞的工具,因此我们可以利用这些工具来积极地扫描容器漏洞,以确保容器不会被漏洞侵入。
安全地运行容器
考虑改变容器运行时
从Kubernetes 1.12开始,RuntimeClass已经以Alpha版本发布,使得可以更改Kubernetes可用的容器运行时。
参考:https://kubernetes.io/blog/2018/10/10/kubernetes-v1.12-introducing-runtimeclass/
请参考以下链接:https://kubernetes.io/blog/2018/10/10/kubernetes-v1.12-introducing-runtimeclass/。
kubeletとコンテナランタイムとのインターフェースは、CRI(Container Runtime Interface)により標準化され、様々なコンテナラインタイムを選択できるようになっています。コンテナランタイムの中にはgVisorやKata Containersのように、コンテナからOSのシステムコールを直接呼び出しを防ぐコンテナランタイムも登場しています。マルチテナントの環境で、複数のテナントが一つのカーネルを共有するような環境の場合には、これらのコンテナラインタイムを活用することを検討しましょう。
请参考我之前整理过的关于容器运行时的文章。
以下是整理容器运行时趋势的一份报告:
https://qiita.com/mamomamo/items/ed5db2ab1555078f8a24
利用秘密资源
おそらくこの記事を読んでいる人は既にご存知だと思いますが、データベース接続のユーザ名やパスワードなどの秘密情報を安全にコンテナに渡すため、Secretリソースを活用しましょう。ただし、Secretを定義しているマニフェストはbase64でエンコーディングされていますが暗号化されているわけではないため、kubesecなどのマニフェストを暗号化するオープンソースソフトウェアの利用も検討しましょう。
kubesec: shyiko/kubesec 在 GitHub 上
最后
本記事を書くことにしたきっかけの一つは、システム全体のセキュリティを設計をする際に、Kubernetesのセキュリティは誰が検討するのか疑問に持ったことが理由です。サーバやネットワークのセキュリティ設計はインフラエンジニアが、アプリケーションのセキュリティ設計はアプリケーションエンジニアがという従来の通りの役割分担だと、Kubernetesのセキュリティ設計が抜け落ちてしまう懸念を持ったためです。Kubernetesのセキュリティ設計の必要性に早く認識してもらい、不要なセキュリティインシデントを防ぐ一助になれば良いなと考えております。
また、調べられる範囲で調査した内容を整理してみましたが、おそらくこれだけでは十分でないとも考えています。他にもこんな機能があるよとか、ご意見がある方はコメントいただけると幸いです。
请提供参考资料。
-
- 9 Kubernetes Security Best Practices Everyone Must Follow
Kubernetes Security