容器安全

gVisor簡介與實戰(zhàn)

gVisor的功能并不是來取代docker,而是像一個docker的低級運行時,它跟普通的container有點不同,你的app并不是真正的像一個主機的進程在運行,gVisor將應用程序加載到它自己的應用程序內存空間中并從那里運行,所以當你ps查看進程時,你不會看到有容器進程存在,你只能看到runsc進程。----Lan Lewis

gVisor是Google開源的有關容器安全的組件,是用Go語言編寫的用戶空間內核,它實現(xiàn)了大部分的Linux系統(tǒng)調用命令,包含一個叫了runsc的OCI運行時,目的是提供應用程序與主機內核之間的邊界隔離,runsc運行時已經(jīng)與Docker和Kubernetes做了集成,使運行沙箱容器sandbox變得很簡單。

與已有的sandbox技術相比,gVisor采用了一種特殊的方式,并且在技術上做了權衡,從而為容器安全領域提供了新的工具和創(chuàng)意。

為什么是gVisor?

容器不是sandbox,盡管容器已經(jīng)改變了我們開發(fā),打包,部署應用程序的方式,但是在沒有隔離的環(huán)境中運行不受信任的或者潛在的惡意代碼是有風險的。

gVisor是容器的用戶空間內核,它限制了應用程序直接訪問主機內核,同時能保持應用程序所期望的訪問結果。與大多數(shù)內核不同,gVisor不承擔或需要一組固定的物理資源,相反,它利用現(xiàn)有的主機內核功能并作為普通的用戶空間進程運行。換句話說,gVisor通過Linux實現(xiàn)Linux。

不應將gVisor與那些以加強容器抗外部威脅,提供額外的完整性檢查或限制服務訪問范圍的技術和工具混淆,我們應該時刻注意哪些數(shù)據(jù)可用于容器。

gVisor與其他容器隔離機制有何不同?

通常采用兩種其他方法提供比原始容器更強的隔離。

硬件虛擬化(如KVM和Xen),通過虛擬機監(jiān)視器(VMM)將虛擬化的硬件暴露給guest內核,這種虛擬化硬件通常是透明的(半虛擬化的),并且可以使用額外的機制來改善訪客和主機之間的可見性(例如氣球驅動器,準虛擬化螺旋鎖),在不同的虛擬機中運行容器可以提供很好的隔離性,兼容性和性能(盡管嵌套虛擬化可能會在此領域帶來挑戰(zhàn)),但對于容器,它通常需要額外的代理,并且可能需要占用更大的資源空間和更慢的啟動時間。

image

基于規(guī)則的執(zhí)行(如seccomp,SELinux和AppArmor)允許為應用程序或容器指定細粒度的安全策略,這些方案通常依靠主機內核中的鉤子來執(zhí)行規(guī)則,如果接口足夠?。炊x了足夠完整的策略),那么這是sandbox應用程序和保持本機性能的絕佳方式,然而,實際上,能任意為未知的應用程序可靠地定義策略是非常困難的,因此使得該方法難以應用。

image

gVisor提供了與上述不同的第三種隔離機制。

gVisor攔截應用程序系統(tǒng)調用,并充當訪客內核,無需通過虛擬化硬件進行翻譯,gVisor可能被認為是合并的客戶內核和VMM。這種架構允許它提供靈活的資源占用(即基于線程和內存映射的資源占用,而不是固定的客戶物理資源占用),同時降低虛擬化的固有成本。但是,這也降低了應用程序兼容性、增大了的系統(tǒng)調用開銷。

image

除此之外,gVisor使用基于規(guī)則的執(zhí)行來提供縱深防御(詳情如下)

gVisor的方法類似于用戶態(tài)Linux(UML),盡管UML在內部對硬件進行了虛擬化,因此提供了固定的資源占用空間。

上述方法中的每一種都有可能在不同的場景變現(xiàn)出優(yōu)越的性能,例如,硬件虛擬化會面臨實現(xiàn)高密度的挑戰(zhàn),而gVisor可能會在系統(tǒng)調用繁重的工作負載時表現(xiàn)出較差的性能。

gVisor是用Go編寫的,目的是為了避免可能困擾內核的安全缺陷。使用Go,有強類型,內置邊界檢查,沒有未初始化的變量,沒有免費使用,沒有堆棧溢出和內置競爭檢測器。 (Go的使用也有其挑戰(zhàn),而且不是免費的。)

gVisor攔截應用程序所發(fā)出的所有系統(tǒng)調用請求,為應用程序請求返回相應的結果,重要的是,gVisor并不是簡單地將應用程序的系統(tǒng)調用重定向到主機內核,相反,gVisor實現(xiàn)了大多數(shù)內核機制(信號,文件系統(tǒng),futexes,管道),并在這些機制之上構建了完整的系統(tǒng)調用處理程序。由于gVisor本身就是一個用戶空間應用程序,因此它會進行一些主機系統(tǒng)調用來支持其操作,但很像VMM,它不會允許應用程序直接控制它所做的系統(tǒng)調用。

文件系統(tǒng)訪問

為了提供縱深防御并限制主機系統(tǒng)調用接口,gVisor容器運行時通常分為兩個獨立的進程。首先,Sentry進程包含內核并負責執(zhí)行用戶代碼和處理系統(tǒng)調用。其次,擴展到沙箱之外的文件系統(tǒng)操作(不是內部proc或tmp文件,管道等)將通過9P連接發(fā)送到代理,稱為Gofer。

image

Gofer充當文件系統(tǒng)代理,代表應用程序打開主機文件,并將它們傳遞給Sentry進程,Sentry進程本身沒有主機文件訪問。此外,Sentry在一個空的用戶空間中運行,并且使用seccomp過濾器限制gVisor對主機進行的系統(tǒng)調用,以提供縱深防御。

網(wǎng)絡系統(tǒng)訪問

Sentry實現(xiàn)了自己的網(wǎng)絡堆棧(也用Go編寫),稱為netstack。網(wǎng)絡堆棧的所有方面都在Sentry內部處理 - 包括TCP連接狀態(tài),控制消息和數(shù)據(jù)包組裝 - 使其與主機網(wǎng)絡堆棧保持隔離。數(shù)據(jù)鏈路層數(shù)據(jù)包直接寫入由Docker或Kubernetes設置的網(wǎng)絡名稱空間內的虛擬設備。網(wǎng)絡直通模式也被支持,但其代價是減少了隔離(見下文)。

平臺

Sentry需要一個平臺來實現(xiàn)基本的上下文切換和內存映射功能?,F(xiàn)在,gVisor支持兩種平臺:

Ptrace平臺使用SYSEMU功能來執(zhí)行用戶代碼,而無需執(zhí)行主機系統(tǒng)調用。這個平臺可以在ptrace運行的任何地方運行(即使沒有嵌套虛擬化的虛擬機)。

KVM平臺(實驗)允許Sentry充當來賓操作系統(tǒng)和VMM,在兩個世界之間無縫切換。 KVM平臺可以在裸機上運行,??也可以在啟用了嵌套虛擬化的VM上運行。雖然沒有虛擬化硬件層 - 沙箱保留了一個流程模型 - gVisor利用現(xiàn)代處理器上提供的虛擬化擴展,以改善地址空間交換機的隔離和性能。

性能

影響性能的因素有這幾個方面,平臺選擇是是最直接的最大的影響,具體取決于具體的工作負載。沒有最好的平臺:Ptrace可以普遍使用,包括VM實例,但應用程序的執(zhí)行可能只是其原始級別的一小部分。除了平臺選擇之外,直通模式可能會有助于以某些隔離為代價來提高性能。

安裝

gVisor只能在x86_64 Linux 3.17+上運行。另外,gVisor僅支持沙箱內的x86_64二進制文件(不能運行32位二進制文??件)。

下載最新的build

下載runsc的鏈接:here

wget https://storage.googleapis.com/gvisor/releases/nightly/latest/runsc
chmod +x runsc
sudo mv runsc /usr/local/bin

配置docker使用runsc

在/etc/docker/daemon.json中參加配置如下,如果沒有這個文件則需要新建。

{
    "runtimes": {
        "runsc": {
            "path": "/usr/local/bin/runsc"
        }
    }
}

重啟docker

sudo systemctl restart docker

查看幫助文檔

root@hm-alone:~# runsc --help
Usage: runsc <flags> <subcommand> <subcommand args>

Subcommands:
    create           create a secure container
    delete           delete resources held by a container
    events           display container events such as OOM notifications, cpu, memory, and IO usage statistics
    exec             execute new process inside the container
    flags            describe all known top-level flags
    gofer            launch a gofer process that server files over 9P protocol (internal use only)
    help             describe subcommands and their syntax
    kill             sends a signal to the sandbox
    list             list contaners started by runsc with the given root
    ps               ps displays the processes running inside a container
    run              create and run a secure container
    start            start a secure container
    state            get the state of a sandbox

Subcommands for internal use only:
    boot             launch a sandbox process (internal use only)
    gofer            launch a gofer process that server files over 9P protocol (internal use only)


Use "runsc flags" for a list of top-level flags

創(chuàng)建container

root@hm-alone:~# docker run --runtime=runsc -it ubuntu /bin/bash
root@fbab7608cfb1:/#
root@hm-alone:~# ps aux | grep runsc
root      4561  0.0  0.1 240660 18440 pts/0    Sl+  05:17   0:00 docker run --runtime=runsc -it ubuntu /bin/bash
root      4723  0.0  0.0   7520  3064 ?        Sl   05:17   0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/fbab7608cfb18d3a2b82151ed9ea26355a3621a8736086a8ccee4213d2659356 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runsc
root      4855  0.0  0.0  19812  9128 ?        Sl   05:17   0:00 /usr/local/bin/runsc --log=/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/fbab7608cfb18d3a2b82151ed9ea26355a3621a8736086a8ccee4213d2659356/log.json --log-format=json --root=/var/run/docker/runtime-runsc/moby gofer --bundle /var/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/fbab7608cfb18d3a2b82151ed9ea26355a3621a8736086a8ccee4213d2659356 --io-fds=3 --io-fds=4 --io-fds=5 --io-fds=6
root      4861  1.4  0.1  58732 18372 pts/1    Ssl+ 05:17   0:00 /usr/local/bin/runsc --log=/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/fbab7608cfb18d3a2b82151ed9ea26355a3621a8736086a8ccee4213d2659356/log.json --log-format=json --root=/var/run/docker/runtime-runsc/moby boot --bundle /var/run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/fbab7608cfb18d3a2b82151ed9ea26355a3621a8736086a8ccee4213d2659356 --controller-fd=3 --console=true --io-fds=4 --io-fds=5 --io-fds=6 --io-fds=7
root      4876  0.0  0.0      4     4 pts/1    tl+  05:17   0:00 [runsc]
root      5344  0.0  0.0   5688   592 pts/1    tl+  05:17   0:00 [runsc]
root      5364  0.0  0.0      4     4 pts/1    tl+  05:17   0:00 [runsc]
root      5368  0.0  0.0      4     4 pts/1    tl+  05:17   0:00 [runsc]
root      5373  0.0  0.0      4     4 pts/1    tl+  05:17   0:00 [runsc]
root      8080  0.0  0.0  14512   936 pts/2    S+   05:18   0:00 grep --color=auto runsc

使用kubernetes

gVisor可以使用cri-o在Kubernetes集群中運行沙盒容器,但目前還不推薦用于生產(chǎn)環(huán)境。按照這些說明在Kubernetes集群中的節(jié)點上運行cri-o。構建runsc并將其放在節(jié)點上,并將其設置為/etc/crio/crio.conf中的runtime_untrusted_workload。沒有加io.kubernetes.crio.TrustedSandbox注釋(或注釋為false)的任何Pod將與runsc一起運行。目前,gVisor僅支持具有單個容器的Pod(不包括永久存在的暫停容器)。單個Pod中支持多個容器即將推出。

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

相關閱讀更多精彩內容

  • Docker白皮書 譯者:李毅 中國惠普大學資深培訓專家 摘要 最近幾年中軟件開發(fā)方式的演進已經(jīng)根本性地改變了應...
    Leo_Liyi閱讀 1,096評論 0 1
  • 容器安全解決方案需要考慮不同技術棧和容器生命周期的不同階段。 1.容器操作系統(tǒng)與多租戶 2.容器內容(使用可信源)...
    RiboseYim閱讀 721評論 0 1
  • 來源:Docker容器安全監(jiān)控系統(tǒng)設計與實現(xiàn)_簡智強 Docker安全是Docker團隊和廣大使用者都極為...
    peerless_1024閱讀 3,129評論 1 3
  • Docker容器的安全性 1.安全策略-Cgroup 1.限制Cpu docker run --rm -ti -c...
    yunpiao閱讀 1,347評論 0 0
  • 錢,是一個了不起的東西。歷史悠久且生生不息,好像沒有什么東西跟它沒關系,它就像一個癟三的情人,讓人煩,又招人喜歡。...
    奔跑的迷路人閱讀 435評論 0 1

友情鏈接更多精彩內容