Chạy Claude Code an toàn trên server như thế nào
Claude Code có thể chạy mọi command mà user được phép chạy. Tìm hiểu skip permissions thay đổi gì và cách giới hạn rủi ro bằng sandbox, container hoặc VPS dùng một lần.
Chạy Claude Code an toàn trên server có nghĩa là gì
Để chạy Claude Code an toàn trên server, hãy bật các prompt yêu cầu cấp quyền, chạy Claude Code bằng một user riêng không có quyền đặc biệt, và tạo ranh giới thực sự cho các lần chạy không cần giám sát thay vì chỉ dựa vào mức độ tin cậy: dùng sandbox tích hợp sẵn, container hoặc một VPS có thể hủy, trên đó không lưu dữ liệu quan trọng. Flag --dangerously-skip-permissions loại bỏ bước phê duyệt giữa model và shell của bạn. Đánh đổi này có thể phù hợp với các tác vụ không cần giám sát, nhưng chỉ nên thực hiện bên trong một ranh giới giới hạn phạm vi mà một command sai có thể truy cập. Hướng dẫn này giải thích flag thực sự thay đổi điều gì và cách xây dựng ranh giới đó theo các mức cô lập tăng dần.
Claude Code có thể làm gì trên máy chủ của bạn
Claude Code là một coding agent chạy trong terminal. Nó đọc file, ghi file và chạy shell command với quyền của user khởi động nó. Đó là giá trị cốt lõi của công cụ này: nó có thể clone một repository, sửa code, chạy test, đọc lỗi rồi lặp lại quy trình để sửa code mà bạn không phải tự nhập từng command. Nếu bạn chưa thiết lập nó trên server, chạy Claude Code trên VPS bằng tmux hướng dẫn cách cài đặt và quản lý session. Trang này trình bày mức quyền bạn trao cho nó sau khi thiết lập.
Rủi ro nằm ngay trong câu trên nếu đọc lại lần nữa. Một process chạy shell command với quyền của user có thể làm mọi việc mà user đó có thể làm. Nó có thể đọc ~/.ssh/id_ed25519, ~/.aws/credentials và mọi file .env mà user của bạn có quyền mở. Nó có thể chạy curl và gửi dữ liệu đến bất kỳ host nào server có thể kết nối. Nó có thể chạy git push --force. Agent không có động cơ riêng. Nguy hiểm xảy ra khi task bị thực hiện sai, hoặc khi văn bản agent đọc trong lúc làm việc chứa instruction do người khác viết: một trang web mà nó đã fetch, hoặc một comment trong issue mà nó được yêu cầu sửa. Trường hợp thứ hai gọi là prompt injection. Vì vậy, việc “model thường xử lý hợp lý” không thể thay thế cho security plan. Instruction cũng có thể đến từ nguồn gần hơn, vì hai session Claude Code trên cùng một máy có thể gửi text cho nhau, và message từ session khác cũng chỉ là thêm text mà agent nhận được đọc. Hãy chuẩn bị cho lần chạy sai, không phải cho trường hợp trung bình.
Hệ thống phân quyền, nói đơn giản
Theo mặc định, Claude Code sẽ hỏi trước khi thực hiện thao tác. Việc đọc các file bên trong project diễn ra im lặng, nhưng khi chỉnh sửa file hoặc chạy shell command, Claude Code sẽ hiển thị chính xác nội dung chỉnh sửa hoặc command rồi chờ bạn xác nhận. Bạn có thể cho phép một thao tác, hoặc cho phép loại thao tác đó trong phần còn lại của session. Các phê duyệt này chỉ áp dụng trong session hiện tại: khi thoát CLI, session tiếp theo sẽ lại bắt đầu ở chế độ thận trọng. Với các rule muốn giữ lâu dài, file settings chứa các danh sách allow, ask và deny cố định. Ví dụ: cho phép git status, hỏi trước khi thực hiện git push, từ chối việc đọc .env. Rule deny luôn được ưu tiên. Mức mặc định này cũng sắp thay đổi vì auto mode sẽ trở thành mặc định vào ngày 14 August 2026. Vì vậy, bạn nên biết mỗi permission mode thực sự cho phép những gì trước khi quyết định server không có người theo dõi nên chạy ở mode nào.
Thiết kế này giả định có người theo dõi terminal, và điều đó đúng trên laptop. Trên server, thường không có ai theo dõi. Bạn khởi chạy một tác vụ dài bên trong tmux rồi đi ngủ. Nếu agent dừng lại để hỏi lúc 2 a.m., tác vụ sẽ không tiếp tục cho đến sáng. Việc tạm dừng làm mất cả thời gian lẫn chi phí, vì một session Claude Code không hoạt động sẽ mất prompt cache đang được giữ nóng và lượt tiếp theo phải trả chi phí để xây dựng lại cache đó. Đó là lý do thực tế khiến nhiều người dùng skip flag trên server, và vấn đề mà flag này giải quyết là có thật. Phần còn lại của hướng dẫn này trình bày cách giải quyết vấn đề đó mà không phải từ bỏ toàn bộ cơ chế bảo vệ.
Thay đổi của --dangerously-skip-permissions
claude --dangerously-skip-permissions tắt bước phê duyệt. Các thao tác chỉnh sửa được thực hiện mà không cần prompt. Các lệnh shell cũng chạy mà không cần prompt. Các kiểm tra đường dẫn được bảo vệ, vốn thường dùng để bảo vệ những vị trí nhạy cảm, cũng bị bỏ qua. Các quy tắc deny do bạn khai báo vẫn có hiệu lực, và một số thao tác đặc biệt nguy hiểm vẫn dừng lại để hỏi, nhưng tóm tắt cách hoạt động rất đơn giản: model quyết định chạy gì thì lệnh đó được chạy.
Có 2 điểm về flag này cần lưu ý trên server. Thứ nhất, flag bị chặn khi Claude Code chạy với tư cách root hoặc qua sudo trên Linux và macOS, vì root không có prompt có thể thay đổi mọi file hoặc service trên máy. Agent vốn cũng cần một tài khoản không có đặc quyền riêng, và flag này bắt buộc điều đó. Thứ hai, flag không thay đổi hành vi của model theo bất kỳ cách nào. Nó loại con người khỏi vòng kiểm soát và không thay đổi gì khác, nên mọi lỗi mà prompt trước đây có thể ngăn chặn giờ sẽ được thực thi.
Vì vậy, hãy nhìn nhận vấn đề một cách thực tế. Nếu bỏ qua quyền, câu hỏi bảo mật chuyển từ “agent có làm điều gì xấu không” sang “một thao tác sai có thể gây ra bao nhiêu thiệt hại”. Bạn không còn cố kiểm soát từng quyết định nữa, mà bắt đầu kiểm soát phạm vi ảnh hưởng. Câu trả lời là containment, với nhiều mức độ.
Sandbox tích hợp sẵn của Claude Code
Trước khi xem các mức, cần biết rằng Claude Code hiện có sandbox ở cấp OS cho các command mà nó chạy. Sandbox này loại bỏ phần lớn lý do khiến người dùng trước đây phải dùng skip flag. Trên Linux, sandbox dùng bubblewrap để cô lập filesystem và socat để định tuyến network traffic qua một proxy. Bên trong sandbox, command chỉ có thể ghi vào thư mục project và một thư mục temp của session. Command chỉ có thể truy cập network thông qua proxy, proxy này kiểm tra từng domain dựa trên allow list. Lần đầu một command cần truy cập domain mới, Claude Code sẽ hỏi bạn.
Bật sandbox bằng command /sandbox trong một session. Trên Ubuntu và Debian, trước tiên hãy cài 2 package cần thiết:
sudo apt install bubblewrap socatTrên Ubuntu 24.04 trở lên, policy AppArmor mặc định ngăn bubblewrap tạo user namespace cần thiết. Panel sandbox sẽ cho bạn biết khi thiếu thành phần nào. Tài liệu sandboxing của Claude Code có profile AppArmor ngắn để khắc phục vấn đề này.
Sandbox có chế độ auto-allow: các command chạy trong sandbox mà không cần prompt, vì boundary được áp dụng hiện đã thay phần việc mà prompt trước đây đảm nhiệm. Những command không thể chạy trong sandbox sẽ chuyển về luồng cấp quyền thông thường, nên các hành động thực sự bất thường vẫn cần bạn xác nhận. Với hầu hết workflow trên server, đây là lựa chọn thay thế đúng cho skip flag. Bạn sẽ gặp ít câu hỏi hơn nhiều mà vẫn có boundary được OS áp dụng, thay vì không có boundary nào.
Cần hiểu rõ các giới hạn của sandbox. Theo mặc định, command chạy trong sandbox vẫn có thể đọc phần lớn filesystem, bao gồm các file chứa credential, trừ khi bạn chặn những path đó. Setting sandbox.credentials tồn tại chính xác để xử lý việc này. Network proxy kiểm tra tên domain nhưng không tự kiểm tra traffic, vì vậy một allow rộng như github.com vẫn để lại khả năng đưa dữ liệu ra ngoài. Docker không chạy được bên trong sandbox. Sandbox nâng mức an toàn cơ bản lên đáng kể. Nhưng đây không phải boundary cô lập hoàn chỉnh, nên các mức bên dưới vẫn quan trọng.
Bậc thang cô lập
Có 3 bậc, theo thứ tự tăng dần về mức độ cô lập. Chọn bậc thấp nhất phù hợp với những gì khác đang chạy trên máy.
Bậc 1: một user không có quyền đặc biệt riêng. Agent có account riêng, thư mục home riêng, thư mục project riêng và không có quyền sudo:
sudo adduser --disabled-password --gecos "" agentRanh giới account ngăn agent truy cập các file của bạn: SSH key và mọi project khác trên máy. Nó cũng giúp sử dụng được skip flag, vì flag này không cho chạy dưới root. Đây là cùng nguyên tắc với chạy mọi service bằng user không có quyền đặc biệt, được áp dụng cho agent. Bậc 1 không cô lập được network và mọi dữ liệu trên máy có quyền đọc cho toàn hệ thống.
Bậc 2: một container. Anthropic cung cấp một devcontainer tham chiếu chạy Claude Code bằng user không phải root, kèm firewall rule giới hạn các host mà agent có thể truy cập. Container do bạn tự build cũng thực hiện được chức năng tương tự. Filesystem chỉ còn các volume bạn mount, còn lưu lượng outbound chỉ được phép theo rule của container. Đây là bậc trung gian phù hợp khi server đang chạy các service khác mà bạn cần bảo vệ. Giới hạn của cách này là các container dùng chung kernel của host, và chỉ một lần mount bất cẩn cũng có thể phá vỡ ranh giới; cấp cho container /var/run/docker.sock là nó có thể truy cập toàn bộ host.
Bậc 3: một VPS riêng. Đây là bậc mạnh nhất nhưng cũng trực diện nhất: cấp cho agent cả một máy không chứa bất kỳ dữ liệu nào bạn cần bảo vệ. Một VPS nhỏ có giá vài dollar mỗi tháng. Thiết lập máy theo runbook 10 phút đầu trên VPS mới, tạo snapshot của trạng thái sạch rồi để agent làm việc. Không có gì khác chạy trên đó. Không dùng SSH key cá nhân, chỉ dùng deploy key giới hạn trong một repository duy nhất. Không có cloud credential và không có dữ liệu production. Khi một lần chạy gặp sự cố, hoặc khi bạn chỉ muốn bắt đầu lại từ trạng thái sạch, hãy khôi phục snapshot hoặc hủy rồi dựng lại máy trong vài phút. Phạm vi ảnh hưởng chỉ giới hạn ở chi phí thuê máy. Với cách này, --dangerously-skip-permissions không còn đáng sợ, vì kết quả tệ nhất có thể xảy ra trong thực tế là phải dựng lại server và revoke một token.
Các bậc có thể kết hợp với nhau. Một agent chạy trong sandbox, bằng user không có quyền đặc biệt, trên một VPS có thể hủy bỏ, gần như không phát sinh thêm chi phí nhưng khiến các kịch bản sự cố trở nên rất đơn giản. Đó là mục tiêu.
Bảo vệ thông tin xác thực
Quy tắc quan trọng nhất: user của agent không được đọc các secret thuộc về thành phần khác.
Chỉ cấp API key cho agent, không cấp cho bất kỳ thành phần nào khác. Đặt key trong một file do user của agent sở hữu, với mode 600, rồi nạp file đó khi shell khởi động:
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/.bashrcTiếp theo, siết quyền theo hướng ngược lại. Trên Debian và Ubuntu, home directory thường được tạo với quyền cho mọi user trên máy đọc được, nên hãy siết quyền của bạn: chmod 750 /home/youruser. Kiểm tra bằng ls -ld /home/* và sửa mọi thứ mà account của agent có thể liệt kê.
Giới hạn phạm vi của từng token. GitHub token có quyền chi tiết và chỉ giới hạn trong một repository, hoặc deploy key riêng cho từng repository, sẽ khiến credential bị lộ chỉ ảnh hưởng đến một project thay vì toàn bộ account của bạn. Nếu dùng sandbox, hãy thêm các thiết lập credential của sandbox để ~/.ssh và ~/.aws bị từ chối ngay cả khi chỉ đọc. Đồng thời, không đặt credential production trên máy này, vì agent không thể làm lộ một secret chưa từng tồn tại ở đó. Nếu các secret đó nằm trong password manager tự host, hãy đặt password manager trên một máy khác với agent và review riêng password manager đó, vì các điểm yếu của Vaultwarden nằm ở admin token và file backup, không phải ở encrypted vault.
Git là lớp an toàn
Mọi thay đổi do agent thực hiện phải có thể review và revert. Git cung cấp cả hai việc này miễn phí nếu agent làm việc trên một branch:
git switch -c agent/refactor-authSau đó review lần chạy bằng git diff main...agent/refactor-auth, merge những thay đổi phù hợp và xóa branch nếu lần chạy không mang lại kết quả. Một lần chạy chỉ sửa ba file sẽ dễ đọc vào buổi sáng hơn nhiều so với lần chạy viết lại một nửa module. Đây là lý do thực tế để dùng một skill buộc agent chỉ thực hiện thay đổi nhỏ nhất nhưng vẫn hoạt động. Bảo vệ main branch ở phía forge để token của agent không thể push vào đó và không thể force-push ở bất kỳ đâu. Lịch sử commit đồng thời là audit log ghi lại những gì đã xảy ra trong lúc bạn ngủ. Giá trị của nó cao hơn mọi lượng nội dung terminal scrollback.
Mạng là một phần của phạm vi ảnh hưởng
Một agent có thể chạy curl. Câu này mô tả toàn bộ vấn đề egress: bất cứ thứ gì agent đọc được thì cũng có thể gửi đến nơi khác, và agent bị prompt injection có thể làm điều đó. User không có đặc quyền không giới hạn được việc này, vì bất kỳ user nào cũng có thể truy cập mọi nơi mà server truy cập được. Sandbox giới hạn phạm vi này theo domain thông qua proxy của nó. Container có thể giới hạn bằng các firewall rule riêng. VPS riêng giới hạn ngay từ đầu lượng dữ liệu có thể bị rò rỉ, nên đây là phương án chắc chắn nhất trong ba phương án.
Đừng cố giải quyết egress chỉ bằng ufw. ufw mặc định cho phép toàn bộ traffic đi ra, còn việc viết các rule outbound nhưng vẫn cho phép apt, npm, git và Claude API hoạt động là công việc phức tạp, dễ âm thầm bị lỗi. Thay vào đó, hãy chọn ranh giới ở cấp sandbox, container hoặc máy chủ, nơi domain allow list hoặc một máy chủ độc lập có thể giải quyết vấn đề này một cách rõ ràng.
Nếu bạn tự xây dựng agent dùng API thay vì chạy Claude Code, cách tiếp cận vẫn hoàn toàn giống nhau. Xây dựng AI agent với Claude trên VPS trình bày hướng này, và agent đó cũng cần một user riêng, các token có phạm vi giới hạn tương tự và một máy chủ riêng có thể hủy bỏ.
Trước hết, hãy harden máy chủ
Dù bạn chọn mức nào, bản thân máy chủ vẫn cần có các cấu hình cơ bản trước khi agent được cài đặt: chỉ cho phép SSH bằng key, không cho phép root login, firewall mặc định từ chối, và tự động cập nhật bảo mật. Tạo checklist tại đây rồi thực hiện lần lượt một lần:
FAQ
Có an toàn khi dùng --dangerously-skip-permissions trên server không?
Không, nếu chỉ bật flag này. Flag này tắt mọi prompt yêu cầu phê duyệt, nên lệnh nguy hiểm đầu tiên sẽ chạy ngay khi model tạo ra nó. Đây là một đánh đổi có thể chấp nhận khi giới hạn được phạm vi ảnh hưởng: tối thiểu phải dùng một user không có đặc quyền riêng; với tác vụ thực sự không cần giám sát, nên dùng container hoặc một VPS tạm thời chỉ chứa một project và một token có scope giới hạn. Không bao giờ dùng cách này trên máy chứa credential production hoặc dữ liệu mà bạn không thể mất.
Claude Code có sandbox không?
Có. Claude Code có sẵn sandbox cho shell command, mở bằng command /sandbox. Trên Linux, sandbox dùng bubblewrap; trên macOS, sandbox dùng Seatbelt. Sandbox giới hạn quyền ghi trong thư mục project và định tuyến network access qua một proxy chỉ cho phép các domain đã được phê duyệt. Chế độ auto-allow chạy các command trong sandbox mà không hiển thị prompt. Vì vậy, chế độ này giảm gián đoạn giống skip flag nhưng vẫn giữ được ranh giới do OS enforced. Đây không phải là ranh giới isolation hoàn chỉnh, nên hãy kết hợp với một user riêng hoặc một máy riêng khi chạy các tác vụ không cần giám sát.
Vì sao skip flag từ chối chạy khi là root?
Vì root không có prompt yêu cầu phê duyệt có thể sửa mọi file và mọi service trên system. Do đó, Claude Code chặn --dangerously-skip-permissions khi chạy dưới root hoặc qua sudo trên Linux và macOS. Cách xử lý không phải là tìm cách vượt qua kiểm tra này. Hãy tạo một user không có đặc quyền cho agent và chạy agent bằng user đó. Ranh giới giữa các account là lớp containment đầu tiên và rẻ nhất.
Claude Code có thể đọc SSH key và file .env của tôi không?
Claude Code có thể đọc mọi thứ mà user đang chạy nó có quyền đọc. Ngay cả policy mặc định của sandbox cũng cho phép đọc các đường dẫn credential cho đến khi bạn chặn chúng. Vì vậy, hãy chạy agent bằng user riêng, đặt mode của thư mục home của bạn là 750 hoặc chặt hơn, chặn các đường dẫn credential trong cấu hình sandbox và tuyệt đối không lưu secret production trên máy đó. Secret mà máy chưa từng lưu thì không thể bị đọc hoặc làm lộ.
Cách an toàn nhất để chạy Claude Code không cần giám sát là gì?
Dùng một VPS riêng giá rẻ chỉ dành cho công việc của agent: harden trong 10 phút, tạo snapshot sạch, chạy Claude Code dưới một user không có đặc quyền với sandbox được bật, lưu API key trong file mode-600, dùng deploy key riêng cho từng repository và thực hiện mọi thay đổi trên các branch mà bạn review trước khi merge. Nếu một lần chạy gặp lỗi, bạn chỉ cần revoke một token và khôi phục snapshot; các tài nguyên khác của bạn không bị ảnh hưởng.