「放進沙箱裡跑」聽起來像是一條指令。實際上,人們說這句話時指的是四種常見邊界之一,而它們攔住的東西大不相同。選錯了,要麼讓您暴露在風險中,要麼讓每次執行都比必要的更慢、更貴。
本文的比較假設程式碼確實不可信:由語言模型編寫、由使用者提交,或來自一個您不認識的人的 pull request。您自己寫的程式碼有不同的需求。
可能出什麼問題
在比較邊界之前,先說清楚它們是用來防什麼的。不可信程式碼可能會:
- 讀取不該讀的東西: 環境變數、SSH 金鑰、主目錄裡的檔案、雲元資料端點。
- 耗盡資源: 無限迴圈、不斷 fork 直到機器卡死、寫滿磁碟。
- 濫用網路: 掃描其他主機、傳送垃圾郵件、挖加密貨幣、呼叫您的內部服務。
- 持久駐留: 安裝一個比任務活得更久的 cron 任務或服務。
- 逃逸: 利用下層的漏洞在主機本身上執行程式碼。
下面每個級別都只能處理其中的一部分。
級別 1:程式
最簡單的沙箱是子程式:帶超時的 subprocess.run,也許以單獨的使用者執行,如果您足夠細緻,還會加上資源限制和 seccomp 過濾器。
能攔住: 失控的執行時間(超時)、部分資源耗盡(限制)、部分危險的系統呼叫(seccomp)。 攔不住: 讀取該使用者能讀的任何東西、網路存取、透過該使用者可寫的任何位置持久駐留,以及任何核心漏洞。 典型失效: 程式碼讀到了一個您忘了是可讀的檔案,或者某個「受限」的語言直譯器原來有後門。歷史上滿是沒守住的語言內沙箱。
啟動時間基本為零。對您自己寫的程式碼沒問題;對不是您寫的程式碼,這算不上邊界。
級別 2:容器
namespaces 讓程式碼擁有自己的檔案、程式和網路檢視;cgroups 限制 CPU 和記憶體;去掉的 capabilities 和 seccomp 縮小了它能向核心請求的範圍。
能攔住: 讀取主機檔案(除非被掛載進來)、看到其他程式、無限制地使用資源,以及在容器用完即丟時的大部分持久駐留問題。 攔不住: 共享的主機核心中的漏洞。機器上的每個容器都和同一個核心對話,所以一個可觸及的核心漏洞就是出口。 典型失效: 設定問題,而不是什麼奇特的漏洞利用。特權容器、把容器執行時的 socket 掛載進去、「只是為了除錯」而開啟主機網路。每一項都在悄悄拆掉邊界。
啟動時間是毫秒級。也有加固版本,包括在系統呼叫到達主機之前將其攔截的使用者態核心,代價是一定的速度和相容性。對於您信任的人寫的程式碼,設定良好的容器是合理的預設選擇。
級別 3:microVM
microVM 像完整虛擬機器一樣,在 hypervisor 下執行自己的核心,但幾乎去掉了所有模擬硬體。Firecracker 是最知名的例子。
能攔住: 容器能攔住的一切,再加上共享核心問題。要觸及主機,程式碼必須攻破 hypervisor 或少數幾個虛擬裝置之一,這個攻擊面比核心的系統呼叫介面小得多。 攔不住: 濫用您交給它的東西。開放的對外流量仍可能被濫用;您注入的金鑰仍可能洩露。 典型失效: 策略問題,而不是隔離問題。有人「為了讓測試跑通」傳進了正式環境的 token,或者給一個根本不需要對外流量的工作負載放開了對外限制。
啟動時間從零點幾秒到大約一秒,開銷幾 MB。這足夠快,可以為每個任務建立一個、用完即刪,這也順帶解決了持久駐留問題:沒有任何東西可供回來。
級別 4:完整虛擬機器
普通虛擬機器或 VPS 的邊界和 microVM 屬於同一類:硬體虛擬化加 hypervisor。區別在於它周圍的一切:完整的裝置模型、完整的作業系統、需要的話還有公用 IP,以及以天或月計的生命週期。
能攔住: 與 microVM 同類的問題,但由於模擬的硬體更多,攻擊面略大。 攔不住: 濫用它自身的網路身分。一台擁有公用 IP、執行著濫用程式碼的虛擬機器,會讓它自己的 IP 被列入黑名單;如果這個 IP 還負責傳送您的郵件,那就麻煩了。(如果已經發生了,請看 IP 被列入黑名單時該怎麼辦。) 典型失效: 活得太久。一台為某次實驗建立的虛擬機器,不斷積累憑據和狀態,慢慢變成了它本該保護的那台可信機器。
啟動時間從幾十秒到幾分鐘,計費通常按月。這對需要對內埠的長期執行服務是合適的形態,對一次 20 秒的程式碼執行則是錯誤的形態。
對比
| 程式 | 容器 | microVM | 完整虛擬機器 | |
|---|---|---|---|---|
| 獨立核心 | 否 | 否 | 是 | 是 |
| 主要邊界 | 使用者權限 | namespaces + 共享核心 | hypervisor、極小裝置模型 | hypervisor、完整裝置模型 |
| 啟動時間 | 約 0 | 毫秒 | 約 0.1–1 秒 | 10 秒 – 數分鐘 |
| 開銷 | 無 | 小 | 幾 MiB | 幾十到幾百 MiB |
| 每個任務用完即丟 | 容易 | 容易 | 容易 | 慢、成本高 |
| 對內埠 / 公用 IP | 主機的 | 主機的 | 通常沒有 | 有 |
如何選擇
- 您或您的團隊寫的程式碼: 程式或容器就夠了。
- 您自己分支的 CI: 在您的 runner 上用容器。
- 代理產生的程式碼、使用者提交、外部 pull request: 每個任務一個 microVM,用完刪除。
- 必須接受連線或執行數週的不可信服務: 一台擁有獨立 IP 的單獨虛擬機器,遠離任何儲存您憑據或傳送您郵件的東西。
無論選哪種,都要額外遵守兩條規則:不要往裡面放任何您不願交給程式碼作者的東西;有意識地決定網路可以做什麼。
我們的產品處於什麼位置
對於級別 3,我們提供程式碼沙箱:約一秒啟動的 Firecracker microVM,可存取對外網際網路,沒有對內埠,按秒計費。它們正是為上面第三條而設計的;MCP 安全防護頁面介紹瞭如何限制代理能用它們做什麼。對於級別 4,像 AI agent 方案這樣的 VPS 按月為您提供一整台機器。AI 代理沙箱中的完整範例端到端展示了 microVM 模式,AI 代理需要什麼樣的基礎設施則把隔離作為多項需求之一來討論。
評論
目前還沒有評論。歡迎成為第一位。