- วิธีใช้งานแฟลก
--dangerously-skip-permissions ของ Claude Code อย่างปลอดภัย
- หลังจากพิจารณาสภาพแวดล้อมการรันแบบแยกส่วนหลายแบบ เช่น Docker, VM, Firejail แล้ว จึงสรุปว่า Virtual Machine (VM) ที่ใช้ Vagrant เหมาะสมที่สุด
- ใช้ Vagrant เพื่อคงไว้ทั้ง การแยกส่วนด้วย VM แบบสมบูรณ์, การตั้งค่าที่ทำซ้ำได้, และ การแชร์โฟลเดอร์ในเครื่อง พร้อมหลีกเลี่ยงปัญหา Docker-in-Docker
- ตั้งค่าให้ Claude Code จัดการระบบได้อย่างอิสระด้วยสิทธิ์ sudo ภายใน VM และนำไปใช้จริงกับการรันเว็บแอป, ตั้งค่า DB, ทำเทสต์อัตโนมัติ เป็นต้น
- วิธีนี้มีประสิทธิภาพในการ ป้องกันความเสียหายต่อไฟล์ซิสเต็มจากความผิดพลาด และหากจำเป็นก็สามารถลบแล้วสร้าง VM ใหม่เพื่อรีเซ็ตอย่างปลอดภัยได้
เบื้องหลัง
- ระหว่างใช้งาน Claude Code ผู้เขียนลองใช้แฟลก
--dangerously-skip-permissions เพื่อแก้ความไม่สะดวกที่ต้องคอยยืนยันคำขอสิทธิ์ทุกครั้ง
- แฟลกนี้จะ ดำเนินการทุกอย่างโดยอัตโนมัติโดยไม่ต้องขออนุมัติล่วงหน้า ไม่ว่าจะเป็นการติดตั้งแพ็กเกจ, เปลี่ยนการตั้งค่า, ลบไฟล์ ฯลฯ
- แม้จะมีประสิทธิภาพเพราะไม่ทำให้เวิร์กโฟลว์สะดุด แต่ก็มี ความเสี่ยงที่ไฟล์ซิสเต็มจะเสียหาย
- เพื่อป้องกันปัญหานี้ จึงมองว่าจำเป็นต้องรันใน สภาพแวดล้อมที่แยกออกจากบัญชีผู้ใช้ของโฮสต์ OS
วิธีที่พิจารณา
- เริ่มจากพิจารณาการแยกส่วนด้วย Docker ก่อน แต่เนื่องจาก Claude ต้องสร้าง Docker image และรันคอนเทนเนอร์เอง จึงจำเป็นต้องมีการตั้งค่า Docker-in-Docker
- ในกรณีนี้ต้องใช้โหมด
--privileged ทำให้ เป้าหมายของการทำ sandbox แทบไม่มีความหมาย
- อีกทั้งยังเพิ่ม ความซับซ้อนและความไม่เสถียร จากปัญหาอย่างเครือข่ายซ้อนชั้นและสิทธิ์ในการเมานต์ volume
- ยังพิจารณา ทางเลือกอื่น ๆ ดังนี้
- รันบน bare metal: มี กรณีเสียหายรุนแรง เช่น ลบฐานข้อมูลหรือโฮมไดเรกทอรี จากตัวอย่างใน Reddit
sandbox-runtime: เป็นการควบคุมการเข้าถึงแบบ ACL ทำให้ Claude เข้าถึงอย่างอื่นนอกเหนือจากโค้ดไม่ได้ แต่ ยังขาดอิสระอย่างสมบูรณ์
- Firejail: มีข้อจำกัดคล้าย Docker
- ตั้งค่า VM แบบแมนนวล: ขาดความสามารถในการทำซ้ำได้
- Cloud VM: มีปัญหาเรื่อง ค่าใช้จ่าย, ความหน่วง, และความจำเป็นต้องอัปโหลดโค้ด
แนวทางที่ใช้ Vagrant
- ใช้ Vagrant เพื่อให้ได้ทั้งการแยกส่วนด้วย VM แบบสมบูรณ์และการตั้งค่าที่ทำซ้ำได้
- เข้าถึงได้เหมือนทำงานในเครื่องผ่าน โฟลเดอร์ที่แชร์ร่วมกัน
- ไม่มีปัญหา Docker-in-Docker และหากจำเป็นก็สามารถลบแล้วสร้าง VM ใหม่ได้ง่าย
- ระหว่างใช้งาน VirtualBox เวอร์ชัน 7.2.4 พบ บั๊กที่ทำให้ CPU ถูกใช้งาน 100% และยืนยันสาเหตุผ่าน GitHub issue
- การตั้งค่า Vagrantfile สุดท้ายมีลักษณะดังนี้
- ใช้เบสอิมเมจ
bento/ubuntu-24.04
- จัดสรรหน่วยความจำ 4GB และ 2 CPU
- ติดตั้ง Docker, Node.js, npm, git, unzip
- ติดตั้ง
@anthropic-ai/claude-code แบบ global
- เพิ่มผู้ใช้
vagrant เข้าในกลุ่ม Docker
วิธีใช้งานจริง
- ในไดเรกทอรีโปรเจกต์ ให้รัน
vagrant up → vagrant ssh → claude --dangerously-skip-permissions ตามลำดับ
- ตอนบูตครั้งแรกจะใช้เวลาหลายนาทีในการ provision และสำหรับแต่ละโปรเจกต์จำเป็นต้องล็อกอิน Claude เพียงครั้งเดียว
- เมื่อทำงานเสร็จสามารถพัก VM ชั่วคราวได้ด้วย
vagrant suspend
- ภายใน VM Claude จะได้รับ สิทธิ์ sudo เพื่อทำงานอย่างเช่น
- รัน API ของเว็บแอปและตรวจสอบด้วย
curl
- ติดตั้งเบราว์เซอร์เพื่อตรวจแอปด้วยตนเองและสร้าง E2E test
- ตั้งค่า PostgreSQL DB และทดสอบ migration
- สร้างและรัน Docker image
- ด้วยสภาพแวดล้อมแบบนี้ Claude จึงสามารถ รันคำสั่ง, ตรวจสอบผลลัพธ์, และทำงานแบบวนซ้ำ ได้ด้วยตัวเอง
ประสิทธิภาพและความปลอดภัย
- บนสภาพแวดล้อม Linux + VirtualBox มี ทรัพยากรเหลือเฟือ และไม่มีความหน่วงในการซิงก์ไฟล์
- สิ่งที่ป้องกันได้
- ความเสียหายต่อไฟล์ซิสเต็ม จากความผิดพลาด
- การติดตั้งแพ็กเกจแบบไม่ยั้งคิด และ การเปลี่ยนการตั้งค่า
- สิ่งที่ป้องกันไม่ได้
- การลบโฟลเดอร์โปรเจกต์ (เพราะซิงก์สองทาง)
- การโจมตีโดยใช้ประโยชน์จาก ช่องโหว่หลุดออกจาก VM
- ปัญหาระดับเครือข่าย
- การรั่วไหลของข้อมูล (VM ยังเข้าถึงอินเทอร์เน็ตได้)
- การตั้งค่านี้มีไว้เพื่อ ป้องกันอุบัติเหตุ ไม่ใช่เพื่อ ป้องกันการโจมตีขั้นสูง
- เนื่องจากเป็นโปรเจกต์ที่ใช้ Git อยู่แล้ว จึงกู้คืนได้ง่ายเมื่อเกิดความเสียหาย และหากต้องการแยกส่วนให้เข้มงวดยิ่งขึ้นก็สามารถใช้การซิงก์ทางเดียวด้วย
rsync ได้
บทสรุป
- หลังแก้ปัญหาบั๊ก CPU ของ VirtualBox ก็ได้ สภาพแวดล้อมการรันที่ไร้แรงเสียดทาน
- สามารถรัน Claude Code ได้อย่างอิสระภายใน VM sandbox แบบสมบูรณ์
- หากมีปัญหาเกิดขึ้นก็เพียงลบ VM แล้วสร้างใหม่ โดย Vagrantfile เพียงไฟล์เดียวก็รับประกันความสามารถในการทำซ้ำได้
- หากจะใช้แฟลก
--dangerously-skip-permissions ก็ แนะนำอย่างยิ่ง ให้จัดสภาพแวดล้อมแบบแยกส่วนลักษณะนี้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
พอใช้ Claude ไปเรื่อย ๆ สุดท้ายก็จะลงเอยด้วย decision fatigue จนอีกไม่กี่เดือนให้หลังก็แค่กดเอนเทอร์ผ่านไปเฉย ๆ
เพราะงั้นผมเลยรู้สึกว่าการรันแบบ YOLO แต่เตรียม สภาพแวดล้อม sandbox ไว้ให้เรียบร้อยปลอดภัยกว่ามาก
บน Ubuntu 22.04 ผมจัด sandbox แบบหลายชั้นด้วยการใช้ bubblewrap ร่วมกับ Landlock LSM
Landlock จำกัดการเข้าถึง filesystem แบบ whitelist และควบคุมการเข้าถึงพอร์ต TCP ได้ด้วย
bubblewrap แยก mount namespace เพื่อสร้าง /tmp แยกตามโปรเจกต์และซ่อนคีย์ลับ
ตั้ง DNS whitelist ด้วย dnsmasq เพื่อให้ resolve ได้เฉพาะโดเมนที่จำเป็น
โครงสร้างแบบนี้ช่วยลด ความเครียด จากการที่ต้องคอยเฝ้าเอเจนต์ตลอดเวลา
การต้องมานั่งอนุมัติ elisp ที่ Claude เสนอทีละชิ้นเป็นประสบการณ์ที่ หมดแรง มาก
แค่ต้องคอยระวังไม่ให้มันติดตั้งอะไรแปลก ๆ ผ่านคำสั่ง Bash ก็เหนื่อยพอแล้ว
/sandboxผมคือ Srini จาก Docker
นักพัฒนาจำนวนมากใช้ Docker เพื่อแก้ปัญหานี้ และเราก็ได้รับฟีดแบ็กเกี่ยวกับข้อจำกัดของ Docker-in-Docker มาเยอะ
เพราะงั้นเราเลยเปิดตัว Docker Sandboxes แบบพรีวิวเชิงทดลอง
ตอนนี้ยังอยู่ช่วงเริ่มต้น แต่เรากำลังพัฒนาเวอร์ชันถัดไปบนพื้นฐาน MicroVM เพื่อหลีกเลี่ยงปัญหา Docker-in-Docker
อยากทราบว่า Claude สามารถสตาร์ตคอนเทนเนอร์อื่นภายใน Docker Sandbox แบบ ไม่มีสิทธิ์พิเศษ ได้หรือเปล่า
ดูเหมือนคนส่วนใหญ่พยายามหลีกเลี่ยงการรัน VM ในเครื่องเอง แต่ผมไม่เข้าใจว่าทำไม
จริง ๆ แล้ว VM ในเครื่อง นี่แหละง่ายที่สุดและแก้ปัญหาได้ครบ
ถ้าใช้ Docker บน Mac มันก็รันอยู่บน Linux VM อยู่แล้ว ดังนั้นมันต่างจากสภาพแวดล้อมจริงแค่ชั้นเดียว
จะ SSH เข้าไปตรง ๆ จาก IDE เพื่อตรวจโค้ดก็ได้
ผมเปิดใช้ตัวเลือก
--dangerously-skip-permissionsและจัดการทุกการเปลี่ยนแปลงผ่าน PRผมใช้แบบนี้คู่กับ workmux มาหลายเดือนแล้ว และมันมีประสิทธิภาพมากเพราะจัดการหลาย PR พร้อมกันได้
เหตุผลที่มันดีกว่า cloud VM คือถ้ารันหลายคอนเทนเนอร์พร้อมกันจะกินหน่วยความจำมาก
ถ้าต้องเปิด cloud VM สเปกสูงไว้ตลอด 24/7 ค่าใช้จ่าย จะสูงมาก
ต่อให้ AI ที่เป็นอันตรายไม่ใช้ช่องโหว่หลุดออกจาก VM มันก็ยังเพิ่มโค้ดตามอำเภอใจลงใน Vagrantfile เพื่อเอา สิทธิ์เข้าถึงโฮสต์ ได้
ต่อให้กังวลแค่เรื่องความผิดพลาดธรรมดา ถ้า Claude ไปแก้ commit hook พอมีการรันขึ้นมาก็เกิดปัญหาได้
เลยรู้สึกว่าการรักษาการแยกแบบสมบูรณ์พร้อมกับยังพัฒนาได้สะดวกนั้นยากมากจริง ๆ
ตัวอย่างเช่น ใช้ Docker volume mount ให้แก้ได้แค่โฟลเดอร์
sandbox/และตั้งไม่ให้เข้าถึง.gitผมใช้วิธีทำ snapshot, เปิด VM เล็ก ๆ มารันเอเจนต์ แล้วค่อยเทียบ snapshot อีกที
การซิงก์อัตโนมัติจะทำลายเป้าหมายเรื่องการแยกสภาพแวดล้อม จึงไม่ควรทำเด็ดขาด
ผมกำลังลองอีกแนวทางหนึ่ง — คือ ดักจับ สิ่งที่ Claude กำลังจะรัน
Shannot จะจับเจตนาก่อนรัน และดักจับ system call ใน PyPy sandbox
คำสั่งและการเขียนไฟล์จะถูกเก็บไว้แค่ใน log โดยยังไม่รันจริง
ผู้ใช้ต้องตรวจใน TUI แล้วอนุมัติก่อน ถึงจะรันจริง
ต่างจาก VM ตรงที่ VM ปล่อยให้รันได้อย่างอิสระในสภาพแวดล้อมแยกสมบูรณ์ ส่วน Shannot จะนำการเปลี่ยนแปลงไปใช้กับระบบจริงแบบ ต้องมีมนุษย์อนุมัติ
เหมาะกับงานอย่างการแก้ไขเซิร์ฟเวอร์
มี Claude MCP integration, การรันระยะไกลผ่าน SSH และความสามารถด้าน checkpoint/rollback ด้วย
สุดท้ายมันจะหยุดตั้งแต่คำขออนุมัติแรก ทำให้เอเจนต์สำรวจต่ออย่างอิสระไม่ได้
สิ่งที่ผมต้องการคือให้เอเจนต์ลองทำจนจบโดยไม่หยุดกลางทาง แล้วค่อยมาประเมินผลลัพธ์
แบบนั้นถึงจะประหยัดเวลาได้มาก
คล้ายกับโหมด system extension แบบ native บน mac ของ Leash แต่ยังไม่มี โหมดอนุมัติแบบโต้ตอบเต็มรูปแบบ
เป็นโปรเจกต์ที่น่าสนใจ
พอความล้าจากการอนุมัติสะสมมากขึ้น สุดท้ายก็อยากใช้
--dangerously-skip-permissionsเพราะงั้นผมเลยรัน Claude Code อยู่ใน devcontainer
จำกัดการเข้าถึงไฟล์ให้เฉพาะ repository และให้ใช้เครือข่ายได้เฉพาะแบบ whitelist
หลังจากนั้นก็ทำให้เป็นแบบทั่วไปด้วย docker compose และขั้นต่อไปคือจะเพิ่มการรองรับเอเจนต์อื่นอย่าง Codex หรือ OpenCode
เครือข่ายตั้งใจจะบังคับ route ผ่าน proxy บนโฮสต์เพื่อเพิ่ม การบันทึก log และการควบคุม
ตอนนี้กำลังใช้ iptables แก้ขัดไปก่อน
ยังอยู่ช่วงต้นแต่ทำงานได้ดีพอสมควร
โค้ด: agent-sandbox
ใช้ mitmproxy เป็น network proxy ตอนนี้ยังไม่สมบูรณ์แต่เกือบครบแล้ว
Claude ใช้เวลาหลายชั่วโมงตั้งค่าระบบเองและทำแอปจนเสร็จ
พวกเราไม่ได้เขียนโค้ดสักบรรทัดเดียว และผลลัพธ์ออกมาดีน่าทึ่งมาก
รู้สึกว่า ความเร็ว ของการพัฒนาด้วย AI น่าทึ่งจริง ๆ
วิธีแก้ของผมง่ายมาก
แบบนี้คำสั่ง npx จะถูกรันอย่างโปร่งใสภายใน Bubblewrap sandbox และเปิดให้เห็นแค่ไดเรกทอรีปัจจุบัน
ทำได้ด้วย POSIX shell ล้วน ๆ ไม่กี่บรรทัด
sandbox-run
และพอทิ้งสิทธิ์ลงไปแล้วก็เรียกกลับคืนมาไม่ได้ด้วย ซึ่งเป็นข้อเสียอีกอย่าง
ผมก็แค่โยนมันเข้า LXC container แบบ non-privileged แล้วจบ
threat model ของผมไม่ใช่การโจมตีซับซ้อน แต่เป็นสถานการณ์แบบ “เผลอลบ home directory ทิ้งทั้งก้อน” มากกว่า
ผมวางสคริปต์ยูทิลิตีไว้ในไดเรกทอรี
run/ของโปรเจกต์ แล้วสตาร์ตคอนเทนเนอร์แบบ compose-baseddevcontainer จะ map volume กับไดเรกทอรีบนโฮสต์
Claude จัดการได้ดีทั้งเรื่องตั้งค่าบริการ อัปเดตสคริปต์ และวิเคราะห์ปัญหารันไทม์
ยังไม่มีการเชื่อมกับเบราว์เซอร์ แต่คิดว่า Playwright หรือ Puppeteer น่าจะพอได้สบาย
อยากรู้ความเห็นเรื่อง sandboxing ในตัว ของ Claude Code
ลิงก์เอกสารทางการ
Claude Code มี escape hatch ที่ใช้ปิด sandbox ได้เมื่อจำเป็น
ถ้าคำสั่งล้มเหลวเพราะข้อจำกัดของ sandbox Claude จะวิเคราะห์สาเหตุแล้วลองใหม่ด้วย
dangerouslyDisableSandboxได้การที่เอเจนต์ปิด sandbox ได้เองดูเหมือนเป็น ช่องโหว่ เลยสงสัยว่ากรณีนี้มีขั้นตอนให้ผู้ใช้อานุมัติหรือไม่
issue ที่เกี่ยวข้อง: #14268, #13583, #10089