1. सैंडबॉक्स एक्ज़ीक्यूट करने वाला तरीका चुनें

सैंडबॉक्सिंग की शुरुआत एक एक्ज़ीक्यूटर (Sandbox Executor देखें) से होती है, जो Sandboxee को चलाने के लिए ज़िम्मेदार है. executor.h हेडर फ़ाइल में इस काम के लिए ज़रूरी एपीआई शामिल होता है. इस एपीआई में बहुत ज़रूरत के हिसाब से बदलाव किए जा सकते हैं. इसकी मदद से, अपनी ज़रूरत के हिसाब से किसी सुविधा को चुना जा सकता है. यहां दिए गए सेक्शन में, तीन अलग-अलग तरीकों के बारे में बताया गया है. इनमें से किसी एक तरीके को चुना जा सकता है.

पहला तरीका: स्टैंड-अलोन – सैंडबॉक्सिंग की सुविधा पहले से चालू करके बाइनरी फ़ाइल का इस्तेमाल करें

यह सैंडबॉक्सिंग का इस्तेमाल करने का सबसे आसान तरीका है. यह तरीका तब सुझाया जाता है, जब आपको एक ऐसी पूरी बाइनरी को सैंडबॉक्स करना हो जिसके लिए आपके पास कोई सोर्स कोड नहीं है. यह सैंडबॉक्सिंग को इस्तेमाल करने का सबसे सुरक्षित तरीका भी है. ऐसा नहीं है, क्योंकि इसमें सैंडबॉक्स न की गई प्रोसेस को शुरू करने की कोई ज़रूरत नहीं है. इसकी वजह से खराब असर पड़ सकता है.

नीचे दिए गए कोड स्निपेट में, हम सैंडबॉक्स किए जाने वाले बाइनरी के पाथ को तय करते हैं. साथ ही, execve syscall को पास किए जाने वाले तर्क भी तय करते हैं. जैसा कि executor.h हेडर फ़ाइल में देखा जा सकता है, हम envp के लिए कोई वैल्यू तय नहीं करते हैं. इसलिए, पैरंट प्रोसेस से एनवायरमेंट को कॉपी किया जाता है. याद रखें कि पहला आर्ग्युमेंट, एक्ज़ीक्यूट किए जाने वाले प्रोग्राम का नाम होता है. साथ ही, हमारा स्निपेट कोई दूसरा आर्ग्युमेंट तय नहीं करता.

एक्सपोर्ट करने वाले इस तरीके के उदाहरण: स्टैटिक और टूल हैं.

#include "sandboxed_api/sandbox2/executor.h"

std::string path = "path/to/binary";
std::vector<std::string> args = {path};  // args[0] will become the sandboxed
                                         // process' argv[0], typically the
                                         // path to the binary.
auto executor = absl::make_unique<sandbox2::Executor>(path, args);

दूसरा तरीका: Sandbox2 फ़ोर्कसर्वर – एक्सक्यूटर को बताएं कि सैंडबॉक्स कब करना है

इस तरीके से, शुरू करने के दौरान सैंडबॉक्स न किए जाने की सुविधा मिलती है. इसके बाद, ::sandbox2::Client::SandboxMeHere() को कॉल करके सैंडबॉक्सिंग की प्रोसेस को चालू किया जा सकता है. सैंडबॉक्सिंग शुरू करते समय, इसे कोड में तय करना ज़रूरी है. साथ ही, इसे सिंगल-थ्रेड होना चाहिए (अक्सर पूछे जाने वाले सवाल में इसकी वजह पढ़ें).

यहां दिए गए कोड स्निपेट में, हम उसी कोड का इस्तेमाल करते हैं जिसके बारे में ऊपर तरीका 1 में बताया गया है. हालांकि, शुरू करने के दौरान, प्रोग्राम को सैंडबॉक्स न किए जाने पर काम करने देने के लिए, हम set_enable_sandbox_before_exec(false) को कॉल करते हैं.

#include "sandboxed_api/sandbox2/executor.h"

std::string path = "path/to/binary";
std::vector<std::string> args = {path};
auto executor = absl::make_unique<sandbox2::Executor>(path, args);
executor->set_enable_sandbox_before_exec(false);

फ़िलहाल, एक्ज़ीक्यूटर में एक बंद सैंडबॉक्स है, जिसे Sandboxee से सूचना मिलने तक बंद किया जाता है. इसलिए, हमें ::sandbox2::Client इंस्टेंस बनाना होगा और एक्ज़िक्यूटर और Sandboxee के बीच कम्यूनिकेशन सेट अप करना होगा. इसके बाद, एक्ज़ीक्यूटर को यह सूचना देनी होगी कि हमारा इनिशिएटिवेशन पूरा हो गया है और हमें sandbox2_client.SandboxMeHere() को कॉल करके सैंडबॉक्सिंग अभी शुरू करनी है.

// main() of sandboxee
int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, false);

  // Set-up the sandbox2::Client object, using a file descriptor (1023).
  sandbox2::Comms comms(sandbox2::Comms::kSandbox2ClientCommsFD);
  sandbox2::Client sandbox2_client(&comms);
  // Enable sandboxing from here.
  sandbox2_client.SandboxMeHere();
  …

इस एक्सक्यूटर तरीके का उदाहरण crc4 है, जहां crc4bin.cc सैंडबॉक्सी है और एक्सक्यूटर (crc4sandbox.cc) को इसकी सूचना देता है कि उसे सैंडबॉक्स में कब जाना चाहिए.

तीसरा तरीका: कस्टम फ़ोर्कसर्वर – एक बाइनरी तैयार करें, फ़ोर्क अनुरोधों का इंतज़ार करें, और खुद सैंडबॉक्स करें

यह मोड आपको बाइनरी शुरू करने देता है, उसे सैंडबॉक्सिंग के लिए तैयार करने देता है, और, अपनी बाइनरी के लाइफ़साइकल के किसी खास समय पर, उसे एक्ज़ीक्यूटर के लिए उपलब्ध कराने देता है.

एक्ज़ीक्यूटर, आपकी बाइनरी को फ़ोर्क अनुरोध भेजेगा, जिसमें fork() (::sandbox2::ForkingClient::WaitAndFork() की मदद से) होगा. नई प्रोसेस, ::sandbox2::Client::SandboxMeHere() की मदद से सैंडबॉक्स किए जाने के लिए तैयार होगी.

#include "sandboxed_api/sandbox2/executor.h"

// Start the custom ForkServer
std::string path = "path/to/binary";
std::vector<std::string> args = {path};
auto fork_executor = absl::make_unique<sandbox2::Executor>(path, args);
fork_executor->StartForkServer();

// Initialize Executor with Comms channel to the ForkServer
auto executor = absl::make_unique<sandbox2::Executor>(
    fork_executor->ipc()->GetComms());

ध्यान रखें कि यह मोड काफ़ी जटिल है और कुछ ही मामलों में लागू होता है. उदाहरण के लिए, जब आपको कम मेमोरी की ज़रूरत हो. आपको COW से फ़ायदा होगा, लेकिन इसका एक नुकसान यह भी है कि असली एएसएलआर नहीं होता है. इसके इस्तेमाल का एक अन्य उदाहरण यह है कि जब Sandboxee में लंबे समय तक सीपीयू की ज़रूरत के हिसाब से प्रोसेस शुरू किया जाता है, तब गैर-भरोसेमंद डेटा प्रोसेस होने से पहले उसे चलाया जा सकता है.

एक्सपोर्ट करने वाले इस तरीके के उदाहरण के लिए, custom_fork देखें.