কোনও রুটবিহীন ব্যবহারকারীর পক্ষে উবুন্টুতে ক্রোট প্রক্রিয়া চালানো কি সম্ভব?
কোনও রুটবিহীন ব্যবহারকারীর পক্ষে উবুন্টুতে ক্রোট প্রক্রিয়া চালানো কি সম্ভব?
উত্তর:
লিনাক্সে ক্রুট (2) সিস্টেম কলটি কেবলমাত্র একটি প্রক্রিয়া দ্বারা করা যেতে পারে যা সুবিধাযুক্ত। প্রক্রিয়াটির যে সক্ষমতা প্রয়োজন তা হ'ল CAP_SYS_CHROOT।
আপনি ব্যবহারকারী হিসাবে ক্রট করতে না পারার কারণটি খুব সহজ। ধরুন আপনার কাছে একটি সেটুইড প্রোগ্রাম রয়েছে যেমন সুডো যা আপনাকে কিছু করার অনুমতি দিলে / ইত্যাদি / sudoers পরীক্ষা করে। এবার এটি আপনার নিজের / ইত্যাদি / সুডোরের সাথে ক্রুট ক্রুটে রাখুন। হঠাৎ আপনার কাছে তাত্ক্ষণিক সুবিধাদি বৃদ্ধি।
নিজেকে ক্রুট করার জন্য কোনও প্রোগ্রাম ডিজাইন করা এবং সেটুয়েড প্রক্রিয়া হিসাবে চালানো সম্ভব তবে এটি সাধারণত খারাপ ডিজাইন হিসাবে বিবেচিত হয়। ক্রুটের অতিরিক্ত সুরক্ষা সেটওয়াইডের সাথে সুরক্ষা সমস্যাগুলিকে উদ্বুদ্ধ করে না।
chroot
তারপরে সম্পাদন করবে ।
@ ইমজ - ইভানজখরিয়াশেভ পেয়ারদের উত্তর সম্পর্কে মন্তব্য করেছেন যে নামস্থানগুলি প্রবর্তনের মাধ্যমে এটি সম্ভব হতে পারে, তবে এটি উত্তর হিসাবে পোস্ট করা হয়নি। হ্যাঁ, এটি প্রকৃতপক্ষে কোনও অ-রুট ব্যবহারকারীকে ক্রোট ব্যবহার করা সম্ভব করে তোলে।
একটি স্ট্যাটিকালি লিঙ্কযুক্ত dash
এবং একটি স্ট্যাটিকালি লিঙ্কযুক্ত busybox
এবং একটি চলমান bash
শেল নন-রুট হিসাবে চলমান দেওয়া হয়েছে:
$ mkdir root
$ cp /path/to/dash root
$ cp /path/to/busybox root
$ unshare -r bash -c 'chroot root /dash -c "/busybox ls -al /"'
total 2700
drwxr-xr-x 2 0 0 4096 Dec 2 19:16 .
drwxr-xr-x 2 0 0 4096 Dec 2 19:16 ..
drwxr-xr-x 1 0 0 1905240 Dec 2 19:15 busybox
drwxr-xr-x 1 0 0 847704 Dec 2 19:15 dash
যে নামস্থান শিকড় ব্যবহারকারী আইডি নামস্থান অ-রুট ইউজার আইডি বাইরে ম্যাপ করা হয়, এবং তদ্বিপরীত, যার কারণে সিস্টেমের শো হিসাবে 0. একজন নিয়মিত ব্যবহারকারী আইডি মালিকানাধীন বর্তমান ব্যবহারকারীর মালিকানাধীন ফাইল ls -al root
ছাড়া, unshare
, আছে বর্তমান ব্যবহারকারীর মালিকানাধীন হিসাবে তাদের দেখান।
দ্রষ্টব্য: এটি সুপরিচিত যে প্রসেসগুলি যেগুলি ব্যবহারে chroot
সক্ষম, একটি থেকে বিচ্ছিন্ন করতে সক্ষম chroot
। যেহেতু unshare -r
কাছে প্রার্থনা করি য়েন chroot
একজন সাধারণ ব্যবহারকারীর কাছে অনুমতির, এটি একটি নিরাপত্তা ঝুঁকি হবে যে যদি একটি ভিতরে অনুমতি দেওয়া হয়েছিল chroot
পরিবেশ। আসলে এটি অনুমোদিত নয় এবং এতে ব্যর্থ হয়:
অংশীদারী: শেয়ারহীন ব্যর্থ: অপারেশন অনুমোদিত নয়
যা ভাগ না করা (2) ডকুমেন্টেশনের সাথে মেলে :
ইপিআরএম (লিনাক্স ৩.৯ থেকে)
CLONE_NEWUSER পতাকাগুলিতে নির্দিষ্ট করা হয়েছিল এবং কলারটি ক্রুট পরিবেশে থাকে (যেমন, কলারের রুট ডিরেক্টরিটি যেখানে থাকে সেখানে মাউন্ট নেমস্পেসের মূল ডিরেক্টরিটির সাথে মেলে না)।
আজকাল, আপনি ক্রুট / বিএসডি কারাগারের পরিবর্তে এলএক্সসির (লিনাক্স কনটেইনারগুলি) সন্ধান করতে চান। এটি একটি ক্রুট এবং ভার্চুয়াল মেশিনের মধ্যে কোথাও রয়েছে, আপনাকে প্রচুর সুরক্ষা নিয়ন্ত্রণ এবং সাধারণ কনফিগারেশনে দেয়। আমি বিশ্বাস করি যে ব্যবহারকারী হিসাবে এটি চালানোর জন্য আপনার প্রয়োজনীয় সমস্ত কিছু সেই গ্রুপের সদস্য হতে হবে যা প্রয়োজনীয় ফাইল / ডিভাইসগুলির মালিকানাধীন, তবে এতে জড়িত দক্ষতা / সিস্টেম অনুমতিও থাকতে পারে। যে কোনও উপায়ে, এটি খুব কার্যক্ষম হওয়া উচিত, যেহেতু এলএক্সসি লিনাক্স কার্নেলের সাথে সেলইনাক্স ইত্যাদি যুক্ত হওয়ার অনেক পরে।
এছাড়াও, মনে রাখবেন যে আপনি কেবল স্ক্রিপ্টগুলি মূল হিসাবে লিখতে পারেন তবে ব্যবহারকারীদের সেই স্ক্রিপ্টগুলি চালানোর জন্য সুরক্ষিত অনুমতি দিন (যদি আপনি চান তবে পাসওয়ার্ড ছাড়াই, তবে নিশ্চিত করুন যে স্ক্রিপ্টটি সুরক্ষিত আছে) sudo ব্যবহার করে।
ফেকরূট / ফেকেররুটের সংমিশ্রণটি সরল প্রয়োজনের জন্য ক্রুটের একটি সিমুলার দেয় যেমন আর্কাইভ উত্পাদন যেখানে ফাইলগুলি রুটের মালিকানাধীন বলে মনে হয়। ফাকেররুট ম্যানপেজটি হ'ল http://linux.die.net/man/1/fakechroot ।
যদিও আপনি কোনও নতুন অনুমতি পাবেন না, তবে যদি আপনি ডিরেক্টরি চালানোর আগে কোনও ডিরেক্টরি (যেমন নকল-ডিস্ট্রো) রাখেন
fakechroot fakeroot chroot ~/fake-distro some-command
এটি এখন কোনও কমান্ডের সন্ধান করুন যেমন আপনি মূল এবং নকল-ডিস্রো-র মধ্যে সমস্ত কিছুর মালিক।
~/fake-distro
ব্যবহারসমূহ, busybox, যা symlinks ls
, mv
এবং অন্যান্য সাধারণ ইউটিলিটি /bin/busybox
। আমি যদি স্পষ্টভাবে কল করি /bin/busybox mv ...
তবে জিনিসগুলি কাজ করে তবে আমি কল করলে /bin/mv ...
আমি পাই sh: /bin/mv: not found
। export FAKECHROOT_EXCLUDE_PATH=/
ফ্যাকেরুট চালানোর আগে সেট করে সেই লক্ষণটি ঠিক করে তবে এটি অন্য চিহ্নগুলিতে (যেমন /usr/bin/vim -> /usr/bin/vim.vim
) ভাঙে ।
মনে হচ্ছে ব্যবহারকারী-নেমস্পেসের সাহায্যে এটি মূল ছাড়া গোটা করা সম্ভব। এখানে একটি উদাহরণ প্রোগ্রাম যা দেখায় যে এটি সম্ভব। আমি কেবল লিনাক্স নেমস্পেসগুলি কীভাবে কাজ করে তা অন্বেষণ করতে শুরু করেছি এবং তাই এই কোডটি সেরা অনুশীলন কিনা তা আমি পুরোপুরি নিশ্চিত নই।
হিসাবে সংরক্ষণ করুন user_chroot.cc
। সঙ্গে সংকলন g++ -o user_chroot user_chroot.cc
। ব্যবহার হয় ./user_chroot /path/to/new_rootfs
।
// references:
// [1]: http://man7.org/linux/man-pages/man7/user_namespaces.7.html
// [2]: http://man7.org/linux/man-pages/man2/unshare.2.html
#include <sched.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include <cstring>
int main(int argc, char** argv) {
if(argc < 2) {
printf("Usage: %s <rootfs>\n", argv[0]);
}
int uid = getuid();
int gid = getgid();
printf("Before unshare, uid=%d, gid=%d\n", uid, gid);
// First, unshare the user namespace and assume admin capability in the
// new namespace
int err = unshare(CLONE_NEWUSER);
if(err) {
printf("Failed to unshare user namespace\n");
return 1;
}
// write a uid/gid map
char file_path_buf[100];
int pid = getpid();
printf("My pid: %d\n", pid);
sprintf(file_path_buf, "/proc/%d/uid_map", pid);
int fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
err = dprintf(fd, "%d %d 1\n", uid, uid);
if(err == -1) {
printf("Failed to write contents [%d]: %s\n", errno,
strerror(errno));
}
close(fd);
}
sprintf(file_path_buf, "/proc/%d/setgroups", pid);
fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
dprintf(fd, "deny\n");
close(fd);
}
sprintf(file_path_buf, "/proc/%d/gid_map", pid);
fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
err = dprintf(fd, "%d %d 1\n", gid, gid);
if(err == -1) {
printf("Failed to write contents [%d]: %s\n", errno,
strerror(errno));
}
close(fd);
}
// Now chroot into the desired directory
err = chroot(argv[1]);
if(err) {
printf("Failed to chroot\n");
return 1;
}
// Now drop admin in our namespace
err = setresuid(uid, uid, uid);
if(err) {
printf("Failed to set uid\n");
}
err = setresgid(gid, gid, gid);
if(err) {
printf("Failed to set gid\n");
}
// and start a shell
char argv0[] = "bash";
char* new_argv[] = {
argv0,
NULL
};
err = execvp("/bin/bash", new_argv);
if(err) {
perror("Failed to start shell");
return -1;
}
}
আমি এটি মাল্টিস্ট্রেপ (নন-রুট হিসাবে চালিত) দিয়ে তৈরি একটি সর্বনিম্ন রুটফেসে পরীক্ষা করেছি। কিছু সিস্টেম ফাইল পছন্দ /etc/passwd
এবং /etc/groups
অতিথি rootfs মধ্যে হোস্ট rootfs থেকে কপি করা হয়েছে।
Failed to unshare user namespace
লিনাক্স 4.12.10 (আর্চ লিনাক্স) এ আমার জন্য ব্যর্থ ।
unshare
। আপনি এই অজগর সংস্করণটিও চেষ্টা করতে পারেন যার মধ্যে আরও ভাল ত্রুটি বার্তা বার্তা থাকতে পারে: github.com/cheshirekow/uchroot
না। আমি যদি সঠিকভাবে মনে করি তবে এখানে কিছু কার্নেল স্তরের জিনিস রয়েছে যা ক্রুট এটি প্রতিরোধ করে। আমি মনে করি না যে জিনিসটি কী ছিল। জেন্টুর ক্যাটালিস্ট বিল্ড টুল (এবং ভেন্টুতে থাকা একটি ক্রুট উবুন্টুতে একটি ক্রোট হিসাবে একই) যখন আমি গণ্ডগোল করলাম তখন আমি এটি আবার তদন্ত করেছি। যদিও এটি কোনও পাসডব্লুড ছাড়াই ঘটানো সম্ভব হবে ... তবে এই জাতীয় জিনিসগুলি সম্ভাব্য সুরক্ষা দুর্বলতার ক্ষেত্রের কাছে রেখে গেছে এবং আপনি কী করছেন তা আপনি নিশ্চিত তা নিশ্চিত করেছেন।