ภาพรวม
เราได้เตรียมตัวอย่าง 2-3 ตัวอย่างเพื่อแสดงวิธีใช้ Sandbox2 ในสถานการณ์ต่างๆ และวิธีเขียนนโยบาย
คุณดูตัวอย่างได้ที่ //sandboxed_api/sandbox2/examples และดูคำอธิบายโดยละเอียดได้ที่ด้านล่าง
CRC4
ตัวอย่าง CRC4 เป็นการคำนวณผลรวมตรวจสอบ CRC4 ที่มีข้อบกพร่องโดยจงใจ ซึ่งแสดงให้เห็นวิธีแซนด์บ็อกซ์โปรแกรมอื่นและวิธีสื่อสารกับโปรแกรมนั้น
- crc4bin.cc: โปรแกรมที่เราต้องการแซนด์บ็อกซ์ (เช่น Sandboxee)
- crc4sandbox.cc: โปรแกรมแซนด์บ็อกซ์ที่จะเรียกใช้โปรแกรมดังกล่าว (เช่น Executor)
วิธีการทำงาน
- Executor จะเริ่ม Sandboxee จากเส้นทางไฟล์โดยใช้
::sandbox2::GetDataDependencyFilePath() - Executor จะส่งอินพุตไปยัง Sandboxee ผ่านช่องทางการสื่อสาร
Commsโดยใช้SendBytes() - Sandboxee จะคำนวณ CRC4 และส่งคำตอบกลับไปยัง Executor ผ่านช่องทางการสื่อสาร
Commsซึ่งจะรับคำตอบด้วยRecvUint32()
หากโปรแกรมเรียกใช้ระบบ (Syscall) อื่นนอกเหนือจากการสื่อสาร (read() และ write()) ระบบจะหยุดโปรแกรมเนื่องจากการละเมิดนโยบาย
คงที่
ตัวอย่างคงที่แสดงวิธีแซนด์บ็อกซ์ไบนารีที่ลิงก์แบบคงที่ เช่น ไบนารีของบุคคลที่สามที่คุณไม่มีซอร์สโค้ด ซึ่งหมายความว่าไบนารีนั้นไม่ทราบว่าจะมีการแซนด์บ็อกซ์
- static_bin.cc: Sandboxee เป็นไบนารี C แบบคงที่ซึ่งแปลงข้อความ ASCII จากอินพุตมาตรฐานเป็นตัวพิมพ์ใหญ่
- static_sandbox.cc: Executor ที่มีนโยบาย ข้อจำกัด และการใช้ตัวบอกไฟล์สำหรับอินพุต Sandboxee
วิธีการทำงาน
- Executor จะเริ่ม Sandboxee จากเส้นทางไฟล์โดยใช้
GetDataDependencyFilepathเช่นเดียวกับ CRC4 - Executor จะตั้งค่าขีดจำกัด เปิดตัวบอกไฟล์ใน
/proc/versionและทำเครื่องหมายให้แมปใน Sandboxee ด้วยMapFd - นโยบายอนุญาตให้ Syscall บางรายการ (
open) แสดงข้อผิดพลาด (ENOENT) แทนที่จะหยุดเนื่องจากการละเมิดนโยบาย ซึ่งอาจมีประโยชน์เมื่อแซนด์บ็อกซ์โปรแกรมของบุคคลที่สามที่เราไม่สามารถแก้ไข Syscall ที่เรียกใช้ได้ ดังนั้นเราจึงทำให้ Syscall เหล่านั้นล้มเหลวอย่างราบรื่นแทน
เครื่องมือ
ตัวอย่างเครื่องมือเป็นทั้งเครื่องมือในการพัฒนานโยบายของคุณเองและทดลองใช้ Sandbox2 API รวมถึงการสาธิตฟีเจอร์ต่างๆ
- sandbox2tool.cc: Executor ที่แสดงให้เห็น:
- วิธีเรียกใช้ไบนารีอื่นที่แซนด์บ็อกซ์
- วิธีตั้งค่าการตรวจสอบระบบไฟล์ และ
- วิธีที่ Executor สามารถเรียกใช้ Sandboxee แบบไม่พร้อมกันเพื่ออ่านเอาต์พุตของ Sandboxee อย่างต่อเนื่อง
ลองทำด้วยตัวเอง
Bazel
bazel run //sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostnameCMake + Ninja
cd build-dir
ninja sandbox2_sandbox2tool && \
./sandbox2_sandbox2tool \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostnameGoogle3 (Blaze)
blaze run //third_party/sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostnameข้อควรพิจารณา:
--sandbox2tool_resolve_and_add_librariesเพื่อแก้ไขและติดตั้งใช้งานไลบรารีที่จำเป็นสำหรับ Sandboxee--sandbox2tool_additional_bind_mounts <PATHS>เพื่อทำให้ไดเรกทอรีเพิ่มเติมพร้อมใช้งานสำหรับ Sandboxee--sandbox2tool_keep_envเพื่อเก็บตัวแปรสภาพแวดล้อมปัจจุบันไว้--sandbox2tool_redirect_fd1เพื่อรับSTDOUT_FILENO (1)ของ Sandboxee และแสดงผลในเครื่อง--sandbox2tool_cpu_timeoutเพื่อตั้งค่าการหมดเวลาของ CPU เป็นวินาที--sandbox2tool_walltime_timeoutเพื่อตั้งค่าการหมดเวลาของเวลาจริงเป็นวินาที--sandbox2tool_file_size_creation_limitเพื่อตั้งค่าขนาดสูงสุดของไฟล์ที่สร้างขึ้น--sandbox2tool_cwdเพื่อตั้งค่าไดเรกทอรีที่ใช้งานปัจจุบันของแซนด์บ็อกซ์
custom_fork
ตัวอย่าง custom_fork แสดงวิธีสร้างแซนด์บ็อกซ์ที่จะเริ่มต้นไบนารี จากนั้นรอคำขอ fork() จาก Executor หลัก
โหมดนี้อาจเพิ่มประสิทธิภาพเมื่อเทียบกับการแซนด์บ็อกซ์ประเภทอื่นๆ เนื่องจากในที่นี้ การสร้างอินสแตนซ์ใหม่ของ Sandboxee ไม่จำเป็นต้องเรียกใช้ไบนารีใหม่ เพียงแค่แยกอินสแตนซ์ที่มีอยู่
- custom_fork_bin.cc: เซิร์ฟเวอร์แยกแบบกำหนดเอง ซึ่งรับคำขอ
fork()(ผ่านForkingClient::EnterForkLoop) เพื่อสร้าง Sandboxee ใหม่ - custom_fork_sandbox.cc: Executor ซึ่งเริ่มเซิร์ฟเวอร์แยกแบบกำหนดเอง จากนั้นจะส่งคำขอไปยังเซิร์ฟเวอร์ (ผ่าน Executor ใหม่) เพื่อสร้าง (ผ่าน
fork()) Sandboxee ใหม่
เครือข่าย
เนมสเปซของเครือข่ายซึ่งเปิดใช้โดยค่าเริ่มต้นจะป้องกันไม่ให้กระบวนการที่แซนด์บ็อกซ์เชื่อมต่อกับโลกภายนอก ตัวอย่างนี้แสดงวิธีจัดการกับปัญหานี้
การเชื่อมต่อจะเริ่มต้นภายใน Executor และซ็อกเก็ตที่ได้จะส่งผ่าน ::sandbox2::Comms::SendFD() Sandboxee จะรับซ็อกเก็ตโดยใช้ ::sandbox2::Comms::RecvFD() จากนั้นจะใช้ซ็อกเก็ตนี้เพื่อแลกเปลี่ยนข้อมูลตามปกติ
- network_bin.cc: โปรแกรมที่เราต้องการแซนด์บ็อกซ์ (เช่น Sandboxee)
- network_sandbox.cc: โปรแกรมแซนด์บ็อกซ์ที่จะดำเนินการ (เช่น Executor)
network_proxy
ตัวอย่างนี้แสดงวิธีอื่นในการจัดการกับเนมสเปซของเครือข่าย ภายในแล้ว ตัวอย่างนี้จะทำงานในลักษณะเดียวกับตัวอย่างด้านบน แต่แสดงเป็น API ที่สะดวกกว่า
Sandboxee สามารถสร้างการเชื่อมต่อเครือข่ายได้ 2 วิธี ได้แก่
- อัตโนมัติ \- โดยการติดตั้งแฮนเดิลเลอร์อัตโนมัติ แล้วเรียกใช้การเชื่อมต่อปกติ
- ด้วยตนเอง \- โดยรับ
NetworkProxyClientและใช้NetworkProxyClient::Connectโดยตรง
ตัวอย่างนี้แสดงทั้ง 2 วิธี ระบบจะใช้โหมดอัตโนมัติเมื่อตั้งค่าแฟล็ก connect_with_handler ไว้ ไม่เช่นนั้นจะใช้โหมดด้วยตนเอง
- network_bin.cc: โปรแกรมที่เราต้องการแซนด์บ็อกซ์ (เช่น Sandboxee)
- network_sandbox.cc: โปรแกรมแซนด์บ็อกซ์ที่จะดำเนินการ (Executor)