![如何有选择地为一个可执行文件或用户启用 unprivileged_userns_clone?](https://linux22.com/image/213920/%E5%A6%82%E4%BD%95%E6%9C%89%E9%80%89%E6%8B%A9%E5%9C%B0%E4%B8%BA%E4%B8%80%E4%B8%AA%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E6%88%96%E7%94%A8%E6%88%B7%E5%90%AF%E7%94%A8%20unprivileged_userns_clone%EF%BC%9F.png)
与仅相比,如何CLONE_NEWUSER
以更细粒度的方式启用kernel.unprivileged_userns_clone
?
我希望通过禁用非 rootCAP_SYS_ADMIN
或 BPF 等新的复杂功能来保持内核 API 攻击面的可管理性,同时也有选择地允许某些特定程序使用它。
例如,chrome-sandbox
想要CLOSE_NEWUSER
或 suid-root 才能正常运行,但我不希望所有程序都能够使用如此复杂的技巧,只有少数经过批准的程序。
答案1
如果不创建自定义内核补丁,这是不可能的。请注意,这个特定于 Debian 的 sysctl已弃用。禁用用户命名空间的方法是user.max_user_namespaces = 0
。
创建一个新的用户命名空间kernel/user_namespace.c:create_user_ns()
。在允许创建新命名空间之前会进行多项检查,但没有任何迹象表明能够在每个文件或每个用户的基础上进行控制。这很不幸,但是许多内核开发人员不了解风险在全球范围内启用非特权用户命名空间的背后。
仅允许 UID 1234 在内核 6.0 中创建新命名空间的示例(未经测试!)补丁:
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -86,6 +86,10 @@ int create_user_ns(struct cred *new)
struct ucounts *ucounts;
int ret, i;
+ ret = -EPERM;
+ if (!uid_eq(current_uid(), KUIDT_INIT(1234)))
+ goto fail;
+
ret = -ENOSPC;
if (parent_ns->level > 32)
goto fail;