範例

總覽

我們已透過幾個範例,說明如何在不同情境下使用 Sandbox2,以及如何編寫政策。

如需這些範例,請參閱 //sandboxed_api/sandbox2/examples,請參閱下方說明。

CRC4

CRC4 範例是一種刻意錯誤計算的 CRC4 總和檢查碼,示範如何將其他程式加入沙箱,以及如何與其通訊。

具體情況如下:

  1. 執行工具會使用 ::sandbox2::GetDataDependencyFilePath(),從檔案路徑啟動 Sandboxee。
  2. 執行工具會使用 SendBytes(),透過通訊管道 Comms 將輸入內容傳送給 Sandboxee。
  3. 沙箱會計算 CRC4,並透過通訊管道 Comms 接收其回覆 (透過 RecvUint32() 接收)。

如果程式發出通訊以外的任何系統呼叫 (read()write()),就會因違反政策而終止。

靜態

靜態範例示範如何沙箱靜態連結二進位檔 (例如不含來源的第三方二進位檔),也就是說,它不會採用沙箱機制。

  • static_bin.cc:沙箱是靜態 C 二進位檔,將 ASCII 文字從標準輸入轉換為大寫。
  • static_sandbox.cc:執行程式及其政策和限制,並為 Sandboxee 輸入使用檔案描述元。

具體情況如下:

  1. 執行程式使用 GetDataDependencyFilepath 從檔案路徑啟動 Sandboxee,就像 CRC4 一樣。
  2. 您可以設定限制、在 /proc/version 中開啟檔案描述元,並將其標示為 MapFd,以便在沙箱中對應。
  3. 這項政策允許部分系統呼叫 (open) 傳回錯誤 (ENOENT),而非因違反政策而遭終止。當我們為第三方程式進行沙箱時,以防我們無法修改系統呼叫了哪些系統呼叫,這時這個功能就能派上用場,反而能讓這些程式失敗。

工具

這項工具的用途是製定自身政策並試用 Sandbox2 API,以及示範相關功能。

  • sandbox2tool.cc:執行示範的執行程式:
    • 如何執行其他採用沙箱機制的二進位檔
    • 如何設定檔案系統檢查
    • 執行程式如何以非同步的方式執行 Sandboxee,以便逐步讀取其輸出內容。

你自己試試看:

Bazel

bazel run //sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname

CMake + Ninja

cd build-dir
ninja sandbox2_sandbox2tool && \
./sandbox2_sandbox2tool \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname

Google3 (Blaze)

blaze run //third_party/sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
 --sandbox2tool_resolve_and_add_libraries \
 --sandbox2tool_additional_bind_mounts /etc \
 /bin/cat /etc/hostname

旗標:

  • --sandbox2tool_resolve_and_add_libraries 用於解析及掛接 Sandboxee 的必要程式庫
  • --sandbox2tool_additional_bind_mounts <PATHS> 可讓沙箱提供給其他目錄
  • --sandbox2tool_keep_env:保留目前的環境變數
  • --sandbox2tool_redirect_fd1 用於接收 Sandboxee STDOUT_FILENO (1),並在本機輸出
  • --sandbox2tool_cpu_timeout:設定 CPU 逾時 (以秒為單位)
  • 如要設定實際逾時時間 (以秒為單位),請--sandbox2tool_walltime_timeout
  • --sandbox2tool_file_size_creation_limit:設定建立檔案的大小上限
  • --sandbox2tool_cwd:設定沙箱目前的工作目錄

custom_fork

custom_fork 範例示範如何建立沙箱,以便初始化二進位檔,然後等待來自父項執行工具的 fork() 要求。

相較於其他類型的沙箱,這個模式可望提升效能。在這裡,建立沙箱的新執行個體不需要執行新的二進位檔,而只是為現有的二進位檔建立分支

  • custom_fork_bin.cc:自訂 fork-伺服器,接收對 fork() 的要求 (透過 Client::WaitAndFork),以便產生新的沙箱使用者。
  • custom_fork_sandbox.cc:用來啟動自訂分支伺服器的執行程式。然後,它會透過新的執行工具傳送要求,以便產生 (透過 fork()) 新的沙箱。

聯播網

根據預設,已啟用網路命名空間,會防止沙箱程序連線至外部,本例示範如何處理這個問題。

連線會在執行程式中初始化,產生的通訊端則透過 ::sandbox2::Comms::SendFD() 傳遞。沙箱會使用 ::sandbox2::Comms::RecvFD() 接收通訊端,然後照常使用這個通訊端交換資料。

network_proxy

這個範例說明處理網路命名空間的替代方式。在內部,運作方式與上述範例完全相同,但以較方便的 API 公開。

沙箱可透過 2 種方式建立網路連線:

  • 自動:安裝自動處理常式,然後發出一般連線呼叫。
  • manual:取得 NetworkProxyClient 並直接使用 NetworkProxyClient::Connect

這個範例將示範這兩種方法。如果已設定 connect_with_handler 旗標,就會使用自動模式,否則會使用手動模式。