간단 사용법
**chroot** [**변경할 Root Directory 지정**] [**실행할 어플리케이션 경로**]
>> chroot /home/user/ /bin/bash
>> /home/user를 Root Directory로 하고 /bin/bash 어플리케이션으로 실행한다.
chroot, 즉 change Root Directory이며 말그대로 Root Directory를 변경하겠다는 명령어이며 root 권한으로 실행된다.
리눅스의 일반적인 File 구조를 보면 파일 시스템의 최상위인 (/
)가 있고 이 밑으로 여러 디렉토리가 존재한다.
/
├── a_chroot_test01
│ ├── sub_01_01
│ ├── sub_01_02
│ └── sub_01_03
├── a_chroot_test02
│ ├── sub_01_0a
│ ├── sub_01_0b
│ └── sub_01_0c
├── a_chroot_test03
│ ├── sub_01_0A
│ ├── sub_01_0B
│ └── sub_01_0C
**...
...**
이런식으로 /
밑에 a_chroot_test01/02/03
있고 **test01
**밑에 **sub01_01/02/03
**이 **test02
**밑에 0a/0b/0c
트리 구조를 가지고 있다.
일반적으로 임의의 프로세스가 접근할 때 기본적으로는 Root Directory(/
)를 기준으로 탐색 및 접근할 수 있다
chroot는 Root Directory를 다른 위치로 지정해서 프로세스를 실행 해주는 프로그램이다!
하지만 예를 들어 프로세스 X를 실행할 때 **a_chroot_test01**
을 Root Directory로 하는 프로세스 X를 보면 기존의 접근 방식인 **/
**에서 시작하는것이 아니기 때문에 a_chroot_test02/03
밑 그 하위 디렉토리를 접근 할 수 없고 프로세스 X를 기준으로 최상위는 **a_chroot_test01
**이기 때문에 다른 디렉토리를 표현 할 수 있는 방법이 없다.
이처럼 Root Directory를 변경하면 특정 프로세스 X가 격리되는 역할을 해주는 것이 chroot
이다.
chroot를 위에서 배운대로 입력해보자
[ec2-user@ip-192-168-1-180 ~]$ chroot /a_chroot_test01 /bin/bash
chroot: cannot change root directory to /a_chroot_test01: Operation not permitted
# Root 권한을 기본으로 하므로 에러 !
[ec2-user@ip-192-168-1-180 ~]$ sudo chroot /a_chroot_test01 /bin/bash
chroot: failed to run command ‘/bin/bash’: No such file or directory
# 음 /bin/bash가 없어서 에러 ?
**/a_chroot_test01
**을 Root Dirtectory로 지정하고 **/bin/bash
**로 실행..
하지만 Root로 지정한 곳의 하위 디렉토리에 **/bin/bash
**가 없으므로 오류가 난다. **/a_chroot_test01
**을 Root로 가져가기때문에,
**/
**에 **/bin/bash
**가 존재하더라도 **/bin/bash
**을 찾을 때 **/a_chroot_test01/bin/bash
**로 검색을 한다!
그렇다면 **/bin/bash
**을 **/a_chroot_test01/
**넣어서 다시 해보면..
$ sudo mkdir /a_chroot_test01/bin
$ sudo cp -p /bin/bash /a_chroot_test01/bin
$ tree
.
├── bin
│ └── bash
├── sub_01_01
├── sub_01_02
└── sub_01_03
sudo chroot /a_chroot_test01 /bin/bash
chroot: failed to run command ‘/bin/bash’: No such file or directory
여전히...없다고 뜨는데..왜? 난 넣었는데??!
프로그램마다 어떤 프로그램은 단독으로 실행되기도하지만, 많은 프로그램들은 시스템의 다른 파일에 의존하고 있다 (설치할때도 보면 rpm으로 설치할때 의존성오류 뿜뿜하는 것처럼,)
이럴 때 **strace
**로 해당 명령어를 입력할 때 systemcall을 확인함으로써 어디서 에러가 났는지 좀 더 명확하게 확인 할 수 있다.
따라서 프로그램의 의존성을 확인해줄 필요가 있는데 이게 바로 ldd
이다
ldd [**의존성 확인하고자 하는 경로**]
ldd **/a_chroot_test01/bin/bash
linux-vdso.so.1 (0x00007ffc051df000)
libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007f9cbea10000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f9cbe80c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9cbe461000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9cbec3b000)**
linux-vdso.so.1은...경로가 안나와서 일단 패스, 나머지 4파일의경로가 나오고 해당 파일을 새로 지정할 Root Diretory에 복사해주자
mkdir /a_chroot_test01/lib64/
sudo cp -p /lib64/libtinfo.so.6 /lib64/libdl.so.2 /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2 /a_chroot_test01/lib64/
tree
.
├── bin
│ └── bash
├── lib64
│ ├── ld-linux-x86-64.so.2
│ ├── libc.so.6
│ ├── libdl.so.2
│ └── libtinfo.so.6
├── sub_01_01
├── sub_01_02
└── sub_01_03
정상적으로 다 넣었으면 다시 chroot
츄라이!
sudo chroot /a_chroot_test01 /bin/bash
bash-4.2#
bash-4.2# /bin/bash --version
GNU bash, version 4.2.46(2)-release (x86_64-koji-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
bash-4.2# ls
bash: ls: command not found
정상적으로 bash가 실행되었다!
경로를 확인하기 위해서 **ls
**를 쳐보지만.. **ls
**또한 프로그램이므로 위와 동일한 과정을 거쳐야한다.
동일한 과정 = **ls
를 실행 시키기 위한 파일을 새로 지정한 Root Directory에 넣어주기 (ldd
**로 의존성 확인은 필수)
$ sudo cp -p /bin/ls /a_chroot_test01
$ ldd /bin/ls
linux-vdso.so.1 (0x00007fff0d187000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007feb9146f000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007feb9126a000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007feb91061000)
libc.so.6 => /lib64/libc.so.6 (0x00007feb90cb6000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007feb90a52000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007feb9084e000)
/lib64/ld-linux-x86-64.so.2 (0x00007feb91696000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007feb90649000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007feb9042b000)
$ sudo cp -p /lib64/libselinux.so.1 /lib64/libcap.so.2 /lib64/libacl.so.1 /lib64/libc.so.6 /lib64/libpcre.so.1 /lib64/libdl.so.2 /lib64/ld-linux-x86-64.so.2 /lib64/libattr.so.1 /lib64/libpthread.so.0 /a_chroot_test01/lib64/
$ sudo chroot /a_chroot_test01 /bin/bash
bash-4.2# pwd
/
bash-4.2# ls
bin lib64 sub_01_01 sub_01_02 sub_01_03
**pwd
**를 통해서 내가 설정한 새로운 Root Directory(**a_chroot_test01**
)을 **/
**로 인식하였고
ls
명령어가 정상적으로 동작함을 확인 할 수 있다.
이미 **/a_chroot_test01
**을 최상위인 **/
**로 인지하고 있으므로 기존에 있던 /a_chroot_test02 또는 03
그리고 그 **하위 디렉토리
**로는 찾아 갈 수없다.
현재 띄운 bash의 Process ID를 확인해보면
bash-4.2# echo $$
4579
호스트의 세션을 하나 더 접속후 ps로 이 프로세스를 찾아보자
[ec2-user@ip-192-168-1-180 ~]$ ps -ef | grep 4579
**root 4579 4578 0 07:57 pts/0 00:00:00 /bin/bash**
ec2-user 5175 5143 0 08:08 pts/1 00:00:00 grep --color=auto 4579
호스트에서 확인 결과 다른 프로세스와 마찬가지로 **프로세스중 하나
**로 보이는 것을 알 수 있다.
[ec2-user@ip-192-168-1-180 ~]$ strace chroot /a_chroot_test01/bin/bash /bin/bash execve("/usr/sbin/chroot", ["chroot", "/a_chroot_test01/bin/bash", "/bin/bash"], 0x7fff04a39290 /* 21 vars */) = 0 brk(NULL) = 0x11f3000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=23792, ...}) = 0 mmap(NULL, 23792, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9ca623e000 close(3) = 0 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\21\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=2021480, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9ca623c000 mmap(NULL, 3844768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9ca5c76000 mprotect(0x7f9ca5e17000, 2097152, PROT_NONE) = 0 mmap(0x7f9ca6017000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a1000) = 0x7f9ca6017000 mmap(0x7f9ca601d000, 15008, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9ca601d000 close(3) = 0 arch_prctl(ARCH_SET_FS, 0x7f9ca623d500) = 0 mprotect(0x7f9ca6017000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7f9ca6244000, 4096, PROT_READ) = 0 munmap(0x7f9ca623e000, 23792) = 0 brk(NULL) = 0x11f3000 brk(0x1214000) = 0x1214000 brk(NULL) = 0x1214000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=113049440, ...}) = 0 mmap(NULL, 113049440, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9c9f0a6000 close(3) = 0 chroot("/a_chroot_test01/bin/bash") = -1 ENOTDIR (Not a directory) open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=2997, ...}) = 0 read(3, "# Locale name alias data base.\n#"..., 4096) = 2997 read(3, "", 4096) = 0 close(3) = 0 open("/usr/share/locale/ko_KR.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=29938, ...}) = 0 mmap(NULL, 29938, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9ca6234000 close(3) = 0 write(2, "chroot: ", 8chroot: ) = 8 write(2, "cannot change root directory to "..., 57cannot change root directory to /a_chroot_test01/bin/bash) = 57 open("/usr/share/locale/ko_KR.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) write(2, ": Not a directory", 17: Not a directory) = 17 write(2, "\n", 1 ) = 1 close(1) = 0 close(2) = 0 exit_group(125) = ? +++ exited with 125 +++
[ec2-user@ip-192-168-1-180 ~]$ strace chroot /a_chroot_test01/bin/bash /bin/bash execve("/usr/sbin/chroot", ["chroot", "/a_chroot_test01/bin/bash", "/bin/bash"], 0x7fff04a39290 /* 21 vars */) = 0 brk(NULL) = 0x11f3000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=23792, ...}) = 0 mmap(NULL, 23792, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9ca623e000 close(3) = 0 openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\21\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=2021480, ...}) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9ca623c000 mmap(NULL, 3844768, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9ca5c76000 mprotect(0x7f9ca5e17000, 2097152, PROT_NONE) = 0 mmap(0x7f9ca6017000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a1000) = 0x7f9ca6017000 mmap(0x7f9ca601d000, 15008, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9ca601d000 close(3) = 0 arch_prctl(ARCH_SET_FS, 0x7f9ca623d500) = 0 mprotect(0x7f9ca6017000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7f9ca6244000, 4096, PROT_READ) = 0 munmap(0x7f9ca623e000, 23792) = 0 brk(NULL) = 0x11f3000 brk(0x1214000) = 0x1214000 brk(NULL) = 0x1214000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=113049440, ...}) = 0 mmap(NULL, 113049440, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9c9f0a6000 close(3) = 0 chroot("/a_chroot_test01/bin/bash") = -1 ENOTDIR (Not a directory) open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=2997, ...}) = 0 read(3, "# Locale name alias data base.\n#"..., 4096) = 2997 read(3, "", 4096) = 0 close(3) = 0 open("/usr/share/locale/ko_KR.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=29938, ...}) = 0 mmap(NULL, 29938, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9ca6234000 close(3) = 0 write(2, "chroot: ", 8chroot: ) = 8 write(2, "cannot change root directory to "..., 57cannot change root directory to /a_chroot_test01/bin/bash) = 57 open("/usr/share/locale/ko_KR.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko_KR/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/ko/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) write(2, ": Not a directory", 17: Not a directory) = 17 write(2, "\n", 1 ) = 1 close(1) = 0 close(2) = 0 exit_group(125) = ? +++ exited with 125 +++