在本文中,我們將演示如何使用OPA執(zhí)行最細粒度的安全策略铁材。請注意碗暗,本文是一個系列的一部分探熔,我們將基于“OPA作為代碼介紹”和“集成OPA到Kubernetes”中獲得的知識進行亩鬼。如果你還沒有這樣做殖告,請瀏覽本系列中已發(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安全策略雳锋,可以在其中對Pod應用非常特定的安全控制黄绩。例如,使用Linux內(nèi)核功能玷过,使用主機命名空間爽丹、網(wǎng)絡、端口或文件系統(tǒng)辛蚊,以及其他許多功能粤蝎。使用OPA,你還可以對pods施加類似的控制嚼隘,在本實驗室中诽里,我們將創(chuàng)建一個OPA策略,不允許在pods中創(chuàng)建有特權的容器飞蛹。特權容器對主機的訪問級別比非特權容器高。
為什么使用OPA而不是原生的Pod安全策略灸眼?
使用Pod安全策略來執(zhí)行我們的安全策略并沒有什么問題卧檐。然而,根據(jù)定義焰宣,PSP只能應用于pods霉囚。它們不能處理其他Kubernetes資源,如Ingresses匕积、Deployments盈罐、Services等榜跌。OPA的強大之處在于它可以應用于任何Kubernetes資源。OPA作為一個許可控制器部署到Kubernetes盅粪,它攔截發(fā)送到API服務器的API調(diào)用钓葫,并驗證和/或修改它們。相應地票顾,你可以有一個統(tǒng)一的OPA策略础浮,適用于系統(tǒng)的不同組件,而不僅僅是pods奠骄。例如豆同,有一種策略,強制用戶在其服務中使用公司的域含鳞,并確保用戶只從公司的鏡像存儲庫中提取鏡像影锈。請注意,我們使用的OPA是使用kube-mgmt部署的蝉绷,而不是OPA Gatekeeper精居。
Rego的策略代碼
在本文中,我們假設你已經(jīng)熟悉了OPA和Rego語言潜必。我們還假設你有一個正在運行的Kubernetes集群靴姿,該集群部署了OPA和kube-mgmt容器。有關安裝說明磁滚,請參閱我們的前一篇文章佛吓。我們的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[_]
}
讓我們簡要地瀏覽一下這個文件:
第1行:包含package。注意垂攘,你必須使用kubernetes.admission讓政策工作维雇。
第2行:Deny是默認對象,它將包含我們需要執(zhí)行的策略晒他。如果所包含的代碼計算結(jié)果為true吱型,則將違反策略。
第3行:我們定義了一個變量陨仅,它將容納pod中的所有容器津滞,并從稍后定義的input_containers[c]接收值。
第4行:如果pod包含“privileged”屬性灼伤,則該語句為true触徐。
第5行:當用戶嘗試運行特權容器時顯示給他們的消息。它包括容器名稱和違規(guī)的安全上下文狐赡。
第7-9行:input_containers[c]函數(shù)從請求對象中提取容器撞鹉。注意,使用了_字符來遍歷數(shù)組中的所有容器。在Rego中鸟雏,你不需要定義循環(huán)—下劃線字符將自動為你完成此操作享郊。
第10-12行:我們再次為init容器定義函數(shù)。請注意孝鹊,在Rego中炊琉,可以多次定義同一個函數(shù)。這樣做是為了克服Rego函數(shù)中不能返回多個輸出的限制惶室。當調(diào)用函數(shù)名時温自,將執(zhí)行兩個函數(shù),并使用AND操作符組合輸出皇钞。因此悼泌,在我們的例子中,在一個或多個位置中存在一個有特權的容器將違反策略夹界。
部署策略
OPA會在opa命名空間的ConfigMaps中找到它的策略馆里。要將我們的代碼應用到ConfigMap中,我們運行以下命令:
kubectl create configmap no-priv-pods --from-file=no-priv-pod.rego
kube-mgmt邊車(sidecar)容器在opa命名空間中持續(xù)監(jiān)視API服務器可柿,以便你只需創(chuàng)建ConfigMap就可以部署策略鸠踪。
運行策略
讓我們通過嘗試部署一個特權容器來確保我們的策略是有效的:
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}
請注意,我們有意將pod部署到默認命名空間复斥,因為我們的admission webhook將忽略在opa命名空間或kube-system中創(chuàng)建的任何資源营密。
總結(jié)
OPA是一種通用的、平臺無感的策略實施工具目锭,可以通過多種方式與Kubernetes集成评汰。
你可以使用OPA策略來模擬Pod安全策略痢虹,以防止在集群上調(diào)度特權容器。
因為OPA可以與其他Kubernetes資源一起工作奖唯,而不僅僅是Pods,所以建議使用它來創(chuàng)建跨越所有相關資源的集群級策略文檔丰捷。