garywill
(GarryW)
2025 年12 月 11 日 01:26
1
这个东西目前仍然非常早期,但已经能用了。
如果你经常使用firejail ,那么你可能有兴趣
做了一个完全可控的沙箱
花了十天搓了千行代码,稍学习了下内核的namespace机制。,
涉及内核的编程,这方面我其实还算个菜鸟,自学一点出来献丑,希望有大佬斧正。
有太多内容,看github readme吧,这里不写了
比firejail好在:
(已实现)可无限嵌套 。firejail拒绝嵌套的,其他unshare等工具在这方面也有间接限制
(计划中)支持overlay . firejail以前支持,但已经移除了这个功能
(计划中)控制容器流量 。firejail的内部iptables是需要预先给了firejail二进制特权的。想搞个完全不需要特权的
(计划中) 外面可随时获取沙箱内的shell. Firejail的沙箱想要从外面进入的是需要sudo nsenter的。所以我想弄个免root办法,把沙箱内shell“共享”到沙箱外
还有好多,不在这写了,看readme吧
Box-in-box Linux sandbox. Fully customizable, endlessly-nestable. Root-less.
1 个赞
garywill
(GarryW)
2025 年12 月 11 日 01:31
2
关于上面提到的计划的后面两点
这两点用什么方法来达到完全免特权的实现 ,心里还没有确定可靠的方案
关于控制流量,看到 passt / pasta ,他们用的tun/tap. 但网上关于这个工具的资料很少
关于共享shell, 不知大家有什么经验,比如什么工具可以通过unix socket文件做到server/client的shell共享
garywill:
(已实现)可无限嵌套 。firejail拒绝嵌套的,其他unshare等工具在这方面也有间接限制
(计划中)支持overlay . firejail以前支持,但已经移除了这个功能
(计划中)控制容器流量 。firejail的内部iptables是需要预先给了firejail二进制特权的。想搞个完全不需要特权的
(计划中) 外面可随时获取沙箱内的shell. Firejail的沙箱想要从外面进入的是需要sudo nsenter的。所以我想弄个免root办法,把沙箱内shell“共享”到沙箱外
你是不是在找:systemd-nspawn。
控制流量需要root。要获取沙箱内的shell,你只要在沙箱内跑个提供该服务的进程就好了。
systemd-nspawn+ssh就可以。
tun也是需要特权的。
garywill
(GarryW)
2025 年12 月 11 日 13:29
4
关于“共享shell" :
sshd似乎不能监听unix socket文件,只能监听tcp。 我弄这个沙箱想要让“共享shell"这个功能与网络解耦,所以想要避免任何tcp.
毕竟socket文件可以随着文件系统bind mount, 更优。
tmux 似乎可以监听socket 文件,我刚试了下。但tmux有点… 不是为此目的而生的,还不确定是否选它
关于tun :
我已简单地试了一下pasta (opensuse仓库里有,passt),它的确可以免root使用tun.
原理我刚查了些资料,说在刚创建user namespace时,暂时拥有内部的CAP_NET_ADMIN能力。很可能pasta就是通过这种方法使用tun的(不过我也暂时没深入研究)
systemd支持。看看你有没有:
systemctl cat sshd-unix-local.socket
cat /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf
userns里的root也算是特权,特别是你强调了「完全免特权」。不然你开个虚拟机,里边不也有个root么?
另外要让netns能够访问外部网络,要么需要root权限来配置veth和网桥之类的设施,要么只模拟TCP和UDP(基本上就是传输层转发啦,跟各种翻墙工具的tun代理一个样子),会造成netns的网络栈不完整,我很不喜欢。
garywill
(GarryW)
2025 年12 月 12 日 02:44
6
我没有sshd的socket耶。。
$ systemctl cat sshd-unix-local.socket
No files found for sshd-unix-local.socket.
$ cat /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf
cat: /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf: 没有那个文件或目录
我在leap 15.6上
那你可以自己配一个。基本思路就是让systemd去监听socket文件然后用inet的方式启动sshd。连接的话,用ProxyCommand调用nc就行吧。
Chingyat
(Lince)
2025 年12 月 26 日 04:25
8
lilydjwg:
tun也是需要特权的。
使用 persistent 的 tun 不需要特权。
先用 ip tuntap add dev tun0 user USER 创建好 tun interface,再用非特权的 USER 打开 tun0。
创建 tun interface 也只需要 cap_net_admin.
garywill
(GarryW)
2026 年3 月 23 日 05:22
10
肝了那么久,感觉可以发布首个试用版了。
项目起名 Tree Sandbox , 新地址在:
Another Linux sandbox tool. Allows unlimited nesting if you want
虽然没有专业安全团队,对这个沙箱项目现在不能给什么安全评估保证,不过,我自认为自己对各种细节还是比较严谨周到的,所以,欢迎尝鲜,欢迎试用~
1 个赞
garywill
(GarryW)
2026 年7 月 1 日 04:47
11
讲些之前开发过程中遇到的。
@lilydjwg 我弄了你说的sshd方案,万事具备了结果最后一步过不去
sshd -i 、传递client socket fd, 密钥等等 都弄好了之后,结果在连接到来、通过验证、sshd将要启动shell session时,setgroup失败。
因为 user namespace 容器在启动后都要对proc里的setgroups 写一次 deny, 而sshd启动时它又一定要做 setgroups
结论: sshd是为root系统设计的,是对 user namespace容器不友好的
最后我转向了一个叫dtach的工具。它是专门为通过unix socket文件共享shell设计的、非常简单的,一次成功
garywill
(GarryW)
2026 年7 月 1 日 04:52
12
还发现了一个 Konsole的bug 。害我排查了好久,bug竟然出在终端模拟器
我脚本在启动时会创建一个专门的 cgroups v2 目录,把自己添加进这个cgroup,然后自然地,所有子进程,也就是整个沙箱都会在这个cgroup里
但konsole偶尔会把其子进程树里的进程擅自移回konsole的cgroup,导致沙箱出些问题。如果用其他终端就没事
我已经向konsole上游反馈了这个问题