kubernetes OPA(open policy agent)

在本文中,我們將演示如何使用OPA執(zhí)行最細(xì)粒度的安全策略。請(qǐng)注意,本文是一個(gè)系列的一部分,我們將基于“OPA作為代碼介紹”和“集成OPA到Kubernetes”中獲得的知識(shí)進(jìn)行。如果你還沒(méi)有這樣做,請(qǐng)瀏覽本系列中已發(fā)表的文章。

https://www.magalix.com/blog/introducing-policy-as-code-the-open-policy-agent-opa
https://www.magalix.com/blog/integrating-open-policy-agent-opa-with-kubernetes-a-deep-dive-tutorial

你可能已經(jīng)熟悉Pod安全策略,可以在其中對(duì)Pod應(yīng)用非常特定的安全控制。例如,使用Linux內(nèi)核功能,使用主機(jī)命名空間、網(wǎng)絡(luò)、端口或文件系統(tǒng),以及其他許多功能。使用OPA,你還可以對(duì)pods施加類似的控制,在本實(shí)驗(yàn)室中,我們將創(chuàng)建一個(gè)OPA策略,不允許在pods中創(chuàng)建有特權(quán)的容器。特權(quán)容器對(duì)主機(jī)的訪問(wèn)級(jí)別比非特權(quán)容器高。

為什么使用OPA而不是原生的Pod安全策略?

使用Pod安全策略來(lái)執(zhí)行我們的安全策略并沒(méi)有什么問(wèn)題。然而,根據(jù)定義,PSP只能應(yīng)用于pods。它們不能處理其他Kubernetes資源,如Ingresses、Deployments、Services等。OPA的強(qiáng)大之處在于它可以應(yīng)用于任何Kubernetes資源。OPA作為一個(gè)許可控制器部署到Kubernetes,它攔截發(fā)送到API服務(wù)器的API調(diào)用,并驗(yàn)證和/或修改它們。相應(yīng)地,你可以有一個(gè)統(tǒng)一的OPA策略,適用于系統(tǒng)的不同組件,而不僅僅是pods。例如,有一種策略,強(qiáng)制用戶在其服務(wù)中使用公司的域,并確保用戶只從公司的鏡像存儲(chǔ)庫(kù)中提取鏡像。請(qǐng)注意,我們使用的OPA是使用kube-mgmt部署的,而不是OPA Gatekeeper。

Rego的策略代碼

在本文中,我們假設(shè)你已經(jīng)熟悉了OPA和Rego語(yǔ)言。我們還假設(shè)你有一個(gè)正在運(yùn)行的Kubernetes集群,該集群部署了OPA和kube-mgmt容器。有關(guān)安裝說(shuō)明,請(qǐng)參閱我們的前一篇文章。我們的no-priv-pod.rego文件如下所示:

package kubernetes.admission
deny[msg] {
  c := input_containers[_]
  c.securityContext.privileged
  msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
}
input_containers[c] {
  c := input.request.object.spec.containers[_]
}
input_containers[c] {
  c := input.request.object.spec.initContainers[_]
}

讓我們簡(jiǎn)要地瀏覽一下這個(gè)文件:

第1行:包含package。注意,你必須使用kubernetes.admission讓政策工作。

第2行:Deny是默認(rèn)對(duì)象,它將包含我們需要執(zhí)行的策略。如果所包含的代碼計(jì)算結(jié)果為true,則將違反策略。

第3行:我們定義了一個(gè)變量,它將容納pod中的所有容器,并從稍后定義的input_containers[c]接收值。

第4行:如果pod包含“privileged”屬性,則該語(yǔ)句為true。

第5行:當(dāng)用戶嘗試運(yùn)行特權(quán)容器時(shí)顯示給他們的消息。它包括容器名稱和違規(guī)的安全上下文。

第7-9行:input_containers[c]函數(shù)從請(qǐng)求對(duì)象中提取容器。注意,使用了_字符來(lái)遍歷數(shù)組中的所有容器。在Rego中,你不需要定義循環(huán)—下劃線字符將自動(dòng)為你完成此操作。

第10-12行:我們?cè)俅螢閕nit容器定義函數(shù)。請(qǐng)注意,在Rego中,可以多次定義同一個(gè)函數(shù)。這樣做是為了克服Rego函數(shù)中不能返回多個(gè)輸出的限制。當(dāng)調(diào)用函數(shù)名時(shí),將執(zhí)行兩個(gè)函數(shù),并使用AND操作符組合輸出。因此,在我們的例子中,在一個(gè)或多個(gè)位置中存在一個(gè)有特權(quán)的容器將違反策略。

部署策略

OPA會(huì)在opa命名空間的ConfigMaps中找到它的策略。要將我們的代碼應(yīng)用到ConfigMap中,我們運(yùn)行以下命令:

kubectl create configmap no-priv-pods --from-file=no-priv-pod.rego
kube-mgmt邊車(sidecar)容器在opa命名空間中持續(xù)監(jiān)視API服務(wù)器,以便你只需創(chuàng)建ConfigMap就可以部署策略。

運(yùn)行策略

讓我們通過(guò)嘗試部署一個(gè)特權(quán)容器來(lái)確保我們的策略是有效的:

kubectl -n default apply -f - <<EOT
apiVersion: v1
kind: Pod
metadata:
 name: nginx-privileged
 labels:
  app: nginx-privileged
spec:
 containers:
 - name: nginx
  image: nginx
  securityContext:
   privileged: true #false
EOT

Error from server (Privileged container is not allowed: nginx, securityContext: {"privileged": true}): error when creating "STDIN": admission webhook "validating-webhook.openpolicyagent.org" denied the request: Privileged container is not allowed: nginx, securityContext: {"privileged": true}
請(qǐng)注意,我們有意將pod部署到默認(rèn)命名空間,因?yàn)槲覀兊腶dmission webhook將忽略在opa命名空間或kube-system中創(chuàng)建的任何資源。

總結(jié)

OPA是一種通用的、平臺(tái)無(wú)感的策略實(shí)施工具,可以通過(guò)多種方式與Kubernetes集成。

你可以使用OPA策略來(lái)模擬Pod安全策略,以防止在集群上調(diào)度特權(quán)容器。

因?yàn)镺PA可以與其他Kubernetes資源一起工作,而不僅僅是Pods,所以建議使用它來(lái)創(chuàng)建跨越所有相關(guān)資源的集群級(jí)策略文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容