什么是chroot

CHROOT就是Change Root,也就是改变程式执行时所参考的根目录位置。 通常的目录架构: 

/bin 
/sbin 
/usr/bin 
/homeshell

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。tcp

所以咱们必须先修改/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了。ide

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。oop

(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。ui

* 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权限。spa

* 结论: code

CHROOT能够增进系统的安全性,限制使用者能作的事,可是CHROOT Is Not Everything,由于仍是有其余的漏洞等著hacker来找出来。