大家好,欢迎来到IT知识分享网。
 
转载: 理解 chroot
什么是 chroot
 chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 /,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 / 位置。
为何使用 chroot
 在经过 chroot 之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件,因此它带来的好处大致有以下3个:
chroot 的使用
 为了更好的理解 chroot 发挥的作用,我们将尝试指定一个特定的位置进行根目录切换。但是由于在经过 chroot 之后,系统读取到的 bin/ 等与系统相关目录将不再是旧系统根目录下的,而是切换后新根下的目录结构和文件,因此我们有必要准备一些目录结构以及必要的文件。
清单 1. 准备切换的目录结构
 
    
    -  
      
       
      
      
      
        $ pwd 
       
     
  
    -  
      
       
      
      
       
       /home 
       /wstone 
       /Build 
       /work 
       
     
  
    -  
      
       
      
      
      
        $ tree . 
       
     
  
    -  
      
       
      
      
      
        . 
       
     
  
    -  
      
       
      
      
       
       | 
       -- bin 
       
     
  
    -  
      
       
      
      
       
       | 
       | 
       -- ash -> busybox 
       
     
  
    -  
      
       
      
      
       
       | 
       | 
       -- bash 
       
     
  
    -  
      
       
      
      
       
       | ` 
       -- busybox 
       
     
  
    -  
      
       
      
      
       
       | 
       -- etc 
       
     
  
    -  
      
       
      
      
      
        ` 
       -- newhome 
       
     
  
   
 
   
这里使用了静态编译后的 busybox 来提供必要的命令,使用静态编译仅是为了避免动态库文件的拷贝。当然我们也可以拷贝旧系统的下的命令到新的目录结构中使用,但是那些命令通常是动态编译的,这就意味着我们不得不拷贝相关的动态库文件到相应的目录结构中。同时这里的 bash 也非真正的 Bourne Again shell,而是一个执行 ash 的 shell 脚本。在清单 2中,展示了位于旧系统中的 chroot 命令的使用。需要注意的是在使用 chroot 时,要求拥有相关的操作权限。
在/home/wstone/Build/work 目录下建立一个文件,名为”bash”,内容就两行如下:
 
    
    -  
      
       
      
      
       
       #!/bin/ash 
       
     
  
    -  
      
       
      
      
      
        ash 
       
     
  
   
 
   
这个脚本的第一句表示解析该脚本的解释器( interpreter)所在位置。chroot缺省执行/bin/bash命令。为了要在新的chroot环境下使用ash,所以建立/bin/bash这个用来执行ash的文件。也可以显示的指出要执行的命令,比如要执行ash
 
    
    -  
      
       
      
      
      
        $ 
       pwd 
       
     
  
    -  
      
       
      
      
      
        /home/wstone/Build/work 
       
     
  
    -  
      
       
      
      
       
       $chroot . ./bin/ash 
       
     
  
    -  
      
       
      
      
       
       #pwd 
       
     
  
    -  
      
       
      
      
      
        / 
       
     
  
   
 
   
清单 2. 位于系统中的 chroot 的使用
 
    
    -  
      
       
      
      
      
        $ 
       pwd 
       
     
  
    -  
      
       
      
      
      
        /home/wstone/Build/work 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       # chroot . 
       
     
  
    -  
      
       
      
      
       
       # pwd 
       
     
  
    -  
      
       
      
      
      
        / 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       # ls 
       
     
  
    -  
      
       
      
      
      
        ash: 
       ls: not found 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       # busybox ls 
       
     
  
    -  
      
       
      
      
      
        bin etc newhome 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
      
        3 directories, 3 files 
       
     
  
   
 
   
我们可以看到当前路径(/home/wstone/Build/work/),在经过 chroot 后转变成了 / 目录,同时从新根下读取了与系统相关的目录结构。使用 ls 命令失败是由于我们创建的测试目录结构中并没有包含命令 ls,但是我们成功的使用了 busybox 中的 ls。以上看到的只是 chroot 的一种使用方式,其实标准的 chroot (Coreutils – GNU core utilities 提供的 chroot)使用方式有2种:
清单 3. 标准 chroot 的2种使用方式
 
    
    -  
      
       
      
      
       
       [1] chroot NEWROOT 
       [COMMAND...] 
       
     
  
    -  
      
       
      
      
       
       [2] chroot OPTION 
       
     
  
   
 
   
刚才我们使用的是方式[2]。这将在没有给定环境时,默认执行 /bin/sh,但是当给定环境后,将运行 ${SHELL} –i,即与环境相同的可交互的 shell。我们的目录结构中并没有包含sh,显然清单 2中的 chroot 运行了 ${SHELL} –i。当然我们也可以在进行切换时指定需要的命令,即使用方式[1]。
清单 4. chroot 另一种方式的使用
 
    
    -  
      
       
      
      
       
       # chroot . /bin/ash 
       
     
  
    -  
      
       
      
      
       
       #  
       
     
  
   
 
   
在清单 4 中,尝试了在经过 chroot 后,执行新目录结构下的 ash shell。不得不说的是,如果新根下的目录结构和文件准备的够充分,那么一个新的简单的 Linux 系统就可以使用了。其实更为常见的是在初始 RAM 磁盘 (initrd)中使用 chroot,以此来执行系统的 init。清单 5 中,展示的是在 Linux 2.4 内核 initrd 中使用 chroot。
清单 5. 在 Linux 2.4 内核 initrd 中使用 chroot 的示例
 
    
    -  
      
       
      
      
      
        mount /dev/hda1 /new-root 
       
     
  
    -  
      
       
      
      
       
       cd /new-root 
       
     
  
    -  
      
       
      
      
      
        pivot_root . old-root 
       
     
  
    -  
      
       
      
      
       
       exec 
       chroot . /sbin/init <dev/console >dev/console 2>&1 
       
     
  
    -  
      
       
      
      
      
        umount /old-root 
       
     
  
   
 
   
由于 Linux 内核的升级,initrd 处理机制和格式发生了变化,在 Linux 2.6 内核 initrd 中不能再使用 pivot_root,因此一般也不再使用 chroot,而是选择使用 busybox 提供的 switch_root 或者 klibc 提供的 run-init 进行根目录的切换。(这并不是说不能在 Linux 2.6内核 initrd 中使用 chroot,选择 switch_root 或 run-init 仅是出于习惯和方便的考虑。)但是实质上,它们仅是将 chroot 的功能进行了封装,以此更加方便简单的切换根目录。
清单 6. 在 Linux 2.6 内核 initrd 中 chroot 的使用
 
    
    -  
      
       
      
      
      
        [1] find -xdev / - 
       exec 
       rm 
       '{}' 
       '; 
       
     
  
    -  
      
       
      
      
       
       [2] cd /newmount; mount --move . /; chroot . 
       
     
  
   
 
   
上面介绍了 chroot 及其使用,但是编写一个简单的 chroot 并不复杂,下面我们就尝试编写chroot 以此来更好的认识 chroot 的处理过程,先编写一个粗略的 chroot 然后再完善它的功能。chroot 的编写涉及了2个函数,chroot() 以及 chdir(),它们都包含在 unistd.h 头文件中。
清单 7. 编写 chroot 涉及的2个函数
 
    
    -  
      
       
      
      
       
       #include <unistd.h> 
       
     
  
    -  
      
       
      
      
       
       int chroot(const char *path); 
       
     
  
    -  
      
       
      
      
       
       int chdir(const char *path); 
       
     
  
   
 
   
chroot() 将切换参数 path 所指位置为根目录 (/),chdir() 用来将当前的工作目录改变成以参数path 所指的目录。以此我们可以编写一个非常粗略的 chroot。
清单 8. 粗略的 chroot
 
    
    -  
      
       
      
      
       
       #include <unistd.h> 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       int main(int argc, char *argv[]) 
       
     
  
    -  
      
       
      
      
      
        { 
       
     
  
    -  
      
       
      
      
       
       chroot( 
       "."); 
       
     
  
    -  
      
       
      
      
       
       chdir( 
       "/"); 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       char *arrays[]={ 
       "ash", 
       NULL}; 
       
     
  
    -  
      
       
      
      
       
       execvp( 
       "ash", arrays); 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       return 
       0; 
       
     
  
    -  
      
       
      
      
      
        } 
       
     
  
   
 
   
这个粗略的 chroot 仅能切换当前位置为根目录,同时默认执行 ash shell,不包含任何的错误处理及警告。编写并保存代码为 test.c。在清单 9 中,展示了这个粗略 chroot 的使用情况,成功的进行了根目录的切换。
清单 9. 粗略 chroot 的使用
 
    
    -  
      
       
      
      
      
        $ gcc -Wall test.c -o 
       test 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       # ./test 
       
     
  
    -  
      
       
      
      
       
       # ls 
       
     
  
    -  
      
       
      
      
      
        ash: 
       ls: not found 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       # busybox ls 
       
     
  
    -  
      
       
      
      
      
        bin etc newhome 
       test test.c 
       
     
  
   
 
   
下面给出功能将近完整的 chroot ,加上了一些错误处理并新增了可执行指定命令的功能。当在没有给出 chroot 切换后要执行的命令时,默认执行 /bin/sh,同时检测环境以确认使用何种 shell。
清单 10. 功能完整的 chroot
 
    
    -  
      
       
      
      
       
       #include <stdio.h> 
       
     
  
    -  
      
       
      
      
       
       #include <unistd.h> 
       
     
  
    -  
      
       
      
      
       
       #include <stdlib.h> 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       int main(int argc, char *argv[]) 
       
     
  
    -  
      
       
      
      
      
        { 
       
     
  
    -  
      
       
      
      
       
       if(argc< 
       2){ 
       
     
  
    -  
      
       
      
      
       
       printf( 
       "Usage: chroot NEWROOT [COMMAND...] \n"); 
       
     
  
    -  
      
       
      
      
       
       return 
       1; 
       
     
  
    -  
      
       
      
      
      
        } 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       printf( 
       "newroot = %s\n", argv[ 
       1]); 
       
     
  
    -  
      
       
      
      
       
       if( 
       chroot(argv[ 
       1])) { 
       
     
  
    -  
      
       
      
      
       
       perror( 
       "chroot"); 
       
     
  
    -  
      
       
      
      
       
       return 
       1; 
       
     
  
    -  
      
       
      
      
      
        } 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       if( 
       chdir( 
       "/")) { 
       
     
  
    -  
      
       
      
      
       
       perror( 
       "chdir"); 
       
     
  
    -  
      
       
      
      
       
       return 
       1; 
       
     
  
    -  
      
       
      
      
      
        } 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       if(argc == 
       2) { 
       
     
  
    -  
      
       
      
      
      
        argv[ 
       0] = 
       getenv( 
       "SHELL"); 
       
     
  
    -  
      
       
      
      
       
       if(!argv[ 
       0]) 
       
     
  
    -  
      
       
      
      
      
        argv[ 
       0] = ( 
       char *) 
       "/bin/sh"; 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
      
        argv[ 
       1] = ( 
       char *) 
       "-i"; 
       
     
  
    -  
      
       
      
      
      
        argv[ 
       2] = 
       NULL; 
       
     
  
    -  
      
       
      
      
      
        } 
       else { 
       
     
  
    -  
      
       
      
      
      
        argv += 
       2; 
       
     
  
    -  
      
       
      
      
      
        } 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       execvp (argv[ 
       0], argv); 
       
     
  
    -  
      
       
      
      
       
       printf( 
       "chroot: cannot run command `%s`\n", *argv); 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       return 
       0; 
       
     
  
    -  
      
       
      
      
      
        } 
       
     
  
   
 
    
   
保存以上代码为 newchroot.c 文件,编译后运行测试其功能。最后要指出的是,本文中的 chroot 并没有使用静态编译。如果有必要(如,在 initrd 中使用 chroot),chroot 应该使用静态编译,若是使用动态编译,那么要拷贝相关的动态库文件到相应目录结构中。
清单 11. newchroot 的测试
 
    
    -  
      
       
      
      
       
       $ gcc -Wall newchroot.c -o newchroot 
       
     
  
    -  
      
       
      
      
       
       
     
  
    -  
      
       
      
      
       
       # ./newchroot . /bin/ash 
       
     
  
    -  
      
       
      
      
      
        newroot = . 
       
     
  
    -  
      
       
      
      
       
       # 
       
     
  
   
 
   
——————————————————————-
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来找出来。 
  
通过Chroot机制让服务器安全到底
所谓“监牢“就是指通过chroot机制来更改某个进程所能看到的根目录,即将某进程限制在指定目录中,保证该进程只能对该目录及其子目录的文件有所动作,从而保证整个服务器的安全。
创建chroot”监牢“
以前,Unix/Linux上的daemon都是以root权限启动的。当时,这似乎是一件理所当然的事情,因为像Apache这样的服务器软件需要绑定到“众所周知“的端口上(小于1024)来监听HTTP请求,而root是惟一有这种权限的用户。
但是,随着攻击者活动的日益频繁,尤其是缓冲区溢出漏洞数量的激增,使服务器安全受到了更大的威胁。一旦某个网络服务存在漏洞,攻击者就能够访问并控制整个系统。因此,为了减缓这种攻击所带来的负面影响,现在服务器软件通常设计为以root权限启动,然后服务器进程自行放弃root,再以某个低权限的系统账号来运行进程。这种方式的好处在于一旦该服务被攻击者利用漏洞入侵,由于进程权限很低,攻击者得到的访问权限又是基于这个较低权限的,对系统造成的危害比以前减轻了许多。
有些攻击者会试图找到系统其它的漏洞来提升权限,直至达到root。由于本地安全性远低于远程安全保护,因此攻击者很有可能在系统中找到可以提升权限的东西。即使没有找到本地漏洞,攻击者也可能会造成其它损害,如删除文件、涂改主页等。
为了进一步提高系统安全性,Linux内核引入了chroot机制。chroot是内核中的一个系统调用,软件可以通过调用库函数chroot,来更改某个进程所能见到的根目录。比如,Apache软件安装在/usr/local/httpd/目录下,以root用户(或具有相同权限的其它账号)启动Apache,这个root权限的父进程会派生数个以nobody权限运行的子进程,具体情况取决于个人设置。父进程监听请求自80端口的tcp数据流,然后根据内部算法将这个请求分配给某个子进程来处理。这时Apache子进程所处的目录继承自父进程,即/usr/local/httpd/。
但是,一旦目录权限设定失误,被攻击的Apache子进程可以访问/usr/local、/usr、/tmp,甚至整个文件系统,因为Apache 进程所处的根目录仍是整个文件系统的根。如果能够利用chroot将Apache限制在/usr/local/httpd/,那么,Apache所能存取的文件都是/usr/local/httpd/下的文件或其子目录下的文件。创建chroot”监牢“的作用就是将进程权限限制在文件系统目录树中的某一子树中。
为什么需要jail
将软件chroot化的一个问题是该软件运行时需要的所有程序、配置文件和库文件都必须事先安装到chroot目录中,通常称这个目录为 chroot jail(chroot”监牢“)。如果要在“监牢“中运行/sbin/httpd,而事实上根本看不到文件系统中那个真正的/sbin目录。因此需要事先创建/sbin目录,并将httpd复制到其中。同时httpd需要几个库文件,执行如下命令可以看到这些库文件(在真实的文件系统下运行)。
#ldd /sbin/httpd
 libaprutil-0.so.0 => /usr/local/httpd/lib/libaprutil-0.so.0 (0x)
 libgdbm.so.2 => /usr/lib/libgdbm.so.2 (0x4003c000)
 libdb-4.0.so => /lib/libdb-4.0.so (0x)
 libpthread.so.0 => /lib/tls/libpthread.so.0 (0x400eb000)
 libexpat.so.0 => /usr/lib/libexpat.so.0 (0x400f8000)
 libapr-0.so.0 => /usr/local/httpd/lib/libapr-0.so.0 (0x)
 librt.so.1 => /lib/librt.so.1 (0x)
 lIBM.so.6 => /lib/tls/lIBM.so.6 (0x4014b000)
 libcrypt.so.1 => /lib/libcrypt.so.1 (0x4016d000)
 libnsl.so.1 => /lib/libnsl.so.1 (0x4019a000)
 libdl.so.2 => /lib/libdl.so.2 (0x401af000)
 libc.so.6 => /lib/tls/libc.so.6 (0x)
 /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x)
这意味着还需要在“监牢“中创建lib目录,并将库文件复制到其中。这一工作可以交由计算机完成,用jail等软件包来帮助简化chroot”监牢“建立的过程。
编译和安装jail
从http://www.jmcresearch.com/static/dwn/projects/jail/jail.tar.gz可以下载到jail的最新版本,它是由位于http://www.jmcresearch.com/projects/jail/的jail chroot项目小组开发的。该软件包包含了帮助自动创建chroot”监牢“的C程序、Perl程序和Bash脚本。
首先将jail.tar.gz置于任意目录,然后执行命令:
#tar xzvf jail.tar.gz && cd jail/src
按照个人实际情况修改makefile文件,尤其是安装路径(默认安装路径是/usr/local)、体系结构(jail支持Linux、FreeBSD、IRIX和Solaris),以及编译选项等。最后执行命令:
#make && make install
为jail创建chroot”监牢“
现在创建一个目录作为chroot”监牢“,以/var/chroot/为例。执行下面的命令为chroot”监牢“创建环境:
#/usr/local/bin/mkjailenv /var/chroot
这样“监牢“就建好了。jail软件包提供了几个Perl脚本作为其核心命令,包括mkjailenv、addjailuser和 addjailsw。如addjailsw会从真实文件系统中拷贝二进制可执行文件及其相关的其它文件(包括库文件、辅助性文件和设备文件)到该“监牢” 中。
为jail”监牢“添加软件
接下来需要为这个“监牢“增加一些软件,以便让它运行起来。执行以下命令安装一些基本的软件,包括ls、cat、cp等程序和ld-linux.so.2等库文件。
#/usr/local/bin/addjailsw /var/chroot
事实上仅有这些基本软件是不够的,还需要把一些真正有用的东西限制起来。下面的例子展示了为“监牢“添加arp程序的过程:
#/usr/local/bin/addjailsw /var/chroot -P arp
addjailsw
 A component of Jail (version 1.9 for linux)
http://www.jmcresearch.com/projects/jail/
 Juan M. Casillas <juanm.casillas@jmcresearch.com>
Guessing arp args(0)
 Warning: file .//lib/tls/libc.so.6 exists. Overwritting it
 Warning: file .//lib/ld-linux.so.2 exists. Overwritting it
 Warning: file .//etc/ld.so.cache exists. Overwritting it
 Warning: file .//usr/lib/locale/locale-archive exists. Overwritting it
 Warning: file .//usr/share/locale/locale.alias exists. Overwritting it
 Warning: can’t create /proc/net/arp from the /proc filesystem
Done.
再以Apache服务器软件为例:
#addjailsw /var/chroot/ -P /usr/local/httpd/bin/httpd
addjailsw
 A component of Jail (version 1.9 for linux)
http://www.jmcresearch.com/projects/jail/
 Juan M. Casillas <juanm.casillas@jmcresearch.com>
Guessing /usr/local/httpd/bin/httpd args(0)
 Warning: file /var/chroot//lib/libssl.so.4 exists. Overwritting it
 Warning: file /var/chroot//lib/libcrypto.so.4 exists. Overwritting it
 Warning: file /var/chroot//lib/libresolv.so.2 exists. Overwritting it
 ……
Done.
不用在意那些警告信息,因为jail会调用ldd检查httpd用到的库文件。而几乎所有基于共享库的二进制可执行文件都需要上述的几个库文件。
接下来将Apache的相关文件拷贝到“监牢“中:
#cp -a /usr/local/httpd/ /var/chroot/usr/local/
可根据个人情况依次将Apache需要的文件复制到“监牢“中。
“监禁“囚犯
有时候需要为chroot”监牢“创建新的用户,比如Apache要求创建nobody用户作为子进程用户。鉴于可能有其它进程使用nobody,还可以使用另一用户——httpd。首先需要在真实系统中创建httpd用户:
#useradd -d /var/chroot -s /usr/local/bin/jail httpd
然后执行以下命令在chroot”监牢“中创建httpd用户:
#/usr/local/bin/addjailuser /var/chroot /usr/local/httpd /usr/sbin/httpd httpd
接下来修改/var/chroot/usr/local/httpd/conf/httpd.conf,将User nobody替换为User httpd。由于chroot后Apache将以httpd身份启动进程,只有root有权将Apache绑定在低端口上(通常为80),因此还需要修改端口值,该值必须大于1024(假设为8080)。这个修改要应用到Apache的所有配置文件中,包括虚拟主机的配置。至于Apache的其它设置,与在真实文件系统时一样配置即可。
接下来需要复制一些其它的文件。启动Apache最常见的方式就是调用apachectl,这是个Bash脚本。查看这个文件,会发现如下行:
HTTPD=’/usr/local/httpd/bin/httpd’
 LYNX=”lynx -dump” 
 ULIMIT_MAX_FILES=”ulimit -S -n `ulimit -H -n`”
 ARGV=”-h”
 $HTTPD -k $ARGV
 $HTTPD -k start -DSSL
 $HTTPD -t
 $LYNX $STATUSURL | awk ‘ /process$/ { print; exit } { print } ‘
其中ulimit、lynx和awk是辅助性的程序。另外需要注意的是,程序使用不同的参数时,可能会使用不同的库文件,因此为了让Apache完整运行,使用下面的命令来跟踪所有可能的文件:
#/usr/local/bin/addjailsw /var/chroot -P httpd “-k start -DSSL”
用上述的参数替换引号中的参数,完成全部的工作。
最后,让成功jail的Apache运行起来:
#su – httpd &
打开浏览器进行测试,访问Web服务器时记住加上8080端口号。
jail高级应用
在前面的介绍中,使用了jail软件包中的三个Perl脚本。这里详细介绍这三个脚本的使用,以便高级用户使用。
mkjailenv
 用法:mkjailenv chrootdir
 作用:创建chroot”监牢“目录,并且从真实文件系统中拷贝基本的软件环境。
 参数:
chrootdir指定chroot”监牢“的路径。
addjailsw
 用法:addjailsw chrootdir [-D] [-P program args]
 作用:从真实文件系统中拷贝指定的文件及其相关文件。
 参数:
chrootdir指定chroot”监牢“的路径。
-D显示详细信息。
-P program args指定要添加到“监牢“中的软件。program可以是个文件名,也可以是文件的完整路径;args是参数。比如可以这样执行addjailsw:
#addjailsw /var/chroot -P vi “-c q”
addjailuser
 用法:addjailuser chrootdir userdir usershell username
 作用:创建新的chroot”监牢“用户。
 参数:
chrootdir指定chroot”监牢“的路径。
userdir指定新添加用户的主目录(相对于chroot”监牢“目录)。
usershell指定新用户使用的Shell的完整路径(比如/bin/bash)。
username为新添加的用户名。
这个脚本会自动修改“监牢“中的/etc/passwd、/etc/group和/etc/shadow文件。
从上文看,如果仅使Apache一个软件运行在“监牢“中,mkjailenv似乎过于“热心“了,因此可以不运行mkjailenv /var/chroot命令,而只运行addjailsw /var/chroot -P httpd或在调试完chroot”监牢“后删除多余的文件,并修改/etc/passwd中多余的用户信息。由此想到,现在大多数流行的Web站点都采用Apache+PHP+MySQL+SSL的搭配(可能还会有FTP、Mail、Perl等组件),因此完全可以建立一个综合的Web”监牢“。系统管理员可以为这个“监牢“设置软件环境,当然这个环境只包括维护Apache+PHP+MySQL+SSL这些组件的必备工具,如使用Bash、SSH、编译软件或上传等。这可能是一个浩大的工程,但是却非常有意义。参考上面的方法,大家可以尝试jail出完美的服务器来。
转自:chroot命令
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120551.html
                