有没有非 root 用户下,能创建出一个隔离 rootfs 内的交互式 shell 的轮子

209 天前
 guanzhangzhang

比如 test01 执行个轮子后,进入了一个隔离的 chroot 类似。

主要是 web 上点击提供一个 web shell 类似,里面的 rootfs 带了 kubectl ,目前同事用 webkubectl 项目使用,但是前不久客户让改为非 root 启动。大致看了下它的实现

  1. 特权容器内 root 用户执行 gotty 启动 start-session.sh 作为 pid 为 1 的角色
  2. 每次访问 web 就是执行 start-session.sh 的内容
    1. unshare --fork --pid --mount-proc --mount xxx.sh 启动隔离空间
    2. mkdir -p /nonexistent ,mount -t tmpfs -o size=${SESSION_STORAGE_SIZE} tmpfs /nonexistent 和一系列处理文件
    3. exec su nobody bash

然后改为非 root 启动 gotty 后,没有执行 unshare 和 mount 权限,所以来问下有没有什么轮子,非 root 用户执行,能 chroot 到一个小巧的 rootfs 内的 shell 交互(该 shell 内什么用户都行,对 chroot 之前的无影响)。目前试过 proot ,容器内 root 都无法启动

1863 次点击
所在节点    Linux
29 条回复
vcn8yjOogEL
209 天前
podman?
codehz
209 天前
你都 unshare 了,不如再 map-root-user 一下(也就是用 user namespace )
不过你这个“小巧的 rootfs 内的 shell 交互”真的可以在非特权用户下跑吗?
你这个 rootfs 要可变的还是不可变的呢
不可变的话,我这有一个封装 rootfs 的小工具 https://github.com/codehz/EasyPak ,本来是用于快速封装一个二进制及其依赖到单文件
只是单纯 chroot 的话,unshare 的 map-root-user 应该就可以用了
ysc3839
209 天前
直接用 Docker ?不过 docker daemon 也是要 root 的。这类系统级的功能估计都很难绕开 root ,真要搞的话只能依靠一些复杂的用户模式沙盒/虚拟化来实现了。
huahsiung
209 天前
proot 行啊。假如 rootfs 根目录为/home/user0/rootfs 。直接 proot -S /home/user0/rootfs /bin/bash 就进入容器内的 bash 了。

你试试

```bash
~$:whoami
user0

~$:proot -S /home/user0/rootfs /bin/bash
~$:whoami
root
```

用 proot 当轻量容器我用很久了
deorth
209 天前
proot
wizardyhnr
209 天前
@ysc3839 docker 有 rootless 的模式
guanzhangzhang
209 天前
@codehz 大佬,咨询下,你说的情况在非 root 用户下,unshare 参数是多少😘
guanzhangzhang
209 天前
@huahsiung 难道是我下载的 proot 不对吗,我是在 https://github.com/proot-me/proot-static-build 下载的
codehz
209 天前
@guanzhangzhang unshare --fork --pid --map-root-user --mount-proc --propagation slave --setgroups deny
里面直接 mount/chroot 都没问题
codehz
209 天前
哦,不要加 setgroups
ysc3839
209 天前
@wizardyhnr 那不就完美解决楼主的问题了?程序自带一个 Docker 即可。
guanzhangzhang
209 天前
@codehz #10 大佬,map-root-user 后无法给结尾 nobody 需要的家目录,而且看似乎是--mount 配合形成 webkubectl 的 shell 隔离的
```
guanzhang@guan:~$ unshare --fork --pid --map-root-user --mount-proc --propagation slave bash
root@guan:~# mkdir -p /nonexistent
mkdir: cannot create directory ‘/nonexistent’: Permission denied
```
codehz
209 天前
@guanzhangzhang 生活小技巧
在/tmp 上再挂一层 tmpfs ,然后把其他目录 bind mount 进去,接着 chroot 进/tmp ,然后再执行 mkdir 一类的操作
codehz
209 天前
此外你可以选择先切到 nobody 再执行上面说的 unshare ,因为在 map-root-user 的模式下,没有办法再切别的用户了
codehz
209 天前
仔细想你这只是为了家目录可写入的话,可以简单的直接在 unshare 里面 mount -t tmpfs tmpfs /root ,这样/root 就是可写入的家目录了
guanzhangzhang
208 天前
@codehz #14 😢我发现容器内非 root 用户执行 unshare 的时候不能带--pid ,否则 unshare: unshare(0x20000000): Operation not permitted
codehz
208 天前
pid namespace 好像问题不大,主要是方便一键咔掉子进程,这个可以用原用户开()
guanzhangzhang
208 天前
@huahsiung 我发现 proot 能杀掉父进程,有隔离进程的吗,容器内非 root 执行 unshare 不能带--pid 的隔离
guanzhangzhang
208 天前
@codehz #17 大佬,没看懂这个怎么搞
codehz
208 天前
@guanzhangzhang 就是先用容器内的 root ,unshare --fork --pid
然后里面再 su nobody unshare ...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/981439

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX