跳到主要內容

【2026 最新】Drop Claude Code 安全實戰:Rootless+gVisor 四關邊界驗收

最後更新: ·
Drop Claude Code 安全實戰首圖:Rootless namespace 與 gVisor syscall gate 四關邊界驗收

你把 Claude Code 放進 sandbox,看到終端前面多了一個 (drop),是不是就能放心讓它執行所有命令?真正的 Drop Claude Code 安全實戰不能停在「有開 sandbox」:你得親手確認它能改專案、不能碰專案外檔案、看不到主機密鑰,而且網路只開到你原本批准的範圍。

這篇專為第一次替 Coding Agent 加隔離層的 Linux 使用者寫。你不需要先懂 kernel;我們會固定 Drop 與 gVisor 版本,建立只有假資料的一次性 Lab,再用同一組四關分別跑 nativegvisor。本機環境不是 Linux、也沒有 Drop/runsc,因此以下是依官方文件與原始碼整理的可重跑驗收流程,不把預期結果寫成 AlphaLab 親測。

先說結論:Sandbox 不是開關,而是四張通行證

一句話記住:Agent 安全邊界=看得見的掛載+帶得進去的環境變數+連得出去的網路+接觸 host kernel 的方式。

  • native:Drop 用 user、mount、PID、IPC、cgroup 與 network namespaces 隔離,但 sandbox 內程式的 system call 最後仍由 host Linux kernel 處理。
  • gVisor:保留 Drop 同一份掛載與網路設定,再插入一個 userspace application kernel;它縮小直接接觸 host kernel system-call surface 的範圍。
  • 兩者都不是 microVM:gVisor 是 application kernel,不是硬體虛擬化;microVM 則另帶 guest kernel 與 hypervisor 邊界。
  • 四關全過的意義:只證明這個版本、這份設定、這組測試的檔案/機密/環境變數/網路邊界符合預期;它不是完整漏洞掃描。
Drop Claude Code 安全實戰官方示意:在隔離終端讀取主機 SSH 私鑰會找不到檔案
Drop 官方示意把核心體驗濃縮成一行:sandbox 內仍像普通 shell,但主機的 ~/.ssh/id_rsa 不在視野裡。圖片/Drop 官方。

Drop Claude Code 安全實戰:native 與 gVisor 差在哪?

把 native 想成「同一棟大樓裡,換了一套門禁與看不到其他房間的走廊」;gVisor 則在門禁後再放一位翻譯官。程式對 kernel 說的 system call,先由 gVisor Sentry 重新實作,再讓少量必要操作碰到 host。gVisor 官方安全模型也明確說明:映射進 sandbox 的檔案仍可依權限讀寫、網路仍可依政策連線;多一層 kernel 邊界不會收回你主動開的門。

Drop native 與 gVisor 架構圖:native 直接使用 host kernel,gVisor 增加 Sentry userspace kernel
兩條路使用同一份 Drop 設定;差別在 system call 是直接到 host kernel,還是先經過 gVisor Sentry。

這個角度也和站內的 Docker Sandboxes microVM 四道邊界不同:那篇檢查獨立 guest kernel 與 host bridge;本文檢查 Linux rootless namespaces,並用同一題 A/B 比較 gVisor。若你要先理解 Claude Code 自己的 permission mode 與 Bash Sandbox,先看 Claude Code Auto Mode 安全教學;外層 Drop 不會取代內層 deny/ask 規則。

開始前:只在 Linux 一次性環境做,先固定兩個版本

截至 2026 年 9 月 24 日,Drop 最新正式 release 是 v0.2.1,發布於 2026 年 8 月 24 日;官方 main branch 已經比它多出數十個 commit,所以不要把 latest 當成可重現版本。以下只下載 release artifact,並比對 GitHub API 公布的 SHA-256:

sudo apt-get update
sudo apt-get install -y passt curl zstd

ARCH=$(uname -m)
case "$ARCH" in
  x86_64) FILE=drop-linux-amd64; SHA=e7398467402f20402db7734b6bab99bd1756297df8c9edd4872d53f55122b790 ;;
  aarch64) FILE=drop-linux-arm64; SHA=11e5f99ae4c6b952bdd41b14252598d05e516f1359fb9c2ebfdd6b70d50e2632 ;;
  *) echo "unsupported architecture: $ARCH"; exit 1 ;;
esac

curl -fL -o "/tmp/$FILE" \
  "https://github.com/wrr/drop/releases/download/v0.2.1/$FILE"
printf '%s  %s\n' "$SHA" "/tmp/$FILE" | sha256sum -c -
install -m 755 "/tmp/$FILE" "$HOME/.local/bin/drop"
drop --version

checksum 必須顯示 OK,版本必須是 v0.2.1。Ubuntu 24 可能還需要官方文件列出的 AppArmor userns profile;Fedora 的 pasta 需要 SELinux policy。遇到 Permission denied 時,照 Drop 官方安裝頁處理,不要改成用 root 跑;Drop 原始碼會直接拒絕 effective UID 0。

gVisor 另外固定在 GitHub 於 2026 年 9 月 23 日 23:19 UTC 發布的 release-20260921.0。目前官方 tarball 除了 runsc,還包含同層的 gvisor-bin/ sidecars;只複製單一 runsc 已不是完整安裝。以下以 x86_64 為例,ARM64 把檔名改成 gvisor-aarch64.tar.zstd、SHA 改成 33c9a4022125ee45cbcd3c8ed431725ef9ca63bc379e38735f0b691172cd33b0

GV=release-20260921.0
GFILE=gvisor-x86_64.tar.zstd
GSHA=e3e7776afd36b08431c668a60f4271f9e9787ce0def960be680acb1681af3861

curl -fL -o "/tmp/$GFILE" \
  "https://github.com/google/gvisor/releases/download/$GV/$GFILE"
printf '%s  %s\n' "$GSHA" "/tmp/$GFILE" | sha256sum -c -
sudo tar --zstd -xf "/tmp/$GFILE" -C /usr/local/bin
runsc --version | tee "$HOME/runsc-version.txt"

gVisor 官方安裝文件偏好 Debian APT,因為未來多檔案升級比較穩;上面用 point release tarball,是為了讓這次 Lab 的 bytes 可核對。正式長期使用時,請選一種更新機制,不要讓 APT 與手動 tar 互相覆蓋。

建立一次性 Lab:repo 可寫、.git 唯讀、HOME 隔離

先建立完全沒有真實憑證、客戶碼或 production 設定的測試區。Drop init 預設把當前目錄掛成可讀寫,但把其中的 .git 改成唯讀;原本的 HOME 會被隔離,每個 Drop environment 另有持久化 HOME。

LAB=$(mktemp -d)
mkdir -p "$LAB/repo" "$LAB/outside"
printf 'outside-canary\n' > "$LAB/outside/host-only.txt"

cd "$LAB/repo"
git init
printf 'inside-canary\n' > README.md
git add README.md
git -c user.name=Lab -c user.email=lab@example.invalid commit -m init
drop init claude-lab

# 先看實際生成設定,再跑任何 Agent
sed -n '1,240p' "$HOME/.config/drop/claude-lab.toml"
sed -n '1,280p' "$HOME/.config/drop/base.toml"

檢查 mountsblocked_pathsenviron.exposed_varsnet.mode。尤其留意 ~/.gitconfig、shell rc、歷史檔與自訂 glob:唯讀只防修改,不會阻止讀取其中的 token。想完全不分享當前 repo,可重建成 drop init --no-cwd claude-lab,再只掛入需要的路徑。

接著在 Drop 裡安裝 Claude Code,讓 binary 與登入狀態落在 claude-lab 自己的 HOME,而不是主機 HOME。Anthropic 目前的 Claude Code 快速開始使用 native installer:

drop run -e claude-lab --runtime native bash

# 以下在 (drop) shell 內執行
curl -fsSL https://claude.ai/install.sh | bash
claude --version
exit

先不要立刻用 --dangerously-skip-permissions。外層 sandbox 限制「碰得到什麼」,Claude Code 的 permission mode 控制「哪些 tool call 直接批准」;兩層回答不同問題。想把這個概念擴成可觀測的 Agent 執行層,可接著讀 AI Agent Harness 是什麼AI Agent Harness 實作

Drop Claude Code 安全實戰四關:同一題跑 native 與 gVisor

先把 host 的假秘密放進環境,並在 host localhost 開一個只服務假檔案的測試 server。不要用真正的 SSH key 或 API key當 canary。

export DROP_TEST_SECRET='FAKE_ONLY_7f3a'
printf 'host-local-service\n' > "$LAB/outside/index.html"
python3 -m http.server 18765 --bind 127.0.0.1 \
  --directory "$LAB/outside" >"$LAB/http.log" 2>&1 &
HTTP_PID=$!
Drop Claude Code 安全實戰四關矩陣:越界寫檔、SSH 密鑰、秘密環境變數、localhost 與外網
四關看的是不同能力:掛載、HOME、環境變數、網路。任何一關失敗,都應先修設定,再啟動 Agent。

第一關:專案內可寫,專案外與 .git 不可寫

for RT in native gvisor; do
  echo "=== $RT / filesystem ==="
  drop run -e claude-lab --runtime "$RT" bash -lc '
    printf ok > boundary-inside.txt
    test "$(cat boundary-inside.txt)" = ok
    if printf bad > .git/escape-test 2>/dev/null; then exit 41; fi
    if printf bad > "'"$LAB"'/outside/escape-test" 2>/dev/null; then exit 42; fi
    echo PASS-filesystem
  '
done

通過標準不是「什麼都不能寫」,而是 boundary-inside.txt 真的出現在 repo,兩個越界寫入都失敗。若 repo 也不能寫,表示掛載太緊;若 .git 能寫,先停下來檢查 environment TOML,而不是把結果解釋成方便。

第二關:主機 ~/.ssh 不在 sandbox HOME

for RT in native gvisor; do
  drop run -e claude-lab --runtime "$RT" bash -lc '
    test ! -e "$HOME/.ssh"
    echo "PASS-ssh-hidden HOME=$HOME"
  '
done

如果這關失敗,最常見原因不是 kernel 逃逸,而是你在 mounts 主動暴露了路徑,或把整個 HOME 掛進去。先修配置。即使 SSH key 被隱藏,repo 內的 .env、測試 fixture 與 shell rc 仍要另行檢查。

第三關:未列入 allowlist 的秘密環境變數不會繼承

for RT in native gvisor; do
  drop run -e claude-lab --runtime "$RT" bash -lc '
    test -z "${DROP_TEST_SECRET:-}"
    echo PASS-env-hidden
  '
done

若假秘密出現,檢查 exposed_vars 是否有過寬的 glob。反過來,Claude Code 登入後存在 sandbox HOME 的憑證,Agent 本來就能代表該帳號發請求;「主機環境變數沒繼承」不等於外部帳號沒有權限。

第四關:localhost 預設拒絕,外網依 net.mode 決定

for RT in native gvisor; do
  echo "=== $RT / network ==="
  drop run -e claude-lab --runtime "$RT" bash -lc '
    if curl -fsS --max-time 3 http://127.0.0.1:18765/; then exit 44; fi
    curl -fsS --max-time 8 https://example.com/ >/dev/null
    echo PASS-isolated-network
  '

  drop run -e claude-lab --runtime "$RT" --net off bash -lc '
    if curl -fsS --max-time 3 https://example.com/; then exit 45; fi
    echo PASS-network-off
  '
done

isolated 的預期是外網可用、host localhost 不可用;off 則兩者都失敗。若開發 server 必須跨界,不要把整個 network namespace 拆掉;Drop 的 tcp_host_ports--tcp-host 可以只放行指定 host port。出站流量是否真的跨界、遠端是否接受,是另一條證據鏈,可搭配 AI Coding Agent 出站流量稽核

A/B 相容性與延遲:不要抄別人的倍數

gVisor 官方效能指南解釋,額外成本主要來自 Sentry 記憶體、system-call 攔截,以及檔案與網路子系統的實作差異;純 CPU 指令不會因為 gVisor 而被模擬。這不代表你的 npm install、測試或 dev server 一定慢多少。版本、kernel、檔案數量與 syscall 密度不同,百分比不能直接搬。

for RT in native gvisor; do
  echo "=== $RT ==="
  /usr/bin/time -f 'elapsed=%e sec maxrss=%M KB' \
    drop run -e claude-lab --runtime "$RT" bash -lc '
      node --version
      git status --short
      claude --version
      YOUR_REAL_TEST_COMMAND
    '
done

YOUR_REAL_TEST_COMMAND 換成專案真正的 lint、unit test 或 build,先跑一輪暖機,再各跑至少三次,保存版本與中位數。若 gVisor 只有某個步驟失敗,先把它標成 compatibility failure,保留錯誤訊息與最小重現;不要直接關掉整層。官方目前列出的 Drop 限制包括 terminal-only、有限 device、setuid 不可用,以及依賴巢狀 user namespace 的 Podman/Snap workflow 不受支援。

native、gVisor、microVM 怎麼選?

Drop native、Drop gVisor 與 microVM 決策比較圖:便利性、kernel 邊界、相容性與適用情境
選型不是「越重越安全」的單一路線;先看威脅模型,再看你是否需要標準 guest kernel、容器巢狀與硬體虛擬化邊界。
  • 選 Drop native:你主要防誤刪、越界讀寫與 localhost 誤連,信任 host kernel,並把低摩擦與相容性擺在前面。
  • 選 Drop gVisor:你會執行未知套件或 Agent 生成的 binary,希望減少 workload 直接接觸 host kernel 的攻擊面,也能接受先做 compatibility gate。
  • 選 microVM:你的威脅模型包含刻意惡意 workload、多租戶、需要獨立標準 guest kernel,或必須在隔離環境裡再跑容器。站內 Agent Substrate 教學則適合要處理大量 Agent 休眠、排程與 sandbox 密度的人。

microVM 也不是自帶完整政策。以 Firecracker 官方 production 文件為例,網路過濾、Jailer、cgroup、patch 與資源限制仍由 operator 配置;換句話說,hypervisor boundary 很重要,但掛載、網路與 credential 通道照樣要驗收。

停手規則與清理程序

  1. 四關任何一關意外成功:不要啟動 Claude Code;先保存版本、TOML 與輸出,再縮小 mount/env/port。
  2. native 與 gVisor 結果不同:先分辨是預期的 compatibility difference,還是同一份配置產生了不同權限結果;後者要當阻擋項。
  3. 測試需要真實 secret:停。Lab 只用 fake canary;真正帳號另做最小權限與撤銷設計。
  4. Agent 要碰 production、發訊息或 merge:外層 sandbox 不能消除外部副作用,保留人工批准與可撤銷 credential。
# 回到 host shell
kill "$HTTP_PID" 2>/dev/null || true
drop rm claude-lab

# 先確認只指向這次 mktemp 建立的 Lab,再人工刪除
printf 'review cleanup target: %s\n' "$LAB"
find "$LAB" -maxdepth 3 -print

drop rm claude-lab 會移除該 environment 的持久 HOME;它不會替你刪掉主機上的 repo 與外部 Lab 目錄。保留四關輸出、drop --versionrunsc --version 與 TOML 作為收據,再由你確認 $LAB 是本次一次性路徑後清理。

常見問題 FAQ

1. Drop 可以在 macOS 或原生 Windows 跑嗎?

目前這份 Drop 流程不行。它依賴 Linux user/mount/PID/network 等 namespaces;macOS 請改用適合該平台的 sandbox 或 microVM,Windows 則先判斷是否要在 WSL2 裡做獨立 Linux Lab。

2. gVisor 等於一台 VM 嗎?

不等於。gVisor 是 userspace application kernel;它攔截並實作 Linux-like system-call interface,但不是帶 guest kernel 的硬體虛擬機。

3. 四關都 PASS,就能執行惡意程式嗎?

不能這樣推論。四關是設定驗收,不是對未知漏洞、side channel、DoS 或 kernel/runtime escape 的完整證明。刻意惡意、多租戶或高價值 secret 的場景,應提高到獨立 VM/microVM 與更完整的監控、資源與 credential policy。

4. 為什麼 repo 可以寫,.git 卻應該唯讀?

讓 Agent 能工作,又不直接改寫歷史控制面。它仍能改 working tree;你在 host review diff 後再 commit。這不是備份,重要 repo 仍要有 remote 或 snapshot。

5. net.mode=off 時 Claude Code 還能用嗎?

正常互動通常無法完成。Claude Code 需要網路連到模型服務;off 適合純本機測試與驗收。實際使用多半要 isolated,再用 proxy、外部 firewall 或專用環境收斂出站。

6. 可以把 ~/.ssh 唯讀掛進去嗎?

技術上 mount 可以唯讀,但秘密仍會被讀到。若只是 Git 操作,優先使用用途受限、可撤銷的 credential 通道;不要把「不可修改」誤認成「不可外洩」。

7. gVisor 比 native 慢多少?

沒有一個可套用所有專案的倍數。syscall、檔案與網路密集工作通常更敏感;純 CPU 工作受影響較小。用你自己的 lint/test/build 做同版本 A/B,保存中位數與錯誤。

8. 可以直接讓 Claude Code bypass permissions 嗎?

先不要。先讓四關、diff review、備份與外部帳號權限各自通過,再決定哪些任務能提高自動化。Sandbox 限制主機能力,不會阻止 Agent 用已授權帳號做不可逆的外部動作。

給新手的 6 個重點

  1. 先固定 Drop、runsc、kernel 與 TOML,再談結果。
  2. native 與 gVisor 用同一組四關,才能比較 runtime 而不是比較設定。
  3. repo 可寫是工作需求;專案外、.git、主機 HOME 與未授權 localhost 必須分開驗。
  4. 秘密環境變數沒繼承,不代表 sandbox 內登入的帳號沒有外部權限。
  5. 效能只量自己的真實 command,不抄不同版本的 benchmark 倍數。
  6. 看到任何意外放行就停手;先縮小能力,再啟動 Agent。

接著閱讀

左右滑動查看更多推薦

結語:先跑四關,再把 Claude Code 放進去

Drop 最有價值的地方,不是替「安全」打勾,而是把掛載、HOME、環境變數與網路變成你能看、能改、能重跑的設定。今天先建立 fake-only Lab,讓 native 與 gVisor 都跑完四關;明天換 kernel、Drop、runsc 或 TOML,就重跑一次。當你能用收據回答「Agent 到底碰得到什麼」,才考慮提高自主權。想把這套方法延伸到自己的 Agent 專案,可從 AlphaLab 的 AI 實戰課程開始,將隔離、評測與可復原流程一起設計。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。