这两天由于工作需要,下载编译了最新的openwrt代码,但是编译时遇到了一个奇怪的问题,编着编着卡住不动了。大概到下图位置就一直卡死了,最开始我以为是慢,需要时间下载或执行啥的,结果第二天来还是卡住不动。我才意识到出问题了。

从上面日志可以看出openwrt在编译package/libs/toolchain时出了问题,所以我接下来执行make -j1 V=s package/libs/toolchain/compile编译,发现这个也是这个现象。那么可以定位是编译package/libs/toolchain过程中有问题。我把编译过程丢给deepseek,它也没头绪,回答驴头不对马嘴。

在我没思路的时候,deepseek给了个好建议,就是抓系统调用日志,使用strace追踪系统调用过程,这样就可以把过程中遇到的错误或者问题找到了,至少知道问题出在哪,接着我就使用strace -f -o /tmp/build.log make -j1 V=s package/libs/toolchain/compile重新执行了一遍,然后把抓出来的日志,继续喂给deepseek,让他分析。结果就是不出意外,deepseek还是没头绪。

接着我在编译卡住时,ps看了一下当前执行的进程,发现两个进程很可疑:
一个是/work/staging_dir/host/bin/fakeroot /work/staging_dir/host/bin/bash /work/scripts/ipkg-build -m "" /work/build_dir/target-mipsel_24kc_musl/toolchain/ipkg-mipsel_24kc/libgcc /work/bin/targets/ramips/mt7621/packages;
一个是/work/staging_dir/host/bin/faked。
我继续追踪系统调用strace -f -o /tmp/faked.log /work/staging_dir/host/bin/faked,然后继续把日志喂给deepseek,这种苦力活它比较适合。
但这次却出现了意外,它居然找到问题原因了!!!就是下图!!!

终于有点希望了,紧接着我问小d,我该怎么解决这个问题,它又开始瞎bb了,说了好几个方法都没有效果,试的我都累死了。

在我将要放弃的时候,不出意外的又出现了转机,居然成功了!!!好家伙,这是把我当小日子整啊,心脏都快受不了了。
千言万语总结起来,其实就是使用docker命令的时候,添加参数”--privileged --userns=host“就可以解决,这样就再也不会卡住了。
例如我的执行命令如下:
sudo docker run -it --privileged --userns=host --rm -v /home/test/openwrt:/work ubuntu22.04 /bin/bash
当然到这里问题解决了,你可能想知道到底是为什么,你也可能不想知道。如果不想知道那看到这里可以结束了,想知道的请继续看下去。
问题背景
由于我的电脑是ubuntu18.04,内核版本5.4。当在Linux 5.4内核上使用Docker容器编译OpenWrt时,遇到编译过程卡住的问题。核心错误表现为:
close_range(0, 2, 0) = -1 EPERM (Operation not permitted)
这个问题在内核版本低于5.9的环境中特别常见,因为close_range系统调用是在Linux 5.9中引入的。
问题原因分析
1.内核版本限制
close_range系统调用在Linux 5.9+中引入,Linux 5.4内核无法识别该系统调用,内核错误地返回EPERM(操作不允许)而非正确的ENOSYS(功能未实现)。
2. Docker安全机制
默认seccomp配置文件阻止未知系统调用,用户命名空间隔离限制权限,Capabilities机制限制特权操作。
3. fakeroot实现依赖
fakeroot的faked守护进程尝试使用close_range,该调用需要CAP_SYS_ADMIN能力,旧内核上无法降级。
解决方案
--privileged --userns=host
参数作用解释
docker run --privileged --userns=host -it your_image
--privileged 授予所有Linux能力禁用seccomp和AppArmor,允许close_range系统调用,解除安全机制限制。
--userns=host 使用主机用户命名空间,容器root=主机root 绕过用户命名空间隔离,解决UID映射问题。
为什么这个组合有效?
解除能力限制,授予CAP_SYS_ADMIN能力,允许特权系统调用,启用所有内核功能接口。
绕过安全机制:
禁用seccomp过滤器(允许所有系统调用)
禁用AppArmor/SELinux限制
消除用户命名空间隔离:
容器内root用户=主机root用户
避免UID/GID映射问题
直接访问主机内核接口
安全警告
--privileged --userns=host虽然有效,但极大降低安全性,仅在以下场景使用:
✅ 临时构建环境
✅ 受信任的CI/CD流水线
✅ 隔离的开发环境
避免在生产环境使用,可能的风险包括:
容器逃逸攻击
主机文件系统被篡改
内核级漏洞利用
资源滥用(fork炸弹等)
适用场景
本方案适用于:
- Docker容器中运行fakeroot
- 旧内核(<5.9)环境
- OpenWrt编译过程卡住
- 类似构建工具依赖特权操作
是的,最后的总结是小d,deepseek做的,实在太累了,懒的写了,还是让这苦力干吧
591

被折叠的 条评论
为什么被折叠?



