關于多租戶容器間安全隔離的思考
顧名思義,多租戶就是很多人來租用容器平臺的資源來實現自己的應用托管運維需求。有了資源,那么誰來管理運維分配使用這些資源?多租戶很重要的一點是資源的安全隔離。即便是專用容器,也需要考慮相應的安全和業務隔離需求。
從多租戶的角度考慮,租戶租用容器云平臺的資源來托管、開發、部署運維自己的應用、服務。容器云平臺需要提供、維護保障租戶能正常使用這些資源,同時給租戶托管的應用提供服務注冊、服務發現、服務配置、日志、監控、預警告警、彈性伸縮、負載均衡、安全等能力。我們要明白的是租戶只是租用這些能力,他們并不負責維護。
那么誰來管理運維分配使用這些資源?那么容器云中什么是資源?資源該由誰來管理?如何分配?誰來運維這些資源?誰來使用這些資源?這也是我寫本篇文章的目的,本文包含了我對一般多租戶安全容器協調器的詳細安全考慮。我會通過具體示例來講解如何在隔離狀態下,安全的運行第三方代碼,詳細介紹請點此。
測試環境的配置
1.用于運行Docker鏡像的API,使每個進程完全與其他進程隔離;
2.濫用行為可以立即終止;
3.代理應該是可自動更新的,以便在出現安全問題時處理它們;
4.能夠將整個syscall接口用于正在運行的進程;
配置性能要求
1.禁止并刪除任何挖礦工具所使用的基礎設施及追蹤器;
2.防火墻可以關閉任何現有網絡端點;
3.防火墻可以將運行該進程的容器與它相關聯的所有本地鏈接和任何可訪問的內部IP隔離開來;
4.如果一層多租戶容器間安全隔離受到破壞,則另一層隔離需要馬上跟上。如果兩層安全隔離同時受到破壞,那么還會有隔離機制用于保護;
5.主機操作系統要是安全的;
測試過程
我們要求每個容器按照如下條件運行:
1.Block/io cgroups,以便磁盤沒有噪聲干擾。Cgroups是control groups的縮寫,是Linux內核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:cpu,memory,IO等等)的機制。最初由google的工程師提出,后來被整合進Linux內核。
2.CPU限制;
3.內存限制;
4.網絡或帶寬限制;
5.有一個與測試主機的其他網絡相隔離的網絡(bpf或iptables);
主機操作系統
主機操作系統應該是一個簡化的操作系統,具備最簡單的功能即可,即盡可能與容器內使用的操作系統共享許多功能。這是為了將主機環境中的運行漏洞降到很低。
這些操作系統的示例包括:
1.配備 CoreOS的 Container Linux ;
2. Container Optimized OS;
3.Intel Clear Linux, 英特爾推出Clear Linux項目的目標是讓用戶可以充分利用虛擬機的隔離技術以及容器的部署優勢;
4.LinuxKit, linuxkit這個工具可以理解為是用多個docker鏡像來組成一個最小化、定制化的操作系統,定制化后的系統只有幾十兆;
主機操作系統的特征
CoreOS Container Linux和Container Optimized OS都具有以下功能:
1.驗證啟動;
2.只讀或 usr:
2.1Container Optimized OS會將根文件系統(/)掛載為只讀,并將其某些部分重新掛載為可寫;
2.2/tmp, /run, /media, /mnt/disks 和 /var/lib/cloud都是使用tmpfs掛載的,雖然它們是可寫的,但它們的內容在重新啟動之后是不會保留的;
2.3目錄/mnt/stateful/partition, /var和/ home是從有狀態的磁盤分區掛載的,這意味著這些位置可用于存儲在重新引導后持續存在的數據。例如,Docker的工作目錄/ var / lib / docker在重新啟動時是有狀態的;
2.4在可寫位置中,只有/var/lib/docker和/var/lib/cloud被掛載為“可執行”,即沒有noexec掛載標志;
2.5CoreOS Container Linux的根文件系統(/)掛載為read_write,而/ usr是只讀的;
3.所有操作系統都允許無縫升級以解決安全問題;
容器運行
容器運行時應該是一個管理程序,以確保Linux容器的用戶配置不會降低集群的安全性。
如果要允許使用整個系統調用接口,Firecracker似乎是最合適的。Firecracker是一種專門用于創建和管理多租戶容器和基于函數的服務的虛擬化技術,使用Rust開發,旨在加快AWS Lambda和AWS Fargate等服務的速度和效率。
網絡要求
默認情況下,網絡應該被鎖定,拒絕所有入口和出口策略。這將創建一種安全形式,確保網絡環境的絕對安全。
這可以通過iptables或直接使用BPF來實現。
DNS
不允許任何inter-cluster DNS,在主節點和系統節點上沒有調度:確保集群中的主節點和系統節點不能被調度,這允許將系統進程的重點轉移到其他地方。
調度程序
調度程序不應該對bin文件進行打包,在許多使用臨時工作載荷的場景中,當前幾個節點耗盡而所有其他節點都沒有被使用時,會出現這種情況。因為工作載荷不斷地完成釋放前幾個節點上的資源(在批處理作業的情況下)。
Kube-batch目前是Kubernetes SIGs旗下的一個孵化項目,是一個運行在 Kubernetes 上面向機器學習 / 大數據 /HPC 的批調度器(batch scheduler),它支持以 Pod Group 為單位進行資源調度,并支持preempt和priority。對于暫時無法滿足資源條件的Pod,在Kubernetes中會處于pending狀態,直到資源釋放從而繼續執行。Kube-batch是基于IBM多年的HPC集群經驗構建的,它更適合批處理作業,因此如果我們打算長期應用此程序,就需要對其進行修改。
如果我們在裸機上運行,我們需要考慮電源管理、BIOS更新、硬件故障等等。
資源約束
使用cgroup管理資源并設置限制:
1.磁盤IO;
2.網絡帶寬;
3.內存;
4.CPU;
避免被挖礦
1.帶有eBPF的CPU跟蹤器會監控CPU使用率,因此如果它沒有波動,則它可能是一個挖礦工具;
2.二進制跟蹤器負責查找具有特定名稱的二進制文件或進程;
3.網絡跟蹤器負責尋找與已知挖礦工具端點相關的進程;
為什么不用kubernetes?
kubernetes,簡稱K8s,是用8代替8個字符“ubernete”而成的縮寫。是一個開源的,用于管理云平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單并且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。
由于我不希望任何允許任意代碼執行的容器只有一層安全保護,所以我認為kubernetes很難滿足這個要求。
Kubernetes的etcd集群之間沒有隔離,而且kubelet與apiserver的通信也不能被隔離。Etcd是Kubernetes集群中的一個十分重要的組件,用于保存集群所有的網絡配置和對象的狀態信息。
總而言之,Kubernetes太復雜了,有太多的第三方驅動程序。攻擊面太大,我們不需要其中的大部分(90%)功能設置。
默認情況下,Kubernetes將為每個節點安排最多110個pod。這是你可以修改的方面,但同樣重要的是要注意kubernetes中的默認調度程序是無法識別資源的,我們必須對其進行修復。具體的請參閱上面的“調度程序”那一節,由于默認調度程序的邏輯,集群中的前幾個節點會破壞。
甚至谷歌內部也不使用Kubernetes來調度虛擬機,Kubernetes在容器中插入了一些額外的env變量,我們也需要處理這些變量。
如果存在影響隔離的內核零日漏洞,我們該怎么辦?
首先,更新內核,但如果內核更新不了,我們可以使用ebpf捕獲易受攻擊的內核函數,并刪除任何試圖利用漏洞的容器。
假設我們已經有了可以持續構建內核和應用補丁的系統,則可以考慮威脅模型。大多數情況下,有人會攻擊我們的基礎架構,因此我們應該確保所有這些服務器在網絡上與其余堆棧隔離。
另外一個威脅是我們正在運行的用戶名和密碼在打開容器之后,黑客會通過VM截取它們。一般來說,容器運行錯誤時就會發生這種情況。