Chroot 簡介

remotesupport發表於2015-01-08

chroot,既是Linux的一條命令,也是它的一個系統呼叫。它的作用就是就是改變當前環境的根目錄到一個資料夾,這個資料夾之外的東西,對於當前環境都是不可見的。因此若是執行不信任的程式碼或程式,使用chroot作為一個安全沙箱是個很好的選擇。這裡我們簡單介紹一下使用chroot的方法和需要注意的問題,並提供一些跳出chroot環境的方法。

Chroot命令

chroot(1)這條命令在大多數Unix/Linux系統中都能找到。它的作用是將根目錄改變到一個新資料夾下並且執行一個shell。因此它要求這個新資料夾下至少有一個可執行的shell。其實大多數情況下,chroot後的資料夾結構都類似於一個小型的Linux系統,例如下面有lib、usr、bin等資料夾。這裡我們介紹怎樣建立一個最小的環境來使用chroot命令。

首先,我們希望這個資料夾的結構是類似於Linux基本的系統結構,這樣chroot後的環境可以作為一個基本的Linux環境來使用。所以用下面的命令先建立一些新資料夾:

mkdir newroot
cd newroot
mkdir bin
mkdir lib
mkdir usr
mkdir usr/bin
mkdir usr/lib

這樣就建立了一些必須的資料夾。其中bin和usr/bin是放二進位制檔案的,而lib和usr/lib是存放連結庫檔案。

前面說過了,chroot後的環境至少需要一個可以執行的shell,我們可以直接將自己系統中的bash拷貝過去。一般bash都在/bin資料夾下,如果不能確定,可以使用下面的命令來查詢:

whereis bash

然後將bash拷貝到新目錄中的相應位置:

cp /bin/bash bin

只拷貝這一個檔案是不夠的,因為一般來說,bash這個程式是通過動態連結來編譯的,所以我們要將所包含的庫檔案也拷貝過去。使用ldd(1)命令可以檢視bash所需要的庫檔案:

ldd /bin/bash

在我的系統中這條命令的輸出是:

    linux-vdso.so.1 =>  (0x00007fff46bff000)
    libreadline.so.6 => /lib/libreadline.so.6 (0x00007fca39fa9000)
    libncursesw.so.5 => /usr/lib/libncursesw.so.5 (0x00007fca39d4c000)
    libdl.so.2 => /lib/libdl.so.2 (0x00007fca39b48000)
    libc.so.6 => /lib/libc.so.6 (0x00007fca397a7000)
    /lib/ld-linux-x86-64.so.2 (0x00007fca3a1ef000)

然後根據輸出來拷貝庫檔案到相應的資料夾:

cp /lib/libreadline.so.6 lib
cp /usr/lib/libncursesw.so.5 usr/lib
cp /lib/libdl.so.2 lib
cp /lib/libc.so.6 lib
cp /lib/ld-linux-x86-64.so.2 lib

這樣就可以使用chroot命令來chroot到新目錄了(需要root許可權):

chroot . /bin/bash

chroot引數的詳細作用可以使用man chroot命令來檢視。在chroot之後,我們可以隨便輸入一些命令,可以發現很多在新環境中是沒有的。而一直執行cd ..的命令,也只能在newroot這個資料夾中。然而在新環境中來開,newroot就是根目錄。

顯然單純這樣的一個環境是沒有多大用途的。在新環境中需要什麼軟體和工具,可以仿照上面移植bash的方法,來配置到新環境中。如果需要一個比較全面的shell環境,可以考慮使用busybox。

使用這種方法來chroot除了可以執行不受信任的程式碼之外,還可以作為一個編譯環境來免受外部環境的汙染,例如LFS(Linux From Scrach)中的用法。