張燕子
(西安郵電大學,陜西 西安 710121)
隨著高校數字化建設的不斷發展,為了節約硬件成本、加強網絡安全管控,虛擬化技術已經成為絕大多數高校數據中心的基礎配置。通過構建私有云管理平臺[1],可以將硬件基礎設施以IaaS(Infrastructureas a Service)的方式為全校各單位提供虛擬化計算和存儲資源[2]。然而,這種通過分配虛擬服務器共享硬件資源的方式存在著人工參與工作量大、部署速度慢、資源管理粒度過大等問題,尤其是虛擬服務器管理權限分配到用戶后,很難滿足操作系統安全管理、業務應用快速變更、資源彈性擴展等需求。
目前,高校數據中心的建設方向正在朝著云原生標準應用的架構發展。容器技術作為云原生應用中最重要的核心技術[3],相比傳統的虛擬機更加輕便快捷,采用容器技術的數字化底層計算環境,既能夠增強其系統整體的安全性,也能讓系統具有更佳的可擴展性和移植性,為以后系統功能的添加和數據庫的遷移打下良好的基礎。容器可以將數字校園內部系統模塊的環境變量和配置隱藏起來,也可以把運行在一個機器上眾多隔離的軟件聯系起來,目前在高校智慧校園建設中得到日益廣泛的應用,但容器本身設計上存在的安全問題也越發突出。本文提出通過對容器整體進行隔離的設計思路,使容器無法訪問主機內核和宿主機文件系統,從而解決容器本身組件存在安全漏洞的問題。
云原生(Cloud Native)是近年來高校數字化建設應用與研究的熱點。云原生的理念是直接按照云上部署的目標去設計應用與服務架構,不再按照傳統應用向云端遷移的設計思想。可以在云計算環境下構建與部署大量微服務應用,利用容器實現對各組件的打包集成,再對容器進行動態調度,從而實現云計算整體資源的優化配置。因此,云原生技術架構具有敏捷開發、性能可靠、高彈性、易擴展、故障隔離和持續更新等特性[4]。云原生計算基金會(Cloud Native Computing Foundation, CNCF)定義的云原生技術集合包括容器、微服務、服務網格、不可變基礎設施與聲明式API[5]。
容器技術是云原生的關鍵技術,本質上就是將多個軟件應用封裝在一個空間中并進行隔離,包括軟件的所有的配置信息、軟件的從屬關系、運行環境、運行時的工具及其附件。
在云運行的環境當中,每個微服務應用都需要搭建配置信息和購買服務器節點等費用,使用容器可以節省大量成本開支和不必要的工作量。容器之中運行的不是虛擬機,能夠具備比虛擬機更加良好的性能。在現實應用環境當中,容器和微服務的相互結合,可以構建便捷、可擴展和經濟花費較小的軟件工具。除了實現微服務的隔離之外,容器還可以為云原生的應用程序帶來更多的好處,使用容器,可以很便捷地將微服務程序的所需運行環境、配置信息、環境變量及其所屬關系移植到理想的服務器節點,而且無需重新去配置和部署環境,從而具備良好的可移植性。
容器運行時(Container Runtime)從傳統意義上來說就是代表容器從拉取鏡像到啟動運行再到中止的整個生命周期。在OCI(Open Container Initiative)標準中,對容器運行時提出了兩個規范,即運行時規范(OCI Runtime Spec)和鏡像規范(OCI Image Spec)[7]。這兩個規范允許不同開發者開發的容器能夠在異構runtime 上運行,從而保證了容器的可移植性和互操作性。
Docker公司與CoreOS和Google公司聯合創建了容器技術標準化組織OCI(Open Container Initiative)[6],對容器技術標準提出了業界標準定義 。 在這一標準下,工業界提出了一個創建并運行容器的命令行工具runC。這是一個輕量化工具,能夠屏蔽不同系統和版本的差異,使容器操作標準化,可以不用通過Docker引擎,直接運行容器。在Docker創建容器的過程中,runC的位置處于容器管理引擎的最底層,直接與操作系統 kernel 緊密協作,為容器提供運行環境。
Docker是輕量化的容器,具有輕量、高效和便攜的優勢[8]。其輕量性體現在可以通過對宿主機內核的訪問而省去不必要的流程,運行速度更快;其高效性體現在容器可以實現跨平臺的遷移,以及更加快速的部署和實現;其便攜性體現在創建和刪除容器更加便利,對于功能的更新只需遠程推送更新而不需要實地部署。
目前,將校園數據中心所部署的系統中各個功能和傳統的容器技術相結合,通過對教師、學生、后勤、科研等各個業務信息系統的設計與重新部署,在原有的基礎上,將各個功能實現的所有附屬信息全部以微服務的形式部署在云端的容器之中,對于整個業務來說其功能實現全部都在云上。云的大數據容量簡化了系統的擴容能力,也為以后系統功能的更新和擴展提供了更好的便捷性[9]。為每個業務功能設計其專屬容器,可能會出現功能過多導致的容器數量增多,這可以通過分級的方式進行簡化。相較傳統的虛擬機模式,在業務系統的可擴展性上有了很大提升,但其安全問題也不可忽視。
容器有權限之分,特權容器的權限最高,可以執行服務器的任何操作,擁有對客戶端資源的訪問權限。如果兩個容器之間為了實現各自目標而進行關聯,但是各自都有權限等級,就必須滿足最低的要求,只能選擇損失最小的一方進行交互[10]。這意味著,如果惡意程序掌握特權容器的規則,則它們可能會被破壞。如果幾個不同的容器之間相互進行攻擊,共用的內核被攻擊,則其他容器也會受到牽連。
出現這些問題的根本原因在于runC組件出現了問題。runC的主要任務是容器的啟停和資源隔離。因為runC在使用文件系統描述符時存在漏洞,會導致最高權限容器被抓取,造成容器的逃逸和越權訪問宿主機的文件系統。攻擊者可以通過惡意鏡像,或者改變容器運行時的配置信息來利用其漏洞。
針對runC組件有兩種主要攻擊方式:一種是攻擊者可能會將容器鏡像修改為惡意程序,runC被替換為此惡意程序,宿主機在執行容器命令的時候就會觸發惡意程序;另一種是攻擊者利用特權容器,將容器運行時的系統文件惡意修改,如果宿主機在該容器中創建新進程,會被攻擊者欺騙從而激活惡意程序,runC可以通過使用自定義帶有惡意程序的二進制文件去替換容器內新進程的二進制文件來達到索引的目地,將runC被替換為此惡意程序,從而執行容器運行命令導致觸發惡意程序[11]。
傳統的Docker容器設計如圖1所示,多個容器共享主機內核和硬件資源,對容器之間做了沙箱隔離,只是提升了容器本身的安全性,但容器之間和主機內核還是會因為runC的漏洞而對安全性構成威脅。

圖1 Docker容器結構
通過對容器本身安全的分析,對原來的容器的結構進行重新的規劃,改造后的安全容器結構圖如圖2所示,可以通過pod對容器統一管理。一個pod里可以有一個或多個容器,為每個容器創建專屬于它的獨立虛擬內核。該虛擬內核只負責用來運行容器,并不包含整個操作系統環境。在容器內部,其運轉方式并不像傳統的虛擬機,相當于一個容器內核,只是通過占用盡可能少的內存空間進一步降低內存的開銷。每個容器都在各自單獨的虛擬機中啟動,不會去訪問主機內核,從而杜絕了通過惡意代碼入侵其他鄰近容器的可能。通過對容器硬件的隔離,限制不受信任的租戶,使其運行的應用程序和之前刪除的應用程序都能被同一個集群安全隔離,不再有污染數據的可能性。

圖2 安全容器結構
本文介紹了校園數據中心中常用的Docker容器結構,分析在部署應用時由于容器組件存在漏洞所導致的安全問題,提出對容器整體添加隔離層的安全措施,對容器的內核和硬件基礎設施進行虛擬化,將很大程度上提升容器本身的隔離性能,從而阻斷發生容器逃逸和訪問宿主機文件系統的可能性。