১. একটি স্যান্ডবক্স এক্সিকিউটর পদ্ধতি বেছে নিন
স্যান্ডবক্সিং একজন এক্সিকিউটর দিয়ে শুরু হয় ( স্যান্ডবক্স এক্সিকিউটর দেখুন), যা স্যান্ডবক্সি চালানোর জন্য দায়ী। executor.h হেডার ফাইলটিতে এই উদ্দেশ্যে প্রয়োজনীয় API রয়েছে। APIটি খুবই নমনীয় এবং আপনার ব্যবহারের ক্ষেত্রে কোনটি সবচেয়ে ভালো কাজ করে তা আপনাকে বেছে নিতে দেয়। নিম্নলিখিত বিভাগগুলিতে আপনি যে 3টি ভিন্ন পদ্ধতি থেকে বেছে নিতে পারেন তার বর্ণনা দেওয়া হয়েছে।
পদ্ধতি ১: স্বতন্ত্র - স্যান্ডবক্সিং ইতিমধ্যেই সক্ষম করে একটি বাইনারি কার্যকর করুন
এটি স্যান্ডবক্সিং ব্যবহারের সবচেয়ে সহজ উপায় এবং যখন আপনি একটি সম্পূর্ণ বাইনারি স্যান্ডবক্স করতে চান যার জন্য আপনার কোনও সোর্স কোড নেই তখন এটি প্রস্তাবিত পদ্ধতি। এটি স্যান্ডবক্সিং ব্যবহারের সবচেয়ে নিরাপদ উপায়, কারণ কোনও আনস্যান্ডবক্সড ইনিশিয়ালাইজেশন নেই যার বিরূপ প্রভাব পড়তে পারে।
নিচের কোড স্নিপেটে, আমরা স্যান্ডবক্স করার জন্য বাইনারিটির পথ এবং 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::Client::SandboxMeHere() কল করে স্যান্ডবক্সিংয়ে কখন প্রবেশ করবেন তা বেছে নেওয়ার সুযোগ দেয়। স্যান্ডবক্সিং শুরু করার সময় আপনাকে কোডে সংজ্ঞায়িত করতে সক্ষম হতে হবে এবং এটি একক-থ্রেডেড হতে হবে ( FAQ তে কেন পড়ুন)।
নিচের কোড স্নিপেটে, আমরা উপরে পদ্ধতি ১-এ বর্ণিত একই কোড ব্যবহার করি। তবে, ইনিশিয়ালাইজেশনের সময় প্রোগ্রামটিকে আনস্যান্ডবক্সড পদ্ধতিতে চালানোর অনুমতি দেওয়ার জন্য, আমরা 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);
যেহেতু স্যান্ডবক্সী কর্তৃক অবহিত না হওয়া পর্যন্ত এক্সিকিউটরের একটি অক্ষম স্যান্ডবক্স রয়েছে, তাই আমাদের একটি ::sandbox2::Client ইনস্ট্যান্স তৈরি করতে হবে, এক্সিকিউটর এবং স্যান্ডবক্সীর মধ্যে যোগাযোগ সেট আপ করতে হবে এবং তারপর এক্সিকিউটরকে অবহিত করতে হবে যে আমাদের আরম্ভকরণ সম্পন্ন হয়েছে এবং আমরা এখন 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::EnterForkLook() এর মাধ্যমে) করবে। নতুন তৈরি প্রক্রিয়াটি ::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 থেকে উপকৃত হবেন কিন্তু এর নেতিবাচক দিক হল কোনও আসল ASLR নেই। আরেকটি সাধারণ ব্যবহারের উদাহরণ হল যখন Sandboxee-তে একটি দীর্ঘ, CPU-নিবিড় ইনিশিয়ালাইজেশন থাকে যা অবিশ্বস্ত ডেটা প্রক্রিয়া করার আগে চালানো যেতে পারে।
এই এক্সিকিউটর পদ্ধতির উদাহরণের জন্য, custom_fork দেখুন।