1.准备工作
安装selinux-policy-devel
selinux-policy-devel 提供更多自定义策略功能
yum install selinux-policy-devel -y
暂时关闭SELinux强制模式(代策略配置好后开启)
setenforce 0
开启 docker selinux
$ tee /etc/docker/daemon.json <<-'EOF'
{
"selinux-enabled" : true
}
EOF
$ systemctl daemon-reload
$ systemctl restart docker
2.创建一个基本的容器策略,例如docker_elephdev
vi docker_elephdev.te
policy_module(docker_elephdev, 1.0);
virt_sandbox_domain_template(docker_elephdev);
# 许可域允许进程不被 SELinux 阻止(permissive)
# 当策略完全配置好后, 需注释掉,则是强制模式(enforcing)
# 配置阶段需容器使用到的规则都将被记录在AVC, 通过日志可以得知容器所需的策略配置
permissive docker_elephdev_t;
virt_sandbox_domain_template
宏会创建新类型,docker_elephdev_t
并为docker
操作创建必要的规则,以将新类型用作容器域
3. 编译并加载策略模块
编译策略
# 如提示命令不存在则使用:/usr/share/selinux/devel/Makefile
make -f /usr/selinux/devel/Makefile docker_elephdev.pp
执行完后目录下会多出3个文件1个临时目录
[root@localhost elephdev]# ll
total 88
-rw-r--r--. 1 root root 0 Sep 26 03:36 docker_elephdev.fc
-rw-r--r--. 1 root root 23 Sep 26 03:36 docker_elephdev.if
-rw-r--r--. 1 root root 80946 Sep 26 03:36 docker_elephdev.pp
-rw-r--r--. 1 root root 116 Sep 26 03:35 docker_elephdev.te
drwxr-xr-x. 2 root root 78 Sep 26 03:36 tmp
加载策略模块
semodule -i docker_elephdev.pp
semodule -l | grep docker_elephdev #验证是否加载成功
4.如何根据容器配置对应策略
运行nginx
容器并指定策略模块
[root@localhost elephdev]# docker run -it --rm -p 80:80 --name elenginx --security-opt label:type:docker_elephdev_t nginx
label:type:docker_elephdev_t nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/09/25 19:41:42 [notice] 1#1: using the "epoll" event method
2021/09/25 19:41:42 [notice] 1#1: nginx/1.21.3
2021/09/25 19:41:42 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/25 19:41:42 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2021/09/25 19:41:42 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/09/25 19:41:42 [notice] 1#1: start worker processes
2021/09/25 19:41:42 [notice] 1#1: start worker process 32
2021/09/25 19:41:42 [notice] 1#1: start worker process 33
查看拦截提醒
产生预期的错误。然后运行audit2allow
以生成规则,以允许对进行这些操作docker_elephdev_t,您可以.te使用新规则更新相同的模块文件(请记住要增加版本号),编译并安装更新的模块
使用 audit2allow 命令,可以轻松地从拒绝操作的日志中生成 SELinux 策略允许规则
[root@localhost elephdev]# grep docker_elephdev_t /var/log/audit/audit.log | audit2allow -r
require {
type node_t;
type http_port_t;
type docker_elephdev_t;
class capability { chown net_bind_service setgid setuid };
class tcp_socket { accept bind create listen name_bind node_bind setopt };
}
#============= docker_elephdev_t ==============
allow docker_elephdev_t http_port_t:tcp_socket name_bind;
allow docker_elephdev_t node_t:tcp_socket node_bind;
allow docker_elephdev_t self:capability { chown net_bind_service setgid setuid };
allow docker_elephdev_t self:tcp_socket { accept bind create listen setopt };
vi docker_elephdev.te
policy_module(docker_elephdev, 1.1);
virt_sandbox_domain_template(docker_elephdev);
require {
type node_t;
type http_port_t;
type docker_elephdev_t;
class capability { chown net_bind_service setgid setuid };
class tcp_socket { accept bind create listen name_bind node_bind setopt };
};
#============= docker_elephdev_t ==============
allow docker_elephdev_t http_port_t:tcp_socket name_bind;
allow docker_elephdev_t node_t:tcp_socket node_bind;
allow docker_elephdev_t self:capability { chown net_bind_service setgid setuid };
allow docker_elephdev_t self:tcp_socket { accept bind create listen setopt };
permissive docker_elephdev_t;
编译并加载策略模块
[root@localhost elephdev]# make -f /usr/share/selinux/devel/Makefile docker_elephdev.pp
Compiling targeted docker_elephdev module
/usr/bin/checkmodule: loading policy configuration from tmp/docker_elephdev.tmp
/usr/bin/checkmodule: policy configuration loaded
/usr/bin/checkmodule: writing binary representation (version 19) to tmp/docker_elephdev.mod
Creating targeted docker_elephdev.pp policy package
rm tmp/docker_elephdev.mod tmp/docker_elephdev.mod.fc
[root@localhost elephdev]# semodule -i docker_elephdev.pp
[root@localhost elephdev]# semodule -l | grep docker_elephdev
docker_elephdev 1.1
启用强制 selinux
setenforce 1
清除audit.log
并测试访问
echo > /var/log/audit/audit.log
curl localhost:80
此时已报错提示且访问成功,说明策略配置成功
开启策略强制模式(去除docker_elephdev.te中的)
policy_module(docker_elephdev, 1.2);
virt_sandbox_domain_template(docker_elephdev);
require {
type node_t;
type http_port_t;
type docker_elephdev_t;
class capability { chown net_bind_service setgid setuid };
class tcp_socket { accept bind create listen name_bind node_bind setopt };
};
#============= docker_elephdev_t ==============
allow docker_elephdev_t http_port_t:tcp_socket name_bind;
allow docker_elephdev_t node_t:tcp_socket node_bind;
allow docker_elephdev_t self:capability { chown net_bind_service setgid setuid };
allow docker_elephdev_t self:tcp_socket { accept bind create listen setopt };
#permissive docker_elephdev_t;
重新编译并加载策略模块
$ make -f /usr/share/selinux/devel/Makefile docker_elephdev.pp
$ semodule -i docker_elephdev.pp
这时访问 nginx 不通,查询容器运行日志发现 recv()
权限不足
调整tcp_socket
策略
再次访问
发表评论 取消回复