chroot

时间:2023-03-09 02:50:45
chroot

用途:更改命令的根目录。

语法:chroot Directory Command

描述:

注意:如果新根目录中的特殊文件具有与实际根目录不同的主要和次要设备号,则可能会覆盖文件系统。

只有具有 root 用户权限的用户才可以使用 chroot 命令。如果具有 root 用户权限,则 chroot 命令将根目录更改到当执行 Command 时 Directory 参数指定的目录。任何路径名中的第一个 /(斜杠)更改为指定 Command 及其子命令的 Directory。

Directory 路径名始终相对于当前 root。即使 chroot 命令生效,Directory 路径名相对于运行进程的当前 root。

在 chroot 命令运行后,大多数程序可能不能正常运行。例如,如果共享库不在新的 root 文件系统中,则使用共享库的命令将失败。最常用的共享库是 /usr/ccs/lib/libc.a 库。

如果当前 root 用户位置使 /etc/passwd 文件不能到达,则 ls -l 命令不会成功给出用户名和组名。此外,如果文件(/usr/lib/nls/*)不在新的 root 文件系统中,取决于这些本地化文件的实用程序也可能会失败。您的职责是确保所有重要的数据文件都在新的 root 文件系统中,并确保已更改访问此类文件的必要路径名。
参数

Command 指定命令以使用 chroot 命令运行。
Directory 指定新的根目录。

示例

注意:以下示例中的命令可能取决于共享库。在运行 chroot 命令之前,请确保共享库在新的 root 文件系统中。
要运行 pwd 命令将 /usr/bin 目录作为 root 文件系统,请输入:

mkdir /usr/bin/lib
 
cp /usr/ccs/lib/libc.a /usr/bin/lib
 
chroot /usr/bin pwd
要运行 Korn shell 子 shell 将另一个系统文件作为 root 文件系统,请输入:

chroot /var/tmp /usr/bin/ksh

这使目录名 /(斜杠)在 /usr/bin/ksh 命令持续时间指向 /var/tmp。它还使得原始的 root 文件系统不可访问。/var/tmp 文件上的文件系统必须包含 root 文件系统的标准目录。特别是,shell 查找 /var/tmp 文件系统中 /bin 和 /usr/bin 文件中的命令。

运行 /usr/bin/ksh 命令创建作为原始 shell 的单独进程运行的子 shell。 按下 END OF FILE(Ctrl-d)键控顺序以结束子 shell 并返回到您在原始 shell 中的位置。这恢复原始 shell 的环境,包括 .(当前目录)和 /(根目录)的意义。
要创建与原始 root 相关的文件,而非新文件,请输入:

chroot directory Command > file
文件

/etc/passwd 指定包含基本用户属性的文件。
/usr/ccs/lib/libc.a 指定标准 I/O 库和标准 C 库。
/usr/ccs/lib/libcurses.a 指定 curses 库。
/usr/lib/liblvm.a 指定 LVM(逻辑卷管理器)库。
/usr/ccs/lib/libm.a 指定 math 库。
/usr/lib/libodm.a 指定 ODM(对象数据管理器)库。
/usr/sbin/chroot 包含 chroot 命令。

相关信息

ksh 命令和 ls 命令。

chdir 子例程和 chroot 子例程。

什么是CHROOT?

CHROOT就是Change Root,也就是改變程式執行時所參考的根目錄位置。

一般的目錄架構:
/
/bin
/sbin
/usr/bin
/home

CHROOT的目錄架構:
/hell/
/hell/bin
/hell/usr/bin
/hell/home

* 為何要CHROOT?

1.限制被CHROOT的使用者所能執行的程式,如SetUid的程式,或是會造成 Load 的 Compiler等等。

2.防止使用者存取某些特定檔案,如/etc/passwd。
3.防止入侵者/bin/rm -rf /。
4.提供Guest服務以及處罰不乖的使用者。
5.增進系統的安全。

*  要如何建立CHROOT的環境?

1.chroot()這個function:

chroot(PATH)這個function必須具有 root 的身份才能執行,執行後會 將跟目錄切換到 PATH 所指定的地方。

2.login的過程:
  使用者無論是從console或是telnet進入,都必須執行/usr/bin/login來
  決定是否能進入系統,而login所做的動作大致是:
  (1)印出login的提示符號,等待使用者輸入密碼。
  (2)檢查密碼是否正確,錯誤的話回到(1)。
  (3)正確的話以setuid()來改變身份為login_user。
  (4)以exec()執行user的shell。
     因此我們必須先修改/usr/bin/login的source code,讓login在(2)到(3)
     的中間執行chroot($CHROOT_PATH)的動作,已達到CHROOT的目的,並以修
     改過的login替代原先的/usr/bin/login。
  (5)稍微好一點的方法必須在做chroot()之前檢查login
     user的group,如果有某個特定的group(如chrootgrp)
     才執行chroot(),不然所有的人都會被chroot了。

3.建立CHROOT所需的環境:
  (1)必須具備的目錄:(假設$CHROOT為希望建立的路徑)
     $CHROOT/etc  $CHROOT/lib  $CHROOT/bin
     $CHROOT/sbin $CHROOT/usr/lib  $CHROOT/usr/bin
     $CHROOT/usr/bin $CHROOT/usr/local  $CHROOT/home
  (2)仔細審查/etc中的檔案,需具備執行程式時所需的檔
     案,如passwd,groups,hosts,resolv.conf等等。
  (3)拿掉不想給的執行檔,如su,sudo等SetUid的程式,
     以及compiler甚至telnet。
  (4)測試一下,以root身份執行  chroot $CHROOT /bin/sh
     即可進入CHROOT環境中。(man chroot for details)

4.在console或是以telnet進入試試。

5.Username/Password Resolve的考量:
   在CHROOT時你可能不希望被CHROOT的使用者(以後簡
   稱CHROOTer)能拿到/etc/passwd或是/etc/shadow等檔
   案,尤其是有root密碼的。以下有三種情形:
(1)/etc/passwd跟 $CHROOT/etc/passwd相同:
   這是最差的作法,因為一來被CHROOTer有機會得到root
   的encrypted password,二來要保持/etc/passwd及
   $CHROOT/etc/passwd的同步性是個大問題。因為
   /usr/bin/login參考的是/etc/passwd,可是一旦
   CHROOTer被chroot後執行passwd時,他所執行的
   passwd所更改的將是$CHROOT/etc/passwd。
(2)/etc/passwd跟$CHROOT/etc/passwd不同:
   你可以把$CHROOT/etc/passwd中的重要人物(如root)
   的密碼拿掉,然後以比較複雜的方法修改
   /usr/bin/login:
   if (has_chroot_group) {
     re-load $CHROOT/etc/passwd
     if (password is valid) {
        chroot($CHROOT)
        exec(shell)
     } else logout()
   }
   此法的好處是你可以將/etc/passwd跟
   $CHROOT/etc/passwd分開來。/etc/passwd只影響
   CHROOTer在login時所使用的username,其他如
   password甚至uid,gid,shell,home等等都是參
   考$CHROOT/etc/passwd的。
   缺點是你其他的daemon如ftpd,httpd都必須做相同
   的修改才能正確取的CHROOTer的資訊,而且你在把一
   個user加入或移出chroot_group時都必須更改
   /etc/passwd跟$CHROOT/etc/passwd。

(3)使用NIS/YP:
   此法大概是最簡單,且麻煩最少的了。因為一切的user
   information都經過NIS Bind來取得,不但可以保護住
   root的密碼,也省去/etc/passwd跟
   $CHROOT/etc/passwd同步管理上的問題。不只是
   passwd,連其他如groups,hosts,services,
   aliases等等都可以一併解決。

* 其他必須考慮的問題:
1.執行檔的同步性:
  再更新系統或是更新軟體時,必須考慮到一併更換
  $CHROOT目錄下的檔案,尤其如SunOS或是BSD等會用
  nlist()來取得Kernel Information的,在更新kernel
  時必須更新$CHROOT下的kernel。
2./dev的問題:
  一般而言你必須用local loopback NFS將/dev read-
  write mount到$CHROOT/dev以使得一般user跟CHROOTer
  可以互相write以及解決devices同步性的問題。
3./proc的問題:
  在Linux或是SYSV或是4.4BSD的系統上許多程式會去
  參考/proc的資料,你必須也將/proc mount到
  $CHROOT/proc。
4./var的問題:
  一般而言/var也是用local loopback NFS read-write
  mount到$CHROOT/var下,以解決spool同步性的問題,
  否則你可能必須要修改lpd或是sendmail等daemon,
  不然他們是不知道$CHROOT/var下也有spool的存在。
5.Daemon的問題:
  你必須修改一些跟使用者相關的Daemon如ftpd,httpd
  以使這些daemon能找到正確的user home。

* CHROOT無法解決的安全問題:
1.不小心或是忘記拿掉SetUid的程式:
  CHROOTer還是有機會利用SetUid的程式來取得root的
  權限,不過因為你已經將他CHROOT了,所以所能影響到
  的只有$CHROOT/目錄以下的檔案,就算他來個
  "/bin/rm -rf /" 也不怕了。
  不過其他root能做的事還是防不了,如利用tcpdump來
  竊聽該localnet中的通訊並取得在該localnet上其他
  機器的帳號密碼,reboot機器,更改NIS的資料,更改
  其他沒有被CHROOT的帳號的密碼藉以取得一般帳號(所
  以root不可加入NIS中)等等。
  (此時就必須藉由securetty或是login.access或是將
   wheel group拿出NIS來防止其login as root)
2.已載入記憶體中的Daemon:
  對於那些一開機就執行的程式如sendmail,httpd,
  gopherd,inetd等等,如果這些daemon有hole(如
  sendmail),那hacker只要破解這些daemon還是可以取
  得root權限。

* 結論:
   CHROOT可以增進系統的安全性,限制使用者能做的事,
   但是CHROOT Is Not Everything,因為還是有其他的
   漏洞等著hacker來找出來。