Skip to content

chroot&bwrap

chroot顾名思义,change root,就是修改挂载点;bwrap则是:bubble wrap 这两个应用为容器(docker, flatpak)技术服务,我们分开来介绍:

chroot

本质是一个系统调用,他会将进程即子进程的"/"重定向到指定的路径下。 这是一个非常危险的操作,所以该操作要求CAP_SYS_CHROOT权限(必须是root)

bwrap

chroot需要root权限,且不够安全,bwrap应用而生;它挂载了命名空间(NameSpace),所以需要用户具备创建命名空间的能力,而现代Linux系统通常允许普通用户这么做。

关于命名空间,user和root账户实际使用同一个,全局的初始的User Namespace,在该空间中,UID-0是特权,1000是平民,所以bwrap实际上请求了一个新的User Namespace,将你映射为了新space的root,这是为了让进程有挂载文件系统的能力,接下来..

透过User Namespace,你可以弄个新家:通过Mount Namespace,然后在内存中创造新的tmpfs,并将其作为新根,然后将宿主的必要部分(/usr, /lib64)挂载到新根下。

  • /usr下的内容只读挂载到容器中的/usr
  • /home/app/app则读写挂载到容器中的/app

然后使用pivot_root(NEW_ROOT, NEW_ROOT/old_root),将进程的根目录编程新根,再然后umount -l /old_root,现在旧根彻底不可见了。

可以做一些实验

shell
bwrap --dev-bind / / --unshare-user --uid 0 bash -c '
    echo "----------------Container Inside----------------"
    echo "Container User: $(whoami)"
    echo "Container UID:  $(id -u)"
    echo "Real access test: Try to touch a file in /root"
    touch /root/hacker_test 2>&1 || echo "Failed! Correct behavior."
'

知识在于积累