如何在伺服器安全執行 Claude Code?
Claude Code 會以使用者身份執行 shell commands,若使用 skip permissions flag 則會跳過確認步驟。本文介紹如何透過 sandbox、container 或 disposable VPS 來限制執行範圍,防止錯誤指令造成系統損害。
在伺服器上安全執行 Claude Code 的意義
若要在伺服器上安全執行 Claude Code,請保持開啟權限提示、以專用的非特權使用者執行,並為自動化執行提供真正的邊界而非僅靠信任:使用內建的 sandbox、container,或是存放無關重要資料的 disposable VPS。--dangerously-skip-permissions flag 會移除模型與 shell 之間的確認步驟。對於自動化工作,這種權衡是合理的,但前提是必須在限制單一錯誤指令影響範圍的邊界內進行。本指南將說明該 flag 實際改變了什麼,以及如何透過層層遞進的隔離方式來建立該邊界。
Claude Code 在你的主機上可以做什麼
Claude Code 是在 terminal 中運行的 coding agent。它會以啟動者的使用者身份讀取檔案、寫入檔案並執行 shell commands。這正是該工具的核心價值:它可以自動完成 clone repository、編輯程式碼、執行測試、讀取錯誤並循環修復程式碼,而不需要你手動輸入每個指令。如果你尚未在伺服器上完成設定,在帶有 tmux 的 VPS 上執行 Claude Code 涵蓋了安裝與 session 處理。本頁面說明一旦設定完成後,你將賦予它多大的權限。
風險就在於「重複讀取相同的句子」。一個能以你的使用者身份執行 shell commands 的 process,可以執行該使用者能做的任何事情。它可以讀取 ~/.ssh/id_ed25519、~/.aws/credentials 以及該使用者可以開啟的每個 .env 檔案。它可以執行 curl 並將資料傳送到伺服器可連線的任何 host。它可以執行 git push --force。Agent 本身沒有動機,危險在於任務執行錯誤,或是它在工作時讀取的文字包含了他人寫下的指令:例如它抓取的網頁,或是要求它修復的 issue 中的註解。第二種情況稱為 prompt injection,這就是為什麼「模型通常很理性」並非安全計畫。你應該針對錯誤的執行進行規劃,而非針對平均狀況。
權限系統的白話說明
在預設情況下,Claude Code 在採取行動前會要求確認。在專案內讀取檔案是靜默完成的,但編輯檔案或執行 shell command 會先顯示確切的編輯內容或指令,並等待確認。你可以核准單一動作,或核准該類型的動作直到 session 結束。這些核准是以 session 為範圍的:關閉 CLI 後,下一個 session 會重新回到謹慎模式。對於需要保留的規則,設定檔會保存持久的 allow、ask 與 deny 清單。例如:允許 git status、針對 git push 進行詢問、拒絕讀取 .env。Deny 規則的優先權最高。
這種設計假設有人正在觀察 terminal,在筆記型電腦上確實如此。但在伺服器上,重點通常是沒人在看。你在 tmux 中啟動一個長時間任務後去睡覺,若 agent 在凌晨 2 點停下來詢問問題,在早上之前將無法取得進展。暫停不僅浪費時間,還會浪費金錢,因為 閒置的 Claude Code session 會失去其 warm prompt cache,下一次對話必須支付重新建立的成本。這就是為什麼人們在伺服器上傾向使用 skip flag 的誠實原因,而它解決的問題是真實存在的。本指南的其餘部分將探討如何在不放棄所有防護措施的情況下解決這個問題。
--dangerously-skip-permissions 改變了什麼
claude --dangerously-skip-permissions 會關閉確認步驟。編輯會直接進行,無需提示。Shell commands 會直接執行,無需提示。原本用於保護敏感位置的 protected-path 檢查也會被跳過。你明確設定的 deny 規則仍然有效,少數極端動作仍會停止詢問,但運作總結很簡單:模型決定要執行的任何指令,都會直接執行。
在伺服器上,關於此 flag 有兩個重點。首先,當 Claude Code 在 Linux 與 macOS 上以 root 或透過 sudo 執行時,該 flag 會被封鎖,因為沒有提示的 root 可以修改機器上的任何檔案或服務。Agent 本身就需要一個非特權帳號,而該 flag 強制執行了這一點。第二,該 flag 不會改變模型的行為。它只是移除了人為介入,除此之外別無變化,因此原本會被提示攔截的每個錯誤現在都會直接執行。
因此,這裡有一個誠實的計算方式。如果你跳過權限檢查,安全問題就從「agent 會不會做壞事」轉變為「一個錯誤的動作會造成多少損害」。你不再試圖控制每一個決定,而是開始控制 blast radius(爆炸半徑)。Containment(圍堵)是答案,且它分為多個層級。
內建的 Claude Code sandbox
在進入層級之前,請知悉 Claude Code 現在為其執行的指令提供 OS 層級的 sandbox,這解決了大部分人們尋求 skip flag 的原因。在 Linux 上,它使用 bubblewrap 進行檔案系統隔離,並使用 socat 將網路流量導向 proxy。在 sandbox 內,指令只能寫入專案目錄與 session temp 目錄,且只能透過會檢查所有 domain 是否在 allow list 中的 proxy 連線網路。當指令第一次嘗試連線新 domain 時,Claude Code 會詢問你。
在 session 中使用 /sandbox 指令即可開啟。在 Ubuntu 與 Debian 上,請先安裝所需的兩個套件:
sudo apt install bubblewrap socat在 Ubuntu 24.04 及更高版本中,預設的 AppArmor policy 會阻止 bubblewrap 建立所需的 user namespaces。sandbox panel 會告知你缺少了什麼,而 Claude Code sandboxing 文件中則提供了修復此問題的簡短 AppArmor profile。
Sandbox 具有 auto-allow 模式:sandboxed commands 會在無需任何提示的情況下執行,因為強化的邊界已經取代了原本提示的功能。無法在 sandbox 內執行的指令會退回到正常的權限流程,因此真正異常的動作仍會要求確認。對於大多數伺服器工作流程,這是 skip flag 的正確替代方案,因為你得到的是一個 OS 強化的邊界,而非完全沒有防護。
請誠實面對其限制。預設情況下,sandboxed command 仍可讀取大部分檔案系統(包括憑證檔案),除非你拒絕這些路徑;sandbox.credentials 設定正是為此而設。網路 proxy 檢查的是 domain name 而非檢查流量本身,因此像 github.com 這樣寬泛的允許仍留有外傳資料的空間。Docker 無法在其中執行。Sandbox 大幅提升了安全底線,但它並非完全的隔離邊界,這就是為什麼下方的層級仍然重要。
圍堵階梯 (The containment ladder)
三個層級,依隔離程度由低到高。請根據主機上運行的其他服務選擇最低層級的方案。
Rung 1: 專用的非特權使用者。 Agent 擁有自己的帳號、家目錄、專案目錄,且沒有 sudo 權限:
sudo adduser --disabled-password --gecos "" agent帳號邊界能將 Agent 與你的檔案隔離:包括你的 SSH keys 以及機器上的其他專案。這也讓 skip flag 變得可用,因為該 flag 會拒絕以 root 身份執行。這與 將每個服務都以非特權使用者執行 的原則相同,只是應用於 Agent。Rung 1 無法限制的部分包括:網路,以及機器上任何對全世界開放讀取的檔案。
Rung 2: Container。 Anthropic 發布了一個參考用的 devcontainer,以非 root 使用者執行 Claude Code,並透過 firewall rules 限制 Agent 可連線的 host;你自己建立的 container 也能達到同樣效果。檔案系統縮減至你掛載的 volumes,外連範圍縮減至 container 規則允許的範圍。當伺服器還託管你關心的其他服務時,這是正確的中間層級。其限制在於 containers 與 host 共用 kernel,一個疏忽的 mount 就會破壞邊界;若將 /var/run/docker.sock 交給 container,它就能觸及整個 host。
Rung 3: 專用的 VPS。 最強大的層級也是最直接的:給予 Agent 一台完全不存放任何你重要資料的機器。一台小型 VPS 每月僅需幾美元。使用 新 VPS 前十分鐘操作指南 進行設定,對乾淨的狀態進行 snapshot,然後讓 Agent 工作。那裡沒有其他東西,沒有個人 SSH key,只有針對單一 repository 的 deploy key。沒有雲端憑證,沒有生產環境資料。當執行出錯或你想要重置環境時,只需幾分鐘即可還原 snapshot 或銷毀並重建機器。你的風險成本僅為租金。在這種設定下,--dangerously-skip-permissions 不再令人恐懼,因為最壞的現實結果也不過是重啟伺服器與撤銷一個 token。
這些層級可以堆疊。一個在 disposable VPS 上以非特權使用者執行的 sandboxed agent,幾乎不會增加額外成本,並能讓失敗案例變得平庸。平庸才是目標。
保護憑證
這條規則決定了其他所有措施的成敗:Agent 的使用者絕對不能讀取屬於其他任何東西的 secrets。
僅將 API key 給予 Agent,不要給予其他人。將其放在屬於 Agent 使用者且權限為 600 的檔案中,並在 shell 啟動時載入:
install -m 600 /dev/null /home/agent/claude.env
echo 'export ANTHROPIC_API_KEY=your-key-here' >> /home/agent/claude.env
echo 'source ~/claude.env' >> /home/agent/.bashrc接著關閉其他方向的存取。在 Debian 與 Ubuntu 上,home directories 通常設定為所有使用者皆可讀取,因此請加強你自己的權限:chmod 750 /home/youruser。使用 ls -ld /home/* 進行檢查,並修正任何 Agent 帳號可以列出的項目。
限制每個 token 的範圍。一個僅限單一 repository 的精細化 GitHub token,或是一個針對單一 repository 的 deploy key,意味著憑證外洩時僅會損失一個專案,而非整個帳號。如果你使用 sandbox,請加入其憑證設定,使 ~/.ssh 與 ~/.aws 即使在讀取時也會被拒絕。並且請將生產環境憑證完全移出該主機,因為 Agent 無法外洩一個從未存在於該處的秘密。
Git 是安全網
Agent 做的每一次更動都應該是可審核且可還原的,如果 Agent 在 branch 上工作,git 可以免費提供這兩項功能:
git switch -c agent/refactor-auth執行完畢後使用 git diff main...agent/refactor-auth 進行審核,合併好的部分,若執行無果則刪除該 branch。在 forge 端保護 main branch,確保 Agent 的 token 無法 push 到該分支,也無法進行 force-push。Commit history 同時也是你睡覺時發生事件的稽核日誌,這比任何 terminal scrollback 都更有價值。
網路是爆炸半徑的一部分
Agent 可以執行 curl。這句話說明了外連問題的核心:Agent 能讀取什麼,它就能將其傳送到某處,而一個遭受 prompt injection 的 Agent 確實可能這麼做。單純的非特權使用者完全無法限制這一點,因為任何使用者都能連線到伺服器可連線的任何地方。Sandbox 透過 proxy 依據 domain 進行限制。Container 可以透過其自身的 firewall rules 進行限制。專用的 VPS 則從源頭限制了可外洩的內容,這是三者中最穩健的方案。
不要試圖僅靠 ufw 來解決外連問題。ufw 預設允許所有外向流量,而撰寫既能允許 apt、npm、git 又能允許 Claude API 的外向規則是非常繁瑣且容易出錯的工作。請改從 sandbox、container 或 machine 層級來選擇邊界,在那裡,一個 domain allow list 或一台純淨的機器能更乾淨地完成同樣的工作。
如果你是針對 API 開發自己的 Agent 而非執行 Claude Code,同樣的邏輯也適用。使用 Claude 在 VPS 上建立 AI Agent 涵蓋了該路徑,其 Agent 值得擁有同樣的專用使用者、同樣的 scoped tokens 以及同樣的 disposable box。
先強化主機
無論你選擇哪一個層級,在 Agent 入駐前,機器本身仍需完成基本設定:僅限 SSH keys、禁止 root login、預設拒絕的 firewall、自動安全性更新。在此生成你的檢查清單並執行一次:
FAQ
--dangerously-skip-permissions 在伺服器上安全嗎?
單獨使用並不安全。該 flag 移除了所有確認提示,因此模型產生的第一個錯誤指令會立即執行。當爆炸半徑受到控制時,這才是一個可以接受的權衡:至少需要一個專用的非特權使用者,對於真正的自動化工作,則需要一個僅存放單一專案與單一 scoped token 的 container 或 disposable VPS。絕對不要在存放生產環境憑證或無法承受損失的資料的主機上使用它。
Claude Code 有 sandbox 嗎?
有的。Claude Code 為 shell commands 內建了 sandbox,可透過 /sandbox 指令開啟。它在 Linux 上使用 bubblewrap,在 macOS 上使用 Seatbelt,將寫入限制在專案目錄,並透過僅允許核准 domain 的 proxy 導向網路存取。其 auto-allow 模式會在無需提示的情況下執行 sandboxed commands,這能像 skip flag 一樣減少干擾,同時保有 OS 強化的邊界。它並非完全的隔離邊界,因此在自動化執行時,請將它與專用使用者或專用機器搭配使用。
為什麼 skip flag 拒絕以 root 身份執行?
因為沒有權限提示的 root 可以修改系統上的任何檔案與服務,因此 Claude Code 在 Linux 與 macOS 上以 root 或透過 sudo 執行時會封鎖 --dangerously-skip-permissions。解決方法不是去對抗檢查,而是為 Agent 建立一個非特權使用者並在那裡執行;該帳號邊界是第一層且成本最低的圍堵手段。
Claude Code 可以讀取我的 SSH keys 與 .env 檔案嗎?
它可以讀取該執行使用者可以讀取的任何內容,甚至 sandbox 的預設政策在未設定拒絕前,也會允許讀取憑證路徑。因此,請以專用使用者身份執行 Agent,將你自己的 home directory 設定為 mode 750 或更嚴格,在 sandbox 設定中拒絕憑證路徑,並將生產環境秘密完全移出主機。主機從未擁有的秘密是無法被讀取或外洩的。
最安全的自動化執行方式是什麼?
使用一台僅用於 Agent 工作且廉價的專用 VPS:在十分鐘內完成強化設定、進行乾淨的 snapshot、在開啟 sandbox 的情況下以非特權使用者執行 Claude Code、使用 mode-600 檔案存放 API key、使用針對單一 repository 的 deploy key,並且所有工作都在你在 merge 前會審核的 branch 上進行。如果執行出錯,你只需撤銷一個 token 並還原 snapshot,你擁有的其他東西都不會受到影響。