计算机系统应用教程网站

网站首页 > 技术文章 正文

Linux隔离技术-CHROOT

btikc 2025-01-18 17:37:04 技术文章 24 ℃ 0 评论

因为前段时间用docker部署了一套elk系统,深感容器技术“一次封装,到处运行”的方便之处,因此就想把自己做的一个小工具做成容器镜像,但我那个小工具是Python做的,还同时调用了一些与系统相关的命令,安装了一些第三方的小工具,因此就涉及到需要将这些东西都分离出来,并能在一个相对隔离的环境中能够运行,这就是出现这一篇文章出现的原因。

关于隔离环境--CHROOT

chroot - change root, 主要是将程序运行环境切换到指定目录。什么是将运行环境切换到指定目录呢,就是切换过去之后,在应用程序内,根目录“/”的位置变成了你指定的目录了,这样一来,就要求你的目录下必须包括程序的所有依赖环境,比如程序调用的系统命令(及其依赖项),系统调用的动态链接库等。

建立CHROOT环境

检查需要在CHROOT下运行程序的依赖库

为了检测我们的程序调用了哪些动态链接库,我们可以使用ldd命令,例如:

ldd /bin/bash

该命令会运行某个/bin/bash文件,并追踪该文件加载的动态链接库,*.so文件。

P.S. ldd命令是一个脚本文件,经过查看,发现其本质是通过调用bash内置的eval命令,追踪其调用的动态链接库。上述命令实际上就等价于:

eval LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=1 /bin/bash

在系统上缺少ldd命令时,可以执行此命令,如果此命令查找的依赖项不全,还可以通过以下命令检查在内存中正常运行程序所加载的动态库

pmap $PID
lsof -p $PID

P.S. 以上分析都会使程序运行并加载到内存中,对于未知程序来说具有较高的风险性,针对未知程序来说,一般建议使用readelf, nm, objdump之类的反编译工具。不过通过这种方式获取到的依赖结果不是特别完整就是了。

我们将依赖文件拷贝到CHROOT的目录下

mkdir -p $DIR/lib64cp -pfL /lib64/xxx.so.y $DIR/lib64/

构建部分所需的设备文件(一般来说不需要,但对于一些访问系统底层功能的应用可能会用到,比如常见的真随机数设备/dev/random)

ls -l /dev/{random,stdin,stdout,stderr,tty} #查看设备文件类型及主次设备号

按照同样的配置权限、类型、主次设备号构建

mknod -m 666 random c 1 8 

该命令创建random设备文件,模式为rw-rw-rw, 设备类型为c(CHAR),主设备号1,次设备号8,可通过ls -l /dev/random 查看

注:实测貌似/dev/stdin, stdout, stderr貌似不需要创建

二、以指定目录为根目录并快速创建CHROOT环境

不管是常见的包管理工具,还是系统自带的rpm工具,都能以指定目录为根目录安装软件包。并在指定目录下释放相关文件。

使用rpm工具

rpm --root=/opt/c-root -ivh xxxx.rpm

如果不检查依赖,则加上 --nodeps 参数

使用yum包管理

yum --installroot=/opt/c-root/ install package-name

这个就比较厉害了,会将软件包相关文件及其依赖项安装到特定目录,这里是/opt/c-root/,这样,通常情况下,直接就能以chroot方式运行了。

编译安装

./configure --prefix=/opt/c-root

默认情况下会将文件编译安装到/usr目录下

通过busybox快速获得一个虚拟环境

yum --installroot=/opt/c-root install busyboxcd /opt/c-root/sbinln -s busybox lnln -s busybox shln -s busybox clear....chroot /opt/c-root sh

解析出程序依赖项后,只需要将相关文件封装进以当前运行的操作系统版本的基础docker镜像,然后写好启动命令即可。当然理论比较简单,实际操作起来就是另一回事了。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表