沙箱
go-faas 如何在 Linux 與 macOS 隔離多語言使用者程式碼。
平台策略
| 平台 | 進入指令 | 隔離方式 |
|---|---|---|
| Linux | systemd-run + bwrap |
User slice 資源上限 + Bubblewrap namespace |
| darwin | sandbox-exec |
Seatbelt profile(偏開發) |
生產環境以 Linux 為主。macOS 支援讓 API 可在 Apple 主機開發。
Linux:systemd Slice
啟動時 sandbox.NewSlice() 寫入 ~/.config/systemd/user/go-faas-slice 並 reload user systemd:
| 設定 | 來源 | 預設 |
|---|---|---|
CPUQuota |
MAX_CPUS * 100 百分比 |
100%(1 核) |
MemoryMax |
MAX_MEMORY |
128M |
MemorySwapMax |
固定 | 0 |
每次執行使用 systemd-run --scope --user --quiet --slice=go-faas-slice -- bwrap ...。
Linux:Bubblewrap
SandboxCommand(linux build)組合的 bwrap 旗標包含:
- 唯讀綁定
/usr、/lib、/lib64 - 唯讀綁定語言 wrapper 至
/wrapper.{py,js,ts} --tmpfs /tmp、--proc、--dev--unshare-all、--unshare-net(無主機網路)--cap-drop ALL、--die-with-parent、--new-session- 清理
HOME/PATH/TMPDIR/LANG;取消LD_PRELOAD/LD_LIBRARY_PATH - TypeScript:額外 ro-bind 工作目錄,並設
NODE_PATH指向node_modules
Python 以 python3 -u /wrapper.py 執行;JS/TS 為 node|tsx /wrapper.*。
macOS:sandbox-exec
Darwin build 產生的 seatbelt profile:
- 預設 deny
- 允許 process exec/fork 與有限 sysctl/mach/signal/IPC
- 允許廣泛 file-read;寫入僅限
$HOME下 - 允許 network(較 Linux bwrap 寬鬆 — 開發取捨)
NewSlice() 在 darwin 為 no-op。
行程 I/O 合約
不論平台,子行程:
- 從 stdin 讀一筆 JSON payload:
code+input字串 - 在 stdout 寫出中間 log 與最終 JSON 結果
- 錯誤寫 stderr(SSE 路徑視 stderr 為致命)
Handler 以 context.WithTimeout 包住 exec.CommandContext 控管逾時。
相依檢查
Linux checker.CheckPackage() 在缺少 Node、TypeScript(tsc)、esbuild 或 Python 時,可能透過 apt/dnf/pacman/apk 安裝 bubblewrap、nodejs、npm、python3。Darwin checker 為 no-op。