chroot 与 jail

2024-04-30 14:38
文章标签 chroot jail

本文主要是介绍chroot 与 jail,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   http://www.cnblogs.com/yxwkf/p/3902433.html

 

所谓“监牢”就是指通过chroot机制来更改某个进程所能看到的根文件夹,即将某进程限制在指定文件夹中,保证该进程仅仅能对该文件夹及其子文件夹的文件有所动作,从而保证整个server的安全。

    创建chroot“监牢”

    曾经,Unix/Linux上的daemon都是以root权限启动的。当时,这似乎是一件理所当然的事情,由于像Apache这种server软件须要绑定到“众所周知”的port上(小于1024)来监听HTTP请求,而root是惟一有这种权限的用户。

    可是,随着攻击者活动的日益频繁,尤其是缓冲区溢出漏洞数量的激增,使server安全受到了更大的威胁。一旦某个网络服务存在漏洞,攻击者就行訪问并控制整个系统。因此,为了减缓这样的攻击所带来的负面影响,如今server软件通常设计为以root权限启动,然后server进程自行放弃root,再以某个低权限的系统账号来执行进程。这样的方式的优点在于一旦该服务被攻击者利用漏洞入侵,因为进程权限非常低,攻击者得到的訪问权限又是基于这个较低权限的,对系统造成的危害比曾经减轻了很多。

    有些攻击者会试图找到系统其他的漏洞来提升权限,直至达到root。因为本地安全性远低于远程安全保护,因此攻击者非常有可能在系统中找到能够提升权限的东西。即使没有找到本地漏洞,攻击者也可能会造成其他损害,如删除文件、涂改主页等。

    为了进一步提高系统安全性,Linux内核引入了chroot机制。chroot是内核中的一个系统调用,软件能够通过调用库函数chroot,来更改某个进程所能见到的根文件夹。比方,Apache软件安装在/usr/local/httpd/文件夹下,以root用户(或具有同样权限的其他账号)启动Apache,这个root权限的父进程会派生数个以nobody权限执行的子进程,详细情况取决于个人设置。父进程监听请求自80port的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 (0x40017000)
libgdbm.so.2 => /usr/lib/libgdbm.so.2 (0x4003c000)
libdb-4.0.so => /lib/libdb-4.0.so (0x40043000)
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 (0x40118000)
librt.so.1 => /lib/librt.so.1 (0x40139000)
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 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

    这意味着还须要在“监牢”中创建lib文件夹,并将库文件拷贝到当中。这一工作能够交由计算机完毕,用jail等软件包来帮助简化chroot“监牢”建立的过程。

 

 

 

简单介绍一下 chroot 命令的应用(分享)

chroot 在 Linux 系统中发挥了根目录的切换工作,

同时带来了系统的安全性等好处。chroot,

即 change root directory (更改 root 目录)。

在 linux 系统中,系统默认的目录结构都是以 `/`,即是以根 (root) 开始的。

而在使用 chroot 之后,系统的目录结构将以指定的位置作为 `/` 位置。

比 如你希望你的朋友可以远程登录你的机器,

但是当然不想让他能够运行你机器中大部分的命令,

只是让他运行你觉得没问题的命令。

具体来说想把他的访问局限在 /usr/chroot中

让他觉得 /usr/chroot就是根目录( / ),这时候就需要用到chroot命令,


  1.  建一个文件夹,

  # mkdir /usr/chroot

  当你此时想用 # chroot /usr/chroot 命令时,你会发现出现错误:

chroot: cannot run command `/bin/bash': No such file or directory

  所以在使用 chroot命令之前是需要 把 bash 移到 /usr/chroot/bin中的

  2. 再建 bin etc lib var home等文件夹

  # mkdir bin etc lib var home

  然后就可以先把 bash 复制过去了, 但是在此之前,还需要做的一件事就是用 ldd 来调查 bash 对各种文件的依赖关系

  3. # ldd /bin/bash

    linux-gate.so.1 =>  (0x00110000)

    libncurses.so.5 => /lib/libncurses.so.5 (0x00b9f000)

    libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x004fe000)

    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00208000)

    /lib/ld-linux.so.2 (0x00491000)

  然后将 /lib/libncurses.so.5,/lib/tls/i686/cmov/libdl.so.2,

  /lib/tls/i686/cmov/libc.so.6这几个文件复制到/usr/chroot/lib中
  
4. 再将 bash 复制到 /usr/chroot中

  # cp /bin/bash /usr/chroot/bin


  5. 好了,这时候 就可以使用 chroot

  # chroot /usr/chroot

  /usr/chroot就变成了 / , prompt也变了, 我的变成了bash-4.1#

但是现在下面一条命令也没有,可以按照上面的步骤添加各种命令ls, pwd ,cd ,mv之类

好了,就这么多。一些具体的应用以后慢慢再来。

 

Chroot 简介

 

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)中的用法。

chroot函数

很多语言都提供chroot这个函数,以在程序中使用chroot环境。我们主要介绍C语言当中的。其实chroot(1)这条命令,就用到了chroot这个函数。

chroot的使用方法很简单,函数原型是int chroot(const char *path)。需要root权限来使用。详细信息可以使用man 2 chroot命令查看。

下面是一个很简单的chroot程序示例:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char *argv[])
{chroot(".");chdir("/");execvp("/bin/bash", NULL);
    return 0;
}

这段代码的功能就是chroot到当前目录下并且打开bash这个shell。需要注意的是,上面这段代码除了没有错误提示之外,还是很危险的!因为运行它就必须给用户root权限,而在以root权限chroot之后,并没有收回权限就打开了一个shell让用户操作。我们后面可以看到,用一段很简单的代码就可以轻易的跳出这个chroot环境。正确的做法是,在chroot之后使用setuid,使当前用户变成一个权限较低的用户,比如在chroot后添加如下代码:

setuid(1000);

在程序中使用chroot的好处就是不一定非要打开一个shell,需要在chroot环境中使用什么程序,直接用exec函数族来执行就行了。这样有两个好处:(1)只需要在新环境中配置需要运行的程序。如果要执行的程序是静态编译的,那么连链接库文件都不用要了。(2)由于一直是程序在控制运行过程,没有提供shell让用户交互操作,所以安全性相对高一些。

跳出chroot

如果有root权限,可以用很多种方法跳出chroot环境。

在新环境中使用chroot

最简单最通用的方法是在新环境中再使用一下chroot。写一个程序可以轻易的跳出chroot环境。方法如下:

  1. 在当前环境中新建一个文件夹,并chroot到它。
  2. 一直执行“cd ..”,就会回到系统真正的根目录。
  3. chroot到这个真正的根目录。

下面是一个简单的C语言代码示例,我们将它保存为jumpout.c:

//jumpout.c#include <stdio.h>  
#include <unistd.h>  #define TEMP_DIR "temp"  int main()
{  int x;chroot(TEMP_DIR);for(x=0;x<1024;x++)   chdir("..");  chroot(".");  execl("/bin/sh", "-i", NULL);return 0; 
}

现在来体验一下这段代码。首先静态编译(这样编译后的可执行文件就不需要动态链接库的支持了):

gcc --static jumpout.c -o jumpout

然后在newroot下面新建一个名为temp的文件夹:

mkdir temp

这样准备工作就做好了。现在chroot到newroot,然后执行jumpout:

chroot . /bin/bash
./jumpout

可以看到我们现在已经跳出chroot环境了。各种命令都可以使用,并且文件夹也都是真正的根文件夹下的结构。

使用perl等其它语言也可以达到同样的效果。很多服务器都支持CGI脚本,这种攻击不是没有可能。因此在chroot之后处理好权限是非常重要的。

使用mknod(2)

mknod(2)系统调用可以按照自己的需求来新建文件。所以它有可能在硬盘上新建一块有特定目的的代码,来破坏chroot环境。或者新建/dev/mem来改写内核的内存。

找到hard link到chroot环境外的文件

使用ptrace(2)

ptrace(2)是用于跟踪和调试程序系统调用的一个函数,它可以跟踪并且改写程序的信号和系统调用。如果在chroot中有某个程序使用到了chroot之外的一些资源,那么就可以使用ptrace来更改这个程序的系统调用来做一些事情。

安全原则

看到了这么多跳出chroot的方法后,就会发现,如果配置不恰当,chroot环境也不是安全的。因此这里给出一些安全的原则。

  1. 几乎所有的跳出chroot环境的方法都需要root权限。因此再chroot后如果没有特殊需求,一定要放弃root权限。
  2. 如果可能,chroot中的文件和文件夹的所有者最好都是root,并控制好读写权限。
  3. chroot后一定要chdir到新的根目录。
  4. 如果没有必要,不要在chroot环境中使用/etc/passwd文件。
  5. 最好不要链接到chroot环境外的文件。

使用中可能遇到的问题

上面已经把容易出现的问题给说到了。这些问题虽然不大,并且懂了之后也没什么,但是却是很容易困惑新手的一些地方,所以这里突出的提一下:

  1. 无论是chroot命令,还是chroot这个函数,都需要root权限。
  2. chroot这个命令需要在新环境中至少有一个shell程序,包括它用到的库文件。使用ldd可以看到相应的库文件。
  3. chroot后不管运行什么命令和软件,都要保证有相应的库文件。gcc默认是动态编译的,因此如果想在chroot环境中不需要库文件就可以执行编译过的二进制文件,则需要静态编译,即加上“–static”选项。

参考资料

系统自带的手册页是很好的参考资料。详见

man 1 chroot
man 2 chroot

这篇文章中有跳出chroot环境的详细讲解和C语言代码:http://www.bpfh.net/simes/computing/chroot-break.html

这里有一篇非常详尽的讲解:http://www.unixwiz.net/techtips/chroot-practices.html

 

 

 

这篇关于chroot 与 jail的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/949136

相关文章

FreeBSD通过CBSD管理低资源容器jail来安装Ubuntu子系统实践

简介 FreeBSD、CBSD、Jail和Ubuntu,四者的组合方案可以说是强强联合,极具性价比和竞争力!同时安装简单方便,整体方案非常先进。 CBSD是为FreeBSD jail子系统、bhyve、QEMU/NVMM和Xen编写的管理层。该项目定位为一个综合解决方案的单一集成工具,用于使用预定义的软件集以最少的配置快速构建和部署计算机虚拟环境。 FreeBSD jail系统容器本身是

FreeBSD jail虚拟容器里装ubuntu系统没有apt命令怎么办?

问题 在FreeBSD jail里使用linux兼容创建了ubuntu环境,但是没有apt命令,该怎么办呢? jail的介绍:FreeBSD jail 容器手册_freebsd虚拟化-CSDN博客 系统是这样进去的: jexec focal chroot /compat/ubuntu /bin/bash 这个问题很少碰到,大约只有两种情况会碰到:1 FreeBSD jail虚拟容器里装ub

使用AppJail配置网络并创建tiny jail(未成功)

创建tiny jail成功了,但是网络配置这块,jail里只能ping通外面,而无法pkg更新软件。本文章是这篇文章Jail管理器AppJail的使用@FreeBSD-CSDN博客的网络篇。 首先host主机配置pf防火墙 参考这里:Packet Filter - AppJail Handbook  在/etc/rc.conf文件中添加 pf_enable="YES"pflog_enab

vsftp 设置chroot_local_user=yes之后,用户无权限登录

我是在centos7上安装了3.0.2版本的vsftp,为了限制用户不能访问父级目录在vsftpd.conf中加了chroot_local_user=yes,这个配置本来的意思是让所有的用户都不能去访问除了自己的home目录以上的目录,但是加了之后发现之前可能登录的用户提示用户身份校验失败,后来查到原因是新版的vsftpd的以下更新: Add stronger checks for the co

chroot -- 限制其他用户liunx空间

目录- 限制其他用户liunx空间 前言开始进入监狱总结 前言 前提 ecs 服务器,centos系统,乌班图系统需要root榕湖 开始 首先,登录到您的ECS机器。创建一个新用户: 使用 adduser 命令创建一个新用户。例如,要创建一个名为 xushouchun 的用户,您需要运行: sudo adduser xushouchunsudo passwd

vsftpd 报错refusing to run with writable root inside chroot

1、响应:    500 OOPS: vsftpd: refusing to run with writable root inside chroot() 错误:    严重错误: 无法连接到服务器   解决方案:ftp武器根目录必须是755,不能是777权限 而且用户属主必须是root sudo chmod 755 /var/ftp sudo chown root:root /var/

chroot相关

chroot [--help][--version][目的目录][执行指令...] [功能] 把根目录换成指定的目的目录. [描述] ‘chroot’使用一个指定的根目录运行命令,在大多数系统上,仅限于超级用户可以做这个动作。 通常情况下,搜索文件名开始于根目录结构。比如‘/’。‘chroot’命令可以更改根路径到新的指定的路径。 使用chroot,实现了如下等功能: 1).增加了系统的安全性,

500 OOPS: vsftpd: refusing to run with writable root inside chroot() 错误的解决方式

之前在centOS7上搭建好了ftp服务器,然而在用windows的cmd远程登录ftp服务器时却报了一下错误: 网上说什么的都有,最后在/etc/vsftpd/vsftpd.conf配置文件中添加了以下两句终于解决了问题。 chroot_local_user=YES ## 原本就有,取掉注释就好allow_writeable_chroot=YES ## 添加 修改后重启ftp服

Ubuntu下chroot启动MeeGo的XServer(pandaboard)

主要参考http://wiki.meego.com/Hardware-accelerated_graphics_on_Pandaboard_using_MeeGo   (1) 下载ubuntu for omap4 (2) 准备好至少4GB的SD卡(虽然IMG文件只有500多MB,但ubuntu首次启动后会安装很多东西)。 (3) 用"sudo fdisk -ls"确定SD卡被挂载到哪个设备

关于CHROOT的基本常识

CHROOT就是Change Root,也就是改变程式执行时所参考的根目录位置。 一般的目录架构: / /bin /sbin /usr/bin /home CHROOT的目录架构: /hell/ /hell/bin /hell/usr/bin /hell/home * 为何要CHROOT? 1.限制被CHROOT的使用者所能执行的程式,如SetUid的程式,或是会造成 Load 的Compile