Kubernetes安全檢查清單是一個(gè)用于確保 Kubernetes 集群安全性的基本指導(dǎo)列表,提供了一些基本的檢查Kubernetes安全檢查清單是一個(gè)用于確保 Kubernetes 集群安全性的基本指導(dǎo)列表,包含認(rèn)證和鑒權(quán)、網(wǎng)絡(luò)安全、Pod安全、日志和審計(jì)等。
一、認(rèn)證和鑒權(quán)
1、在啟動(dòng)后 system:masters 組不用于用戶或組件的身份驗(yàn)證。
2、kube-controller-manager 運(yùn)行時(shí)要啟用 –use-service-account-credentials 參數(shù)。
3、根證書要受到保護(hù)(或離線 CA,或一個(gè)具有有效訪問控制的托管型在線 CA)。
4、中級(jí)證書和葉子證書的有效期不要超過未來 3 年。
5、存在定期訪問審查的流程,審查間隔不要超過 24 個(gè)月。
6、遵循基于角色的訪問控制良好實(shí)踐,以獲得與身份驗(yàn)證和授權(quán)相關(guān)的指導(dǎo)。
在啟動(dòng)后,用戶和組件都不應(yīng)以 system:masters 身份向 Kubernetes API 進(jìn)行身份驗(yàn)證。 同樣,應(yīng)避免將任何 kube-controller-manager 以 system:masters 運(yùn)行。 事實(shí)上,system:masters 應(yīng)該只用作一個(gè)例外機(jī)制,而不是管理員用戶。
二、網(wǎng)絡(luò)安全
以下是關(guān)于網(wǎng)絡(luò)安全的相關(guān)注意事項(xiàng):
1、使用的 CNI 插件可支持網(wǎng)絡(luò)策略。
2、對(duì)集群中的所有工作負(fù)載應(yīng)用入站和出站的網(wǎng)絡(luò)策略。
3、落實(shí)每個(gè)名字空間內(nèi)的默認(rèn)網(wǎng)絡(luò)策略,覆蓋所有 Pod,拒絕一切訪問。
4、如果合適,使用服務(wù)網(wǎng)格來加密集群內(nèi)的所有通信。
5、不在互聯(lián)網(wǎng)上公開 Kubernetes API、kubelet API 和 etcd。
6、過濾工作負(fù)載對(duì)云元數(shù)據(jù) API 的訪問。
7、限制使用 LoadBalancer 和 ExternalIP。
許多容器網(wǎng)絡(luò)接口(Container Network Interface,CNI)插件提供了限制 Pod 可能與之通信的網(wǎng)絡(luò)資源的功能。這種限制通常通過網(wǎng)絡(luò)策略來完成,網(wǎng)絡(luò)策略提供了一種名字空間作用域的資源來定義規(guī)則。在每個(gè)名字空間中,默認(rèn)的網(wǎng)絡(luò)策略會(huì)阻塞所有的出入站流量,并選擇所有 Pod,采用允許列表的方法很有用,可以確保不遺漏任何工作負(fù)載。并非所有 CNI 插件都在傳輸過程中提供加密。如果所選的插件缺少此功能,一種替代方案是可以使用服務(wù)網(wǎng)格來提供該功能。
控制平面的 etcd 數(shù)據(jù)存儲(chǔ)應(yīng)該實(shí)施訪問限制控制,并且不要在互聯(lián)網(wǎng)上公開。此外,應(yīng)使用雙向 TLS(mTLS)與其進(jìn)行安全通信。用在這里的證書機(jī)構(gòu)應(yīng)該僅用于 etcd。應(yīng)該限制外部互聯(lián)網(wǎng)對(duì) Kubernetes API 服務(wù)器未公開的 API 的訪問。請(qǐng)小心,因?yàn)樵S多托管的 Kubernetes 發(fā)行版在默認(rèn)情況下公開了 API 服務(wù)器。當(dāng)然,可以使用堡壘機(jī)訪問服務(wù)器。
對(duì) kubelet API 的訪問應(yīng)該受到限制,并且不公開,當(dāng)沒有使用 –config 參數(shù)來設(shè)置配置文件時(shí),默認(rèn)的身份驗(yàn)證和鑒權(quán)設(shè)置是過于寬松的。如果使用云服務(wù)供應(yīng)商托管的 Kubernetes,在沒有明確需要的情況下,也應(yīng)該限制或阻止從 Pod 對(duì)云元數(shù)據(jù) API 169.254.169.254 的訪問,因?yàn)檫@可能泄露信息。
三、Pod安全
- 僅在必要時(shí)才授予 create、update、patch、delete 工作負(fù)載的 RBAC 權(quán)限;
- 對(duì)所有名字空間實(shí)施適當(dāng)?shù)?Pod 安全標(biāo)準(zhǔn)策略,并強(qiáng)制執(zhí)行;
- 為工作負(fù)載設(shè)置內(nèi)存限制值,并確保限制值等于或者不高于請(qǐng)求值;
- 對(duì)敏感工作負(fù)載可以設(shè)置 CPU 限制;
- 對(duì)于支持 Seccomp 的節(jié)點(diǎn),可以為程序啟用合適的系統(tǒng)調(diào)用配置文件;
- 對(duì)于支持 AppArmor 或 SELinux 的系統(tǒng),可以為程序啟用合適的配置文件。
RBAC 的授權(quán)是至關(guān)重要的,但不能在足夠細(xì)的粒度上對(duì) Pod 的資源進(jìn)行授權(quán),也不足以對(duì)管理 Pod 的任何資源進(jìn)行授權(quán)。唯一的粒度是資源本身上的 API 動(dòng)作,例如,對(duì) Pod 的 create。在未指定額外許可的情況下,創(chuàng)建這些資源的權(quán)限允許直接不受限制地訪問集群的可調(diào)度節(jié)點(diǎn)。
Pod 安全性標(biāo)準(zhǔn)定義了三種不同的策略:特權(quán)策略(Privileged)、基線策略(Baseline)和限制策略(Restricted),它們限制了 PodSpec 中關(guān)于安全的字段的設(shè)置。這些標(biāo)準(zhǔn)可以通過默認(rèn)啟用的新的 Pod 安全性準(zhǔn)入或第三方準(zhǔn)入 Webhook 在名字空間級(jí)別強(qiáng)制執(zhí)行。請(qǐng)注意,與它所取代的、已被移除的 PodSecurityPolicy 準(zhǔn)入機(jī)制相反,Pod 安全性準(zhǔn)入可以輕松地與準(zhǔn)入 Webhook 和外部服務(wù)相結(jié)合使用。
restricted Pod 安全準(zhǔn)入策略是 Pod 安全性標(biāo)準(zhǔn)集中最嚴(yán)格的策略,可以在多種模式下運(yùn)行,根據(jù)最佳安全實(shí)踐,逐步地采用 warn、audit 或者 enforce 模式以應(yīng)用最合適的安全上下文(Security Context)。盡管如此,對(duì)于特定的用例,應(yīng)該單獨(dú)審查 Pod 的安全上下文,以限制 Pod 在預(yù)定義的安全性標(biāo)準(zhǔn)之上可能具有的特權(quán)和訪問權(quán)限。
為了限制一個(gè) Pod 可以使用的內(nèi)存和 CPU 資源,應(yīng)該設(shè)置 Pod 在節(jié)點(diǎn)上可消費(fèi)的內(nèi)存和 CPU 限制,從而防止來自惡意的或已被攻破的工作負(fù)載的潛在 DoS 攻擊。這種策略可以由準(zhǔn)入控制器強(qiáng)制執(zhí)行。請(qǐng)注意,CPU 限制設(shè)置可能會(huì)影響 CPU 用量,從而可能會(huì)對(duì)自動(dòng)擴(kuò)縮功能或效率產(chǎn)生意外的影響,換言之,系統(tǒng)會(huì)在可用的 CPU 資源下最大限度地運(yùn)行進(jìn)程。
注意:內(nèi)存限制高于請(qǐng)求的,可能會(huì)使整個(gè)節(jié)點(diǎn)面臨 OOM 問題。
1、啟用 Seccomp
Seccomp 代表安全計(jì)算模式(Secure computing mode),這是一個(gè)自 Linux 內(nèi)核版本 2.6.12 被加入的特性。 它可以將進(jìn)程的特權(quán)沙箱化,來限制從用戶空間發(fā)起的對(duì)內(nèi)核的調(diào)用。 Kubernetes 允許將加載到節(jié)點(diǎn)上的 Seccomp 配置文件自動(dòng)應(yīng)用于 Pod 和容器。
Seccomp 通過減少容器內(nèi)對(duì) Linux 內(nèi)核的系統(tǒng)調(diào)用(System Call)以縮小攻擊面,從而提高工作負(fù)載的安全性。 Seccomp 過濾器模式借助 BPF 創(chuàng)建具體系統(tǒng)調(diào)用的允許清單或拒絕清單,名為配置文件(Profile)。
從 Kubernetes 1.27 開始,可以將 RuntimeDefault 設(shè)置為工作負(fù)載的默認(rèn) Seccomp 配置。 可以閱讀相應(yīng)的安全教程。 此外,Kubernetes Security Profiles Operator 是一個(gè)方便在集群中管理和使用 Seccomp 的項(xiàng)目。
注意:Seccomp 僅適用于 Linux 節(jié)點(diǎn)。
2、啟用 AppArmor 或 SELinux
(1)AppArmor
AppArmor 是一個(gè) Linux 內(nèi)核安全模塊, 可以提供一種簡(jiǎn)單的方法來實(shí)現(xiàn)強(qiáng)制訪問控制(Mandatory Access Control, MAC)并通過系統(tǒng)日志進(jìn)行更好地審計(jì)。 要在 Kubernetes 中啟用 AppArmor,至少需要 1.4 版本。 與 Seccomp 一樣,AppArmor 也通過配置文件進(jìn)行配置, 其中每個(gè)配置文件要么在強(qiáng)制(Enforcing)模式下運(yùn)行,即阻止訪問不允許的資源,要么在投訴(Complaining)模式下運(yùn)行,只報(bào)告違規(guī)行為。 AppArmor 配置文件是通過注解的方式,以容器為粒度強(qiáng)制執(zhí)行的,允許進(jìn)程獲得剛好合適的權(quán)限。
(2)SELinux
SELinux 也是一個(gè) Linux 內(nèi)核安全模塊,可以提供支持訪問控制安全策略的機(jī)制,包括強(qiáng)制訪問控制(MAC)。 SELinux 標(biāo)簽可以通過 securityContext 節(jié)指配給容器或 Pod。
注意:AppArmor和SELinux 僅在 Linux 節(jié)點(diǎn)上可用, 在一些 Linux 發(fā)行版中已啟用。
四、日志和審計(jì)
1、審計(jì)日志(如果啟用)將受到保護(hù)以防止常規(guī)訪問。
2、 /logs API 被禁用(所運(yùn)行的 kube-apiserver 設(shè)置了 –enable-logs-handler=false)。
Kubernetes 包含一個(gè) /logs API 端點(diǎn),默認(rèn)啟用,這個(gè)端點(diǎn)允許用戶通過 HTTP 來請(qǐng)求 API 服務(wù)器的 /var/log 目錄的內(nèi)容。 訪問此端點(diǎn)需要身份驗(yàn)證,允許大范圍訪問 Kubernetes 日志可能會(huì)令安全信息被潛在的攻擊者利用。
好的做法是設(shè)置一個(gè)單獨(dú)的方式來收集和聚合控制平面日志, 并且不要使用 /logs API 端點(diǎn)。另一個(gè)使用場(chǎng)景是運(yùn)行控制平面時(shí)啟用了 /logs API 端點(diǎn)并 (在運(yùn)行 API 服務(wù)器的主機(jī)或容器內(nèi))將 /var/log 的內(nèi)容限制為僅保存 Kubernetes API 服務(wù)器日志。
五、Pod布局
- Pod 布局是根據(jù)應(yīng)用程序的敏感級(jí)別來完成的;
- 敏感應(yīng)用程序在節(jié)點(diǎn)上隔離運(yùn)行或使用特定的沙箱運(yùn)行時(shí)運(yùn)行。
處于不同敏感級(jí)別的 Pod,例如,應(yīng)用程序 Pod 和 Kubernetes API 服務(wù)器,應(yīng)該部署到不同的節(jié)點(diǎn)上。 節(jié)點(diǎn)隔離的目的是防止應(yīng)用程序容器的逃逸,進(jìn)而直接訪問敏感度更高的應(yīng)用, 甚至輕松地改變集群工作機(jī)制。 這種隔離應(yīng)該被強(qiáng)制執(zhí)行,以防止 Pod 集合被意外部署到同一節(jié)點(diǎn)上。 可以通過以下功能實(shí)現(xiàn):
1、節(jié)點(diǎn)選擇器(Node Selector)
作為 Pod 規(guī)約的一部分來設(shè)置的鍵值對(duì),指定 Pod 可部署到哪些節(jié)點(diǎn)。 通過 PodNodeSelector 準(zhǔn)入控制器可以在名字空間和集群級(jí)別強(qiáng)制實(shí)施節(jié)點(diǎn)選擇。
2、PodTolerationRestriction
容忍度準(zhǔn)入控制器, 允許管理員設(shè)置在名字空間內(nèi)允許使用的容忍度。 名字空間中的 Pod 只能使用名字空間對(duì)象的注解鍵上所指定的容忍度,這些鍵提供默認(rèn)和允許的容忍度集合。
3、RuntimeClass
RuntimeClass 是一個(gè)用于選擇容器運(yùn)行時(shí)配置的特性,容器運(yùn)行時(shí)配置用于運(yùn)行 Pod 中的容器, 并以性能開銷為代價(jià)提供或多或少的主機(jī)隔離能力。
六、Secrets
- 不用 ConfigMap 保存機(jī)密數(shù)據(jù);
- 為 Secret API 配置靜態(tài)加密;
- 如果合適,可以部署和使用一種機(jī)制,負(fù)責(zé)注入保存在第三方存儲(chǔ)中的 Secret;
- 不應(yīng)該將服務(wù)賬號(hào)令牌掛載到不需要它們的 Pod 中;
- 使用綁定的服務(wù)賬號(hào)令牌卷, 而不要使用不會(huì)過期的令牌。
Pod 所需的秘密信息應(yīng)該存儲(chǔ)在 Kubernetes Secret 中,而不是像 ConfigMap 這樣的替代品中。 存儲(chǔ)在 etcd 中的 Secret 資源應(yīng)該被靜態(tài)加密。
需要 Secret 的 Pod 應(yīng)該通過卷自動(dòng)掛載這些信息,最好使用 emptyDir.medium 選項(xiàng)存儲(chǔ)在內(nèi)存中。該機(jī)制還可以用于從第三方存儲(chǔ)中注入 Secret 作為卷,如 Secret Store CSI 驅(qū)動(dòng)。與通過 RBAC 來允許 Pod 服務(wù)賬號(hào)訪問 Secret 相比,應(yīng)該優(yōu)先使用上述機(jī)制。這種機(jī)制允許將 Secret 作為環(huán)境變量或文件添加到 Pod 中。請(qǐng)注意,與帶訪問權(quán)限控制的文件相比,由于日志的崩潰轉(zhuǎn)儲(chǔ),以及 Linux 的環(huán)境變量的非機(jī)密性,環(huán)境變量方法可能更容易發(fā)生泄漏。
不應(yīng)該將服務(wù)賬號(hào)令牌掛載到不需要它們的 Pod 中。這可以通過在服務(wù)賬號(hào)內(nèi)將 automountServiceAccountToken 設(shè)置為 false 來完成整個(gè)名字空間范圍的配置,或者也可以單獨(dú)在 Pod 層面定制。對(duì)于 Kubernetes v1.22 及更高版本,請(qǐng)使用綁定服務(wù)賬號(hào)作為有時(shí)間限制的服務(wù)賬號(hào)憑證。
七、鏡像
- 盡量減少容器鏡像中不必要的內(nèi)容;
- 容器鏡像配置為以非特權(quán)用戶身份運(yùn)行;
- 對(duì)容器鏡像的引用是通過 Sha256 摘要實(shí)現(xiàn)的,而不是標(biāo)簽(tags), 或者通過準(zhǔn)入控制器在部署時(shí)驗(yàn)證鏡像的數(shù)字簽名來驗(yàn)證鏡像的來源;
- 在創(chuàng)建和部署過程中定期掃描容器鏡像,并對(duì)已知的漏洞軟件進(jìn)行修補(bǔ)。
容器鏡像應(yīng)該包含運(yùn)行其所打包的程序所需要的最少內(nèi)容, 最好只使用程序及其依賴項(xiàng),基于最小的基礎(chǔ)鏡像來構(gòu)建鏡像。 尤其是,在生產(chǎn)中使用的鏡像不應(yīng)包含 Shell 或調(diào)試工具, 因?yàn)榭梢允褂门R時(shí)調(diào)試容器進(jìn)行故障排除。
構(gòu)建鏡像時(shí)使用 Dockerfile 中的 USER 指令直接開始使用非特權(quán)用戶。 安全上下文(Security Context) 允許使用 runAsUser 和 runAsGroup 來指定使用特定的用戶和組來啟動(dòng)容器鏡像, 即使沒有在鏡像清單文件(Manifest)中指定這些配置信息。 不過,鏡像層中的文件權(quán)限設(shè)置可能無法做到在不修改鏡像的情況下,使用新的非特權(quán)用戶來啟動(dòng)進(jìn)程。
避免使用鏡像標(biāo)簽來引用鏡像,尤其是 latest 標(biāo)簽,因?yàn)闃?biāo)簽對(duì)應(yīng)的鏡像可以在倉庫中被輕松地修改。 首選使用完整的 Sha256 摘要,該摘要對(duì)特定鏡像清單文件而言是唯一的。 可以通過 ImagePolicyWebhook 強(qiáng)制執(zhí)行此策略。 鏡像簽名還可以在部署時(shí)由準(zhǔn)入控制器自動(dòng)驗(yàn)證, 以驗(yàn)證其真實(shí)性和完整性。
掃描容器鏡像可以防止關(guān)鍵性的漏洞隨著容器鏡像一起被部署到集群中。 鏡像掃描應(yīng)在將容器鏡像部署到集群之前完成,通常作為 CI/CD 流水線中的部署過程的一部分來完成。 鏡像掃描的目的是獲取有關(guān)容器鏡像中可能存在的漏洞及其預(yù)防措施的信息, 例如使用公共漏洞評(píng)分系統(tǒng) (Common Vulnerability Scoring System,CVSS)評(píng)分。 如果鏡像掃描的結(jié)果與管道合性規(guī)則匹配,則只有經(jīng)過正確修補(bǔ)的容器鏡像才會(huì)最終進(jìn)入生產(chǎn)環(huán)境。
八、準(zhǔn)入控制器
- 選擇啟用適當(dāng)?shù)臏?zhǔn)入控制器;
- Pod 安全策略由 Pod 安全準(zhǔn)入強(qiáng)制執(zhí)行,或者和 Webhook 準(zhǔn)入控制器一起強(qiáng)制執(zhí)行;
- 保證準(zhǔn)入鏈插件和 Webhook 的配置都是安全的。
準(zhǔn)入控制器可以幫助提高集群的安全性。 然而,由于它們是對(duì) API 服務(wù)器的擴(kuò)展,其自身可能會(huì)帶來風(fēng)險(xiǎn), 所以它們應(yīng)該得到適當(dāng)?shù)谋Wo(hù)。
下面列出了一些準(zhǔn)入控制器,可以考慮用這些控制器來增強(qiáng)集群和應(yīng)用程序的安全狀況。 列表中包括了可能在本文檔其他部分曾提及的控制器。第一組準(zhǔn)入控制器包括默認(rèn)啟用的插件, 除非知道自己在做什么,否則請(qǐng)考慮保持它們處于被啟用的狀態(tài):
- CertificateApproval:執(zhí)行額外的授權(quán)檢查,以確保審批用戶具有審批證書請(qǐng)求的權(quán)限。
- CertificateSigning:執(zhí)行其他授權(quán)檢查,以確保簽名用戶具有簽名證書請(qǐng)求的權(quán)限。
- CertificateSubjectRestriction:拒絕將 group(或 organization attribute)設(shè)置為 system:masters 的所有證書請(qǐng)求。
- LimitRanger:強(qiáng)制執(zhí)行 LimitRange API 約束。
- MutatingAdmissionWebhook:允許通過 Webhook 使用自定義控制器,這些控制器可能會(huì)變更它所審查的請(qǐng)求。
- PodSecurity:Pod Security Policy 的替代品,用于約束所部署 Pod 的安全上下文。
- ResourceQuota:強(qiáng)制執(zhí)行資源配額,以防止資源被過度使用。
- ValidatingAdmissionWebhook:允許通過 Webhook 使用自定義控制器,這些控制器不變更它所審查的請(qǐng)求。
第二組包括默認(rèn)情況下沒有啟用、但處于正式發(fā)布狀態(tài)的插件,建議啟用這些插件以改善安全狀況:
- DenyServiceExternalIPs:拒絕使用 Service.spec.externalIPs 字段,已有的 Service 不受影響,新增或者變更時(shí)不允許使用。 這是 CVE-2020-8554:中間人使用 LoadBalancer 或 ExternalIP 的緩解措施。
- NodeRestriction:將 kubelet 的權(quán)限限制為只能修改其擁有的 Pod API 資源或代表其自身的節(jié)點(diǎn) API 資源。 此插件還可以防止 kubelet 使用 node-restriction.kubernetes.io/ 注解, 攻擊者可以使用該注解來訪問 kubelet 的憑證,從而影響所控制的節(jié)點(diǎn)上的 Pod 布局。
第三組包括默認(rèn)情況下未啟用,但可以考慮在某些場(chǎng)景下啟用的插件:
- AlwaysPullImages:強(qiáng)制使用最新版本標(biāo)記的鏡像,并確保部署者有權(quán)使用該鏡像。
- ImagePolicyWebhook:允許通過 Webhook 對(duì)鏡像強(qiáng)制執(zhí)行額外的控制。