क्या गैर-रूट उपयोगकर्ता के लिए उबंटू पर चेरोट प्रक्रिया चलाना संभव है?
क्या गैर-रूट उपयोगकर्ता के लिए उबंटू पर चेरोट प्रक्रिया चलाना संभव है?
जवाबों:
लिनक्स पर चेरोट (2) सिस्टम कॉल केवल एक प्रक्रिया द्वारा किया जा सकता है जो विशेषाधिकार प्राप्त है। क्षमता की जरूरत है क्षमता CAP_SYS_CHROOT है।
एक उपयोगकर्ता के रूप में आपके द्वारा काटे जाने का कारण बहुत सरल नहीं है। मान लें कि आपके पास एक सेटूइड प्रोग्राम है जैसे कि sudo जो चेक / etc / sudoers है अगर आपको कुछ करने की अनुमति है। अब इसे अपने / आदि / सुडोल के साथ चुरोट चुरोट में डालें। अचानक आपके पास एक त्वरित विशेषाधिकार वृद्धि है।
एक कार्यक्रम को स्वयं चुरूट करना और इसे एक सेट्यूइड प्रक्रिया के रूप में चलाना संभव है, लेकिन इसे आमतौर पर खराब डिजाइन माना जाता है। चुरोट की अतिरिक्त सुरक्षा सेतु के साथ सुरक्षा मुद्दों को प्रेरित नहीं करती है।
chroot
फिर प्रदर्शन करेंगे ।
@ imz - इवानज़खायराशेव पेहर्स के जवाब पर टिप्पणी करते हैं कि यह नामस्थानों की शुरूआत के साथ संभव हो सकता है, लेकिन इसका उत्तर के रूप में परीक्षण और पोस्ट नहीं किया गया है। हां, यह वास्तव में गैर-रूट उपयोगकर्ता के लिए चेरोट का उपयोग करना संभव बनाता है।
एक स्टैटिकली-लिंक्ड 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
वातावरण। वास्तव में, इसकी अनुमति नहीं है, और इसके साथ विफल रहता है:
unshare: unshare विफल: ऑपरेशन की अनुमति नहीं है
जो अनशेयर (2) प्रलेखन से मेल खाता है :
EPERM (लिनक्स 3.9 के बाद से)
CLONE_NEWUSER झंडे में निर्दिष्ट किया गया था और कॉल करने वाला चिरोट वातावरण में है (यानी, कॉलर की रूट निर्देशिका माउंट नेमस्पेस की मूल निर्देशिका से मेल नहीं खाती जिसमें वह रहता है)।
इन दिनों, आप चेरोट / बीएसडी जेल के बजाय एलएक्ससी (लिनक्स कंटेनर) देखना चाहते हैं। यह कहीं न कहीं चेरोट और वर्चुअल मशीन के बीच है, जो आपको बहुत अधिक सुरक्षा नियंत्रण और सामान्य विन्यास प्रदान करता है। मेरा मानना है कि आप सभी को इसे चलाने की जरूरत है क्योंकि एक उपयोगकर्ता को उस समूह का सदस्य होना चाहिए जो आवश्यक फाइलों / उपकरणों का मालिक है, लेकिन इसमें क्षमताएं / सिस्टम अनुमतियाँ भी शामिल हो सकती हैं। किसी भी तरह से, यह बहुत ही उचित होना चाहिए, क्योंकि एलएक्ससी काफी हालिया है, लंबे समय के बाद SELinux आदि को लिनक्स कर्नेल में जोड़ा गया था।
यह भी ध्यान रखें कि आप केवल स्क्रिप्ट को रूट के रूप में लिख सकते हैं, लेकिन उपयोगकर्ताओं को उन लिपियों को चलाने की सुरक्षित अनुमति दें (यदि आप चाहें तो पासवर्ड के बिना, लेकिन यह सुनिश्चित करें कि sudo का उपयोग करके स्क्रिप्ट सुरक्षित है)।
फ़ेकरूट / फ़ेचक्रोट का संयोजन टार अभिलेखागार का निर्माण करने के लिए साधारण आवश्यकताओं के लिए चुरोट का एक सिमुलक्रे देता है जहाँ फाइलें जड़ से मालूम होती हैं। Fakechroot manpage http://linux.die.net/man/1/fakechroot है ।
हालाँकि, आपको कोई नई अनुमति नहीं मिलती है, लेकिन यदि आप एक निर्देशिका (जैसे नकली-डिस्ट्रो) का उपयोग करने से पहले करते हैं
fakechroot fakeroot chroot ~/fake-distro some-command
यह अब कुछ-कमांड की तलाश में है जैसे आप रूट हैं और नकली-डिस्ट्रो के भीतर सब कुछ का मालिक है।
~/fake-distro
उपयोग बिजीबॉक्स, जो कि सिमलिंक 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
होस्ट रूटफ़ेट्स से गेस्ट रूटफ़्स में कॉपी किए गए थे।
Failed to unshare user namespace
लिनक्स पर मेरे लिए 4.12.10 (आर्क लिनक्स) पर विफल रहता है ।
unshare
। आप इस अजगर संस्करण को भी आज़मा सकते हैं जिसमें बेहतर त्रुटि संदेश हो सकता है: github.com/cheshirekow/uchroot
नहीं, अगर मुझे सही ढंग से याद है तो कुछ कर्नेल स्तर की चीज है जो चेरोट करता है जो इसे रोकता है। मुझे याद नहीं है कि वह चीज क्या थी। मैंने इसे वापस जांच की जब गेंटू के कैटलिस्ट बिल्ड टूल के साथ खिलवाड़ किया गया (और जेंटू पर चुरोट उबंटू पर चुरोट के समान है)। हालांकि इसे बिना पासवार्ड के बनाना संभव होगा ... लेकिन इस तरह की चीजों को संभावित सुरक्षा कमजोरियों के दायरे में छोड़ दिया जाता है और सुनिश्चित करें कि आप जानते हैं कि आप क्या कर रहे हैं।