1. Preparation

Install selinux-policy-devel

selinux-policy-devel provides more custom policy functions

yum install selinux-policy-devel -y

Temporarily turn off SELinux mandatory mode (turn it on after the generation policy is configured)

setenforce 0

Open docker selinux

$ tee /etc/docker/daemon.json <<-'EOF'
{
  "selinux-enabled": true
}
EOF

$ systemctl daemon-reload

$ systemctl restart docker

2. Create a basic container strategy, such as docker_elephdev

vi docker_elephdev.te

policy_module(docker_elephdev, 1.0);

virt_sandbox_domain_template(docker_elephdev);

# Permissive domain allows the process not to be blocked by SELinux (permissive)
# When the strategy is fully configured, it needs to be commented out, it is enforcing mode (enforcing)
# The rules that need to be used by the container during the configuration phase will be recorded in the AVC, and the policy configuration required by the container can be learned through the log
permissive docker_elephdev_t;

The virt_sandbox_domain_template macro creates a new type, docker_elephdev_t and creates the necessary rules for the docker operation to use the new type as a container domain

3. Compile and load the strategy module

Compilation strategy

# If the prompt command does not exist, use: /usr/share/selinux/devel/Makefile
make -f /usr/selinux/devel/Makefile docker_elephdev.pp

image.png

After execution, there will be 3 more files and 1 temporary directory in the directory

[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

Load strategy module

semodule -i docker_elephdev.pp
semodule -l | grep docker_elephdev #Verify whether the loading is successful

image.png

4. How to configure the corresponding strategy according to the container

Run the nginx container and specify the strategy module

[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

image.png

View block reminder

image.png

Produces the expected error. Then run audit2allow to generate rules to allow these operations on docker_elephdev_t, you can .te update the same module file with the new rules (remember to increase the version number), compile and install the updated module

Using the audit2allow command, you can easily generate SELinux policy permission rules from the logs of denial operations

[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;

Compile and load the strategy module

[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

Enable mandatory selinux

setenforce 1

Clear audit.log and test access

echo> /var/log/audit/audit.log

curl localhost:80

At this time, an error message has been reported and the access is successful, indicating that the policy configuration is successful

Enable policy enforcement mode (remove 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;

Recompile and load the strategy module

$ make -f /usr/share/selinux/devel/Makefile docker_elephdev.pp
$ semodule -i docker_elephdev.pp

At this time, access to nginx is unavailable, and querying the container running log finds that recv() permissions are insufficient

image.png

Adjust the tcp_socket strategy, plus read and write

allow docker_elephdev_t self:tcp_socket {accept bind create listen setopt write read };

Visit again

image.png

点赞(0)

评论列表 共有 0 评论

暂无评论

微信服务号

微信客服

淘宝店铺

support@elephdev.com

发表
评论
Go
顶部