週末花了一點時間讀 NVIDIA 新公開的 OpenShell 是怎麼做到沙盒(Sandbox)的網路安全,因為 Anthropic 和 OpenAI 提供的 Managed Agent 也有相似的功能,但並不能看到原始程式碼,也就只能推測可能是利用哪些技術實作。
讓我比較意外的是,OpenShell 文件有提供對 AI 提問的功能,我在沒有讀原始程式碼的前提下,很快就驗證我的假設,也大概理解到目前是怎麼解決憑證(Credentials)的問題。
不透明憑證
大多數的 AI 應用都可能經過雲端,這表示 API Key 這類可以用於認證身分的資料都不能讓 Agent 可以碰觸到,即使是放在環境變數也都很危險,但是在 AI Native(AI 原生)的目標下,這是嚴重阻礙自主能力的問題,因此如何讓憑證變得「不透明(Opaque)」就很重要。
OpenShell 的處理方式並沒有讓我意外太多,關鍵的是處理的細緻程度,單純就不透明憑證的處理上,跟我在 Kobako 的處理方式類似,在沙盒內的環境我採取提供 Handle 機制類似,在內部看到的是某種「佔位符(Placeholder)」只有離開沙盒環境才會被轉換成原始的內容,因此 Agent 看到的頂多是 <apiKey:1> 這樣的字串,並不會知道原始內容。
轉換部分則統一由監督者(Supervisor)來處理,這是一個在沙盒外部執行的服務,所有的流量都會被轉到這個服務上處理,沙盒本身會被拔掉網路(容器(Container)關閉網路、虛擬機器(Virtual Machine)沒有網卡),再透過 Linux Kernel 的 seccomp 攔截 TCP 連線和 DNS 查詢,轉送到監督者服務上,避免漏接。
但這個技術也有限制,他只能針對 L7(Layer 7,應用層)做處理,也就是 HTTP 請求這類情境才能使用不透明憑證,如果想要對 L4(Layer 4,傳輸層)處理就會受限,這算是預期內的限制。
網路處理
既然我們都能夠攔截流量,為什麼只能對 L7 而不能針對 L4 處理,理由很單純,因為 L4 是 TCP 和 UDP 我們根本無從得知使用者使用了怎樣的標準溝通,要檢查過所有封包找出對應的佔位符做替換,這可能會嚴重拖慢速度以及有較高的錯誤率。
針對 L7 我們反而相對單純,只需要處理 HTTP 請求,大多數的憑證都存在於查詢、標頭等地方,我們只需要提供一個 HTTP Proxy 的服務就可以很快的替換掉,這也不難理解為什麼 Claude 和 ChatGPT 上的遠端呼叫允許,都是設定某個域名(Domain)來控制,基本上在這些沙盒內,唯一可行且能夠帶有憑證的,只有 HTTP 請求。
那麼 L4 本身就安全嗎?在 OpenShell 中還處理了許多經常遇到的安全問題,像是對區域網路發出連線。例如我想要逃出沙盒環境允許我連線的伺服器,因此我先對區域網路內所有 IP 範圍發出 ARP 請求,找到可以連線的裝置,接著只需要找到某個漏洞,就可以突破限制。
因此 OpenShell 預設會把對 10.x 192.168.x 這類屬於區域網路的請求封鎖,從一開始就無法發出,既然可以做到限制發出請求的位置,能夠設定 allowed_ips 的功能自然就成立,這就可以確保 Agent 在沙盒內只能對被允許的位置發出請求。
除此之外,針對 DNS 的攻擊防禦我認為是最巧妙的一點。假設 Agent 在網路上發現一個 https://hacker.com/api 端點想呼叫,但這個端點會偷偷換掉 DNS 解析的位置(DNS Rebinding 攻擊),那麼 Agent 可能就會錯誤的對區域網路,或者錯誤的伺服器位置發出請求,就會有風險。
既然區域網路用的 IP 範圍本身就不可用,那麼就善用這些範圍來加強防護,當 OpenShell 攔截到查詢時,會使用自己的 DNS 伺服器回應,並且記住自己解析的位置和一個私有位置,像是 blog.aotoki.me 解析為 172.67.195.165 的時候,回傳到沙盒的是 172.31.1.64 並且在監督者紀錄 sandbox:1,172.67.195.165,172.31.1.64 來當成對應(示意),當 Agent 想呼叫時對 172.31.1.64 發起的連線就會被攔截,並且由監督者轉接,那麼只需要保證監督者不受到這類攻擊的影響,就可以確保所有沙盒的網路安全。
這類處理非常細緻,但確實也是一般情境下很少會去仔細考慮的狀況,我認為蠻值得繼續花時間研究,而且官方文件可以直接跟 AI 討論。
Kobako 的計畫
會特地去了解 OpenShell 的機制,是因為目前正在開發 Kobako 的 Filesystem 能力,完成後就會進入到 Networking 功能的開發,在有 Filesystem 的基礎下加入網路功能並不困難,但真正困難的是 OpenShell 所設計的這些機制。
如果仔細去看 OpenShell 的防禦跟作法,會覺得相當的「厚重」需要 DNS、Proxy 伺服器的存在,我認為比較適合比較大規模的部署,而且還需要保證監督者這類專屬的服務存在,對於小型專案或者像我這種自有 Homelab 的玩家並不太划算。
Kobako 選擇的是另一條路線,一個盡可能輕量精簡的環境,也因此預設只能執行 mruby 也成為很大的限制,如果要用於執行 Coding Agent 這類情境,還是得回到依賴容器環境,但其他類型的任務需要簡單的記憶、API 呼叫能力時,這種輕量的條件意外是很有用的。
我認為「如何安全的執行 Agent」應該會是明年的主軸之一,這不單純是駕馭(Harness)問題,他已經被擴大到環境的問題,如果環境惡劣或者防護很差,最終還是會變得難以控制。
至於 Kobako 這類押注在 WebAssembly 技術的沙盒該扮演怎樣的角色,仍然很值得思考。
喜歡這篇文章?請我喝杯奶茶 🧋