如何为特定容器创建自定义SELinux策略以允许挂载/proc并指定安全上下文?
当然可行!这正是SELinux策略灵活性的体现——我们可以创建一个自定义的SELinux域(类型),仅赋予它挂载/proc的权限,然后让指定容器使用这个域运行,完全不会影响默认的容器安全策略。下面是详细步骤:
1. 确认SELinux运行状态
首先确保你的系统SELinux处于Enforcing模式(这是默认的安全强化状态):
sestatus
如果显示Current mode: enforcing就没问题;如果不是,可以用sudo setenforce 1临时开启,或者修改/etc/selinux/config文件永久生效。
2. 生成/编写自定义SELinux策略模块
你找不到默认策略源码没关系,我们可以通过审计日志生成基础策略,再按需定制:
步骤2.1 触发SELinux拒绝日志
先尝试运行需要挂载/proc的容器,故意触发SELinux拦截(这一步是为了生成审计日志):
docker run --rm -v /proc:/hostproc:ro alpine ls /hostproc
这时候会报错,SELinux会把权限拒绝记录写入系统审计日志。
步骤2.2 提取并生成基础策略
用audit2allow工具从审计日志中提取规则,生成自定义策略模块:
sudo ausearch -m avc -ts recent | sudo audit2allow -a -M my_container_proc
执行后会得到两个文件:my_container_proc.te(策略源码文件)和my_container_proc.pp(编译后的可加载模块)。
步骤2.3 定制策略源码
编辑my_container_proc.te,我们要创建一个全新的容器安全类型(比如my_container_t),继承默认container_t的基础权限,再专门添加挂载/proc的规则:
policy_module(my_container_proc, 1.0) # 引入依赖的类型和权限类 require { type container_t; type proc_t; class filesystem mount; class dir mounton; class file read; } # 定义新的容器域类型 type my_container_t; domain_type(my_container_t) # 继承容器的可执行文件入口规则 domain_entry_file(my_container_t, container_exec_t) # 标记为容器域,继承容器的基础安全属性 container_domain(my_container_t) # 允许新类型挂载/proc文件系统 allow my_container_t proc_t:filesystem mount; allow my_container_t proc_t:dir mounton; # 允许读取/proc下的文件(按需添加,根据你的容器需求调整) allow my_container_t proc_t:file read;
这样我们就创建了一个仅比默认容器多了/proc挂载权限的安全域,严格遵循最小权限原则。
步骤2.4 编译并加载策略模块
编译策略源码为可加载模块:
sudo checkmodule -M -m -o my_container_proc.mod my_container_proc.te sudo semodule_package -o my_container_proc.pp -m my_container_proc.mod
将编译好的模块加载到SELinux系统中:
sudo semodule -i my_container_proc.pp
可以用sudo semodule -l | grep my_container_proc确认模块已成功加载。
3. 让Docker使用自定义SELinux上下文运行容器
现在运行目标容器时,通过--security-opt参数指定我们的自定义安全类型:
docker run --rm --security-opt label=type:my_container_t -v /proc:/hostproc:ro alpine ls /hostproc
这次应该能正常列出/proc下的内容了!
如果你用Docker Compose,在配置文件中添加security_opt字段即可:
services: my_service: image: your_image:tag security_opt: - label=type:my_container_t volumes: - /proc:/hostproc:ro
4. 验证策略生效
查看容器进程的SELinux标签,确认它确实在我们自定义的安全域中运行:
ps -Z | grep <container_pid>
输出应该类似:system_u:system_r:my_container_t:s0:c123,c456,说明策略已生效。
注意事项
- 不要直接修改默认的
container_t类型,这会降低所有容器的安全性,我们的自定义类型仅影响需要挂载/proc的特定容器。 - 如果后续容器还有其他权限需求,可以重复步骤2.1-2.4,用
audit2allow提取新的拒绝规则,补充到自定义策略中。 - 自定义策略模块可以用
sudo semodule -r my_container_proc卸载,方便测试和回滚。
内容的提问来源于stack exchange,提问作者Omnifarious

