정의: chroot – Linux의 시스템 호출 및 유틸리티
13368 단어 systemcallskernellinux
chroot()
는 1979년 버전 7 Unix에 added이었으며 파일 시스템 격리에 사용되었습니다.사실, 이것은 전체 현재 컨테이너화 아이디어의 전신이며, 지금은 namespaces cgroups가 사용되고 이전 chroot는 예를 들어 호스트에서 격리되고 테스트 목적으로 사용될 수 있는 환경을 만드는 데 사용되었습니다.
또한 ch와 root는 change와 root(파일 시스템의)의 "약어"입니다.
Linux 파일 시스템 트리
Linux의 디렉토리 트리는 일반적으로 다음과 같습니다(Filesystem Hierarchy Standard 참조).
$ tree -d -L 1 /
/
├── bin -> usr/bin
├── boot
├── data
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib
├── lost+found
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/bin
├── srv
├── sys
├── tmp
├── usr
└── var
chroot()
다음 그림과 함께 시연할 수 있는 중첩된 파일 시스템 트리를 만들 수 있습니다.아래에서 일부 C 코드 예제와
chroot()
유틸리티 및 운영 체제에서의 사용법에 대해 자세히 살펴보겠습니다.chroot – Linux 시스템 호출
따라서 chroot는 루트를 변경하여 파일 시스템에 대한 액세스를 제한하기 위한 것입니다.
즉. 다음과 같은 디렉토리 구조 대신:
$ tree -d -L 1 /
/
├── bin -> usr/bin
├── boot
├── data
...
├── tmp
├── usr
└── var
프로세스는
chroot()
에 전달된 매개변수에 의해 최상위 수준에서 제한되는 항목만 볼 수 있습니다.예를 들어 사용할 다음 디렉토리를 만들어 보겠습니다.
$ mkdir -p /tmp/chroot/{1,2,3,4}
그리고 다음 코드를 C로 작성해 봅시다.
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
int main(void) {
// check path before chroot()
char t_cwd[PATH_MAX];
getcwd(t_cwd, sizeof(t_cwd));
printf("Current dir before chroot(): %s\n", t_cwd);
// do chroot()
chdir("/tmp/chroot/");
if (chroot("/tmp/chroot/") != 0) {
perror("chroot /tmp/chroot/");
return 1;
}
// check path path after chroot()
char a_cwd[PATH_MAX];
getcwd(a_cwd, sizeof(a_cwd));
printf("Current dir after chroot(): %s\n", a_cwd);
// point dr struct to the "root"
struct dirent *de;
DIR *dr = opendir("/");
// run readdir() and list "root"'s content
while ((de = readdir(dr)) != NULL)
printf("%s\n", de->d_name);
// try to open /etc/passwd from a "host" filesystem
FILE *f;
f = fopen("/etc/passwd", "r");
if (f == NULL) {
perror("/etc/passwd");
return 1;
} else {
char buf[100];
while (fgets(buf, sizeof(buf), f)) {
printf("%s", buf);
}
}
return 0;
}
여기서는 다음과 같습니다.
chroot()
.chroot()
chroot()
파일을 열려고 합니다구축:
$ gcc chroot_example.c -o chroot_example
그리고 실행하여 확인합니다(
/etc/passwd
는 루트에서만 사용할 수 있으므로):$ sudo ./chroot_example
Current dir before chroot(): /home/setevoy/Scripts/C
Current dir after chroot(): /
.
..
4
3
2
1
/etc/passwd: No such file or directory
sudo
자체는 커널의 chroot()
파일에 정의되어 있습니다.SYSCALL_DEFINE1(chroot, const char __user *, filename)
{
return ksys_chroot(filename);
}
그리고
chroot()
을 반환합니다.int ksys_chroot(const char __user *filename)
{
struct path path;
int error;
unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
retry:
error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
if (error)
goto out;
error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
if (error)
goto dput_and_out;
error = -EPERM;
if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
goto dput_and_out;
error = security_path_chroot(&path);
if (error)
goto dput_and_out;
set_fs_root(current->fs, &path);
error = 0;
dput_and_out:
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}
out:
return error;
}
차례로 프로세스에 대해
open.c
을 호출합니다.void set_fs_root(struct fs_struct *fs, const struct path *path)
{
struct path old_root;
path_get(path);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_root = fs->root;
fs->root = *path;
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_root.dentry)
path_put(&old_root);
}
좋은 syscalls 설명 here>> 및 here>>>을 찾을 수 있습니다.
ksys_chroot() – Linux 유틸리티
Linux에서 격리된 공간을 만들려면
set_fs_root()
유틸리티를 사용할 수 있습니다.$ which chroot
/usr/bin/chroot
$ file /usr/bin/chroot
/usr/bin/chroot: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=f3861107940247a67dbbf6343fa5ff1c1c70305c, stripped
격리된 파일 시스템을 사용하여 "감옥"(FreeBSD
chroot
은 UNIX chroot의 고급 후속 제품)에 대한 카탈로그를 생성해 보겠습니다.$ cd /tmp/
$ mkdir changed_root
실제로
chroot
유틸리티는 동일한 jail
시스템 호출을 호출합니다. chroot
으로 확인하겠습니다.$ sudo strace -e trace=chroot chroot changed_root/
chroot("changed_root/") = 0
chroot: failed to run command ‘/bin/bash’: No such file or directory
+++ exited with 127 +++
'/bin/bash': 이 새로운 환경에는
chroot()
디렉토리와 strace
실행 파일이 없다는 사실로 인해 이러한 파일 또는 디렉토리 오류가 발생하지 않습니다.마찬가지로 다른 프로그램을 호출하려고 하면 이러한 오류가 반환됩니다.
[setevoy@setevoy-arch-work /tmp] $ which ls
/usr/bin/ls
[setevoy@setevoy-arch-work /tmp] $ sudo chroot changed_root /usr/bin/ls
chroot: failed to run command ‘/usr/bin/ls’: No such file or directory
수정해 보겠습니다.
/bin
에 bash
디렉토리를 만들고 이 "컨테이너"내부의 "호스트"에서 파일을 복사/bin
합니다.[setevoy@setevoy-arch-work /tmp] $ mkdir changed_root/bin
[setevoy@setevoy-arch-work /tmp] $ cp /bin/bash changed_root/bin
[setevoy@setevoy-arch-work /tmp] $ file changed_root/bin/bash
changed_root/bin/bash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=357034d1736cd97d2c8f8347045250dbd0de998e, stripped
다시 시도하십시오:
[setevoy@setevoy-arch-work /tmp] $ sudo chroot changed_root /bin/bash
chroot: failed to run command ‘/bin/bash’: No such file or directory
괜찮아.
그러나 지금은 필요한 라이브러리가 없기 때문에 발생합니다.
/tmp/changed_root
이것에 대해 말할 수 없습니다.bash
의 종속성을 chroot
으로 확인합니다.[setevoy@setevoy-arch-work /tmp] $ ldd /bin/bash
linux-vdso.so.1 (0x00007ffe37f16000)
libreadline.so.8 => /usr/lib/libreadline.so.8 (0x00007f39b13d2000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f39b13cd000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f39b1209000)
libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x00007f39b119a000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f39b153f000)
새 작업 디렉터리에 두 개의 카탈로그(
bash
및 ldd
)를 더 만듭니다.[setevoy@setevoy-arch-work /tmp] $ mkdir changed_root/usr/lib changed_root/lib64
그리고 libs 파일을 복사합니다.
[setevoy@setevoy-arch-work /tmp] $ cp /usr/lib/libreadline.so.8 changed_root/usr/lib/
[setevoy@setevoy-arch-work /tmp] $ cp /usr/lib/libdl.so.2 changed_root/usr/lib/
[setevoy@setevoy-arch-work /tmp] $ cp /usr/lib/libc.so.6 changed_root/usr/lib/
[setevoy@setevoy-arch-work /tmp] $ cp /usr/lib/libncursesw.so.6 changed_root/usr/lib/
[setevoy@setevoy-arch-work /tmp] $ cp /lib64/ld-linux-x86-64.so.2 changed_root/lib64
/lib
를 다시 실행합니다.[setevoy@setevoy-arch-work /tmp] $ sudo chroot changed_root/
bash-5.0#
이제 여기에서 실행 중인
/lib64
및 모든 내장 함수가 있습니다.bash-5.0# pwd
/
그러나 분명히 – 다른 외부 유틸리티는 여기에서 작동하지 않습니다.
bash-5.0# ls -l
bash: ls: command not found
그리고 이것은
chroot
에 대해 수행한 것과 동일한 방식으로 수정할 수 있습니다.[setevoy@setevoy-arch-work /tmp] $ which ls
/usr/bin/ls
[setevoy@setevoy-arch-work /tmp] $ cp /usr/bin/ls changed_root/bin/
[setevoy@setevoy-arch-work /tmp] $ ldd /usr/bin/ls
linux-vdso.so.1 (0x00007ffdebbf5000)
libcap.so.2 => /usr/lib/libcap.so.2 (0x00007fa5b147d000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fa5b12b9000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fa5b14d8000)
[setevoy@setevoy-arch-work /tmp] $ cp /usr/lib/libcap.so.2 changed_root/usr/lib/
다른 라이브러리는 이미 복사되었으므로 다시 실행해 보겠습니다
bash
.bash-5.0# /bin/ls -l /
total 0
drwxr-xr-x 2 1000 1000 80 Mar 22 11:45 bin
drwxr-xr-x 2 1000 1000 120 Mar 22 11:37 lib
drwxr-xr-x 2 1000 1000 60 Mar 22 11:38 lib64
drwxr-xr-x 3 1000 1000 60 Mar 22 11:39 usr
또한보십시오
유사한 게시물
2019-03-03 (0)
2018-03-10 What is: Linux namespaces, примеры PID и Network namespaces (0)
2017년 3월 18일 Linux: LVM – уменьшить home, увеличить root (1)
2018-10-20 Linux: увеличение размера раздела без LVM с сохранением данных на ext4 (0)
Reference
이 문제에 관하여(정의: chroot – Linux의 시스템 호출 및 유틸리티), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/setevoy/what-is--chroot--the-system-call-and-utility-in-linux-105k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)