Seccomp 簡介
Seccomp(全稱 “Secure computing”),早在 2.6.12 版本(2005年3月8日)就引入到內(nèi)核中,是通過只允許內(nèi)核支持部分 syscall(系統(tǒng)調(diào)用),或者拒絕內(nèi)核認為可能有危險的 syscall 集合的方式,來限制一個進程所支持的 syscall調(diào)用。
最初,Seccomp 只允許使用read、 write、_exit、sigreturn 4個系統(tǒng)調(diào)用,一旦調(diào)用其他系統(tǒng)調(diào)用時,內(nèi)核就會發(fā)送 SIGKILL 信號終止進程。因此也被稱為 Seccomp-strict 模式。但由于其限制過于嚴格,導致實際上,并沒有多少應(yīng)用能夠用的上這一安全特性。
直到 3.5 版本(2012年7月12日)的內(nèi)核中引入 Seccomp的第二種匹配模式。
在這種模式下,可以通過所謂的 filter自定義被允許使用的 syscall,而自定義過濾規(guī)則是借由BPF 語言來實現(xiàn),故可以事先在用戶態(tài)下定義好需要匹配的系統(tǒng)調(diào)用,并且加載到內(nèi)核中,這種模式也被稱為Seccomp-BPF。
相比于 Seccomp-strict 模式,Seccomp-BPF 極大的增添了 syscall 的可擴展性,并且使用 BPF 編寫也大大的降低了開發(fā)者的編寫難度。
現(xiàn)如今,關(guān)鍵的程序限制為只允許調(diào)用那些「它絕對需要的成功運行的系統(tǒng)調(diào)用」,這種思想被越來越多的產(chǎn)品采納。基于瀏覽器的沙箱和在云原生上大火的容器就是就是兩個很好的示例,甚至于 systemd 服務(wù)也能夠通過 Seccomp 來限制。
一個 seccomp profile 簡單示例如下:
{ "defaultAction": "SCMP_ACT_ERRNO", "architectures": [ "SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32" ], "syscalls": [ { "names": [ "madvise", "epoll_ctl", "getsockname", "setsockopt", "vfork", "mmap", "read", ], "action": "SCMP_ACT_ALLOW", } ] }
如何理解這個 Seccomp profile 呢?
SCMP_ACT_ALLOW 表示syscall 允許通過,將defaultAction 設(shè)置為 SCMP_ACT_ERRNO 則不在 syscall白名單范圍內(nèi)的 syscall 都會被拒絕,還可以將defaultAction 設(shè)置為 SCMP_ACT_LOG 則不在 syscall 白名單范圍內(nèi)的 syscall 會產(chǎn)生日志。
通過 Seccomp Profile 用于可以根據(jù)服務(wù)所需的 syscall 自行定義,通過 SCMP_ACT_ERRNO 與SCMP_ACT_ALLOW 配合實現(xiàn)對允許的 syscall 放行,對不在 syscall 列表中的 syscall 進行攔截。從而實現(xiàn) syscall維度服務(wù)的安全防護。
SCMP_ACT_LOG與SCMP_ACT_ERRNO 可以在不同場景使用,進而實現(xiàn)不同程度的安全防護即告警和攔截。
Linux 內(nèi)核主要支持的 Seccomp Filter 動作如下:
Seccomp Filter Action | Description |
SCMP_ACT_KILL | 當線程產(chǎn)生的系統(tǒng)調(diào)用與過濾規(guī)則相匹配時,線程將被內(nèi)核以SIGSYS的方式終止。 |
SCMP_ACT_KILL_PROCESS | 當進程產(chǎn)生的系統(tǒng)調(diào)用與過濾規(guī)則相匹配時,進程將被終止。 |
SCMP_ACT_TRAP | 當線程產(chǎn)生的系統(tǒng)調(diào)用與過濾規(guī)則相匹配時,線程將會拋出一個SIGSYS信號。 |
SCMP_ACT_ERRNO | 當線程產(chǎn)生的系統(tǒng)調(diào)用與過濾規(guī)則相匹配時,它將收到errno的一個返回值。 |
SCMP_ACT_TRACE | 如果線程正在被跟蹤,并且跟蹤進程時在對ptrace(2)的調(diào)用中指定了PTRACE_O_TRACESECCOMP選項,則將會通過 PTRACE_EVENT_SECCOMP通知跟蹤進程,并且可以使用PTRACE_GETEVENTMSG 選項檢索msg_num中提供的值。 |
SCMP_ACT_LOG | 當線程產(chǎn)生的系統(tǒng)調(diào)用與過濾規(guī)則相匹配時,則它不會對調(diào)用系統(tǒng)調(diào)用的線程產(chǎn)生任何影響,但系統(tǒng)調(diào)用會被記錄到日志。 |
SCMP_ACT_ALLOW | 當線程產(chǎn)生的系統(tǒng)調(diào)用與過濾規(guī)則相匹配時,則它不會對調(diào)用系統(tǒng)調(diào)用的線程產(chǎn)生任何影響。 |
SCMP_ACT_NOTIFY | 當進程產(chǎn)生與seccomp過濾規(guī)則匹配的系統(tǒng)調(diào)用時,內(nèi)核將會通知正在監(jiān)視的用戶態(tài)進程。該進程在內(nèi)核中產(chǎn)生了系統(tǒng)調(diào)用等待,直到監(jiān)視進程返回seccomp_notify_respond(3)。 |
Seccomp in Kubernetes
從安全的角度來看,Kubernetes 中包含如下所示的潛在攻擊面:
為了保證集群以及容器應(yīng)用的安全,Kubernetes 提供了多種安全機制,限制容器的行為,減少容器和集群的攻擊面,保證整個系統(tǒng)的安全性。
本文主要介紹 Kubernetes 中的 Seccomp 功能。Seccomp (Secure computing mode縮寫)代表安全計算模式,自 2.6.12 版本以來一直是 Linux 內(nèi)核的一個特性。它可以用來設(shè)置沙箱化進程的權(quán)限,限制它從用戶空間到內(nèi)核的系統(tǒng)調(diào)用。Kubernetes 可以自動將 Seccomp profile 加載到pod 和容器所在的節(jié)點。Kubernetes 提供兩種方式用于 pod 綁定 seccomp profile。
通過 annotation 標簽綁定 seccomp profile
用戶可以通過 pod 中的 annotation 標簽向 pod 中添加seccomp 安全配置,并且可以選擇對 pod 添加 seccomp 還是對 pod 中某個容器添加 seccomp 策略。
pod 層面:
annotations: seccomp.security.alpha.kubernetes.io/pod: "localhost/profile.json"
container 層面:
annotations: container.security.alpha.kubernetes.io/: "localhost/profile.json"
這里容器運行時會默認從節(jié)點上配置的 seccomp 策略文件目錄(k8s 集群上默認為/var/lib/kubelet/seccomp)中加載名稱為 profile.json 的配置文件,這里的配置 value 支持以下三種策略:
runtime/default-使用運行時默認的 seccomp 配置,比如docker 默認的 profile、containerd 的默認 profile
unconfined-不使用 seccomp 過濾
localhost/-使用節(jié)點本地 seccompprofileroot 路徑下自定義的配置文件
注意:從 Kubernetes v1.25 開始,kubelet 不再支持這些注解,也不再支持在靜態(tài) Pod 中使用注解,并且當創(chuàng)建帶有 seccomp 字段的 Pod 時不再自動填充 seccomp 注解。后續(xù)統(tǒng)一使用下面介紹的 securityContext 配置。
通過 security-context 配置 seccompprofile
社區(qū)從 1.19 版本 seccomp 特性 GA 開始在securityContext 配置中增加了 seccompProfile 的字段,用戶可以直接在此配置 Pod 和 Container 維度的 seccomp策略,由于 annotations 配置的方式已經(jīng)是廢棄狀態(tài),為了今后不必要的兼容性調(diào)整,推薦使用該方式配置:
securityContext: seccompProfile: type: Localhost localhostProfile: profiles/audit.json
有三種 seccomp 配置類型:
Unconfined:不啟用 seccomp
RuntimeDefault: kubelet 會啟用默認的 seccomp 配置(默認 seccomp 配置文件是有容器運行時定義的)
Localhost:節(jié)點本地seccomp 配置根目錄(一般默認為/var/lib/kubelet/seccomp)下配置文件的相對路徑
所以基于 k8s 提供的 seccomp 配置方式,我們可以實現(xiàn)對 pod 進行 syscall 級別的安全防護。
Seccomp 在云原生場景下的應(yīng)用方式
云原生場景下,業(yè)務(wù)一般是通過微服務(wù)的方式對外提供服務(wù),一般每個微服務(wù)的行為相比與主機業(yè)務(wù)行為會更為單一。因此當通過一系列的測試手段激發(fā)出服務(wù)所需的全部syscall 從而生成 syscall 白名單,通過 syscall 白名單限制服務(wù)系統(tǒng)調(diào)用,可以在 syscall 維度保證服務(wù)安全。當有攻擊通過服務(wù)漏洞進入到服務(wù)對應(yīng)的 Pod 中,它想要進行一些操作,但這些操作對應(yīng)的 syscall 不在白名單內(nèi),此時攻擊失敗。
我們將 syscall 白名單的生成與使用分為三個階段:學習階段,監(jiān)視階段,保護階段。
整個過程如圖所示:
學習階段:seccomp controller 組件為 crd 資源,它可以實現(xiàn)對 k8s 集群內(nèi)指定 pod 進行 syscall 采集并且將采集得到的 syscall 列表落盤到每個工作節(jié)點。seccomp controller 的 syscall 學習功能是通過 eBPF實現(xiàn)的,通過eBPF可以獲取工作節(jié)點每個進程產(chǎn)生的系統(tǒng)調(diào)用,進而獲取到指定 pod 對應(yīng)的系統(tǒng)調(diào)用。通過eBPF的方式,將集群中每個容器產(chǎn)生的 syscall 調(diào)用進行收集,生成 syscall 白名單。
監(jiān)視階段:使用 SCMP_ACT_LOG 過濾方式,可以將不在白名單的系統(tǒng)調(diào)用,以日志的形式打印出來,此時測試人員和安全運維人員可以對系統(tǒng)調(diào)用進行判斷,確定業(yè)務(wù)是否需要該 syscall,如果需要則加入到 syscall 白名單中。在監(jiān)視階段可以完成 syscall 白名單的收斂,進而得到與業(yè)務(wù)完全匹配的 syscall 白名單。
監(jiān)視模式創(chuàng)建的 seccomp 配置文件如下所示:(syscall列表只是舉例,實際 Pod 所需 syscall 列表會更多)
{ "defaultAction": "SCMP_ACT_LOG", "architectures": [ "SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32" ], "syscalls": [ { "names": [ "madvise", "epoll_ctl", "getsockname", "setsockopt", "vfork", "mmap", "read", "write", "close", "arch_prctl" ], "action": "SCMP_ACT_ALLOW" } ] }
保護階段:使用 SCMP_ACT_ERRNO 過濾方式,對每個業(yè)務(wù)容器進行 syscall 級別的保護。一旦業(yè)務(wù)容器中存在異常系統(tǒng)調(diào)用,對其進行攔截。
SCMP_ACT_ERRNO 對 syscall 攔截發(fā)生在內(nèi)核態(tài),所以不用擔心 seccomp profile 安全防護的效率問題。
保護模式創(chuàng)建的 seccomp 配置文件如下所示:
{ "defaultAction":"SCMP_ACT_ERRNO", "architectures": [ "SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32" ], "syscalls": [ { "names": [ "madvise", "epoll_ctl", "getsockname", "setsockopt", "vfork", "mmap", "read", "write", "close", "arch_prctl" ], "action":"SCMP_ACT_ALLOW" } ] }
總結(jié)
本文從 Seccomp 機制出發(fā),在 linux 內(nèi)核層面介紹了 Seccomp 可以實現(xiàn)的安全能力即對進程的系統(tǒng)調(diào)用限制能力。
Kubernetes 為我們提供了可以對容器進行系統(tǒng)調(diào)用層面保護的接口即 Seccomp 能力。在云原生場景,通過使用 eBPF獲取業(yè)務(wù)系統(tǒng)調(diào)用白名單,通過linux 內(nèi)核支持的 Seccomp 機制對業(yè)務(wù)容器進行系統(tǒng)調(diào)用維度的防護,進而保證業(yè)務(wù)容器 syscall 層面的安全。
一旦有攻擊者希望通過不在白名單內(nèi)的 syscall 實現(xiàn)攻擊行為,通過 Seccomp 機制我們可以對攻擊進行告警和攔截,最終保證業(yè)務(wù)容器的安全。
Seccomp 機制為云原生場景提供了 Syscall 維度的安全保證,后續(xù)將對此持續(xù)探索。
審核編輯:劉清
-
Act
+關(guān)注
關(guān)注
0文章
14瀏覽量
20957 -
LINUX內(nèi)核
+關(guān)注
關(guān)注
1文章
316瀏覽量
21608 -
BPF
+關(guān)注
關(guān)注
0文章
24瀏覽量
3968
原文標題:【云安全系列】Seccomp—云安全syscall防護利器
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論