SELinux 相关 

Last Update: 2023-08-13

目录

常见坑

systemd 的 ExecStart 字段被阻止

systemctl status <service_name> 显示服务没有运行,并且在 journalctl 里可以找到类似于这样的日志:

Oct 29 20:16:08 fedora-us-west setroubleshoot[1865]: SELinux is preventing (e.binary) from execute access on the file gsite.binary. For complete SELinux messages run: sealert -l 26c7ef6d-0e1c-4b7b-abac-46fa3aebfc85
Oct 29 20:16:08 fedora-us-west setroubleshoot[1865]: SELinux is preventing (e.binary) from execute access on the file gsite.binary.

                                                     ,*****  Plugin catchall (100. confidence) suggests   **************************

                                                     If you believe that (e.binary) should be allowed execute access on the gsite.binary file by default.
                                                     Then you should report this as a bug.
                                                     You can generate a local policy module to allow this access.
                                                     Do
                                                     allow this access for now by executing:
                                                     # ausearch -c '(e.binary)' --raw | audit2allow -M my-ebinary
                                                     # semodule -X 300 -i my-ebinary.pp

SELinux 把在 ExecStart 字段内可以使用的二进制的文件限制为 system_u:object_r:bin_t:s0 。这个权限通常会出现在 /usr/bin, /usr/sbin, /usr/libexec, /usr/local/bin 目录下的二进制文件上。

所以只要把二进制文件的权限改好就可以执行了。

比如 chcon -R -t bin_t /opt/tomcat/bin/

另一个思路是把某个路径加入到 SELinux 的策略组里面,然后执行 restorecon 命令让 SELinux 使用策略组的权限配置覆盖现有的配置:

# 把能用 /opt/java/bin(/.*)? 匹配的路径加入到 bin_t 组里面
semanage fcontext -a -t bin_t "/opt/java/bin(/.*)?"
# 用 bin_t 组的权限配置覆盖 /opt/java/bin 及项目的权限配置
restorecon -r -v /opt/java/bin

Nginx 的 proxy_pass 无法成功转发

使用命令 sudo cat /var/log/audit/audit.log | grep nginx | grep denied 得到有类似下面内容的 SELinux 日志:

type=AVC msg=audit(1635500973.326:971): avc:  denied  { name_connect } for  pid=767 comm="nginx" dest=7500 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0
type=AVC msg=audit(1635500978.651:975): avc:  denied  { name_connect } for  pid=767 comm="nginx" dest=7500 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0
type=AVC msg=audit(1635500983.613:976): avc:  denied  { name_connect } for  pid=767 comm="nginx" dest=10080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0

使用命令 sudo cat /var/log/nginx/error.log 得到有类似下面内容的 Nginx error 日志:

2021/10/29 08:04:33 [crit] 776#776: *35 connect() to 127.0.0.1:2014 failed (13: Permission denied) while connecting to upstream, client: 172.68.133.68, server: tools.lishouzhong.com, request: "GET /gate0 HTTP/1.1", upstream: "http://127.0.0.1:2014/gate0", host: "tools.lishouzhong.com"
2021/10/29 08:04:37 [crit] 776#776: *37 connect() to 127.0.0.1:2014 failed (13: Permission denied) while connecting to upstream, client: 172.68.133.68, server: tools.lishouzhong.com, request: "GET /gate0 HTTP/1.1", upstream: "http://127.0.0.1:2014/gate0", host: "tools.lishouzhong.com"
2021/10/29 08:04:38 [crit] 776#776: *39 connect() to 127.0.0.1:2014 failed (13: Permission denied) while connecting to upstream, client: 172.68.133.68, server: tools.lishouzhong.com, request: "GET /gate0 HTTP/1.1", upstream: "http://127.0.0.1:2014/gate0", host: "tools.lishouzhong.com"

日志的重点是 13: Permission denied

最快的解决方法是把 SELinux 的 httpd_can_network_connect 功能给打开:

执行 getsebool httpd_can_network_connect 可以查看 httpd_can_network_connect 参数的情况,一般是关着的 (httpd_can_network_connect --> off)。

执行 setsebool -P httpd_can_network_connect 1setsebool -P httpd_can_network_connect on (-P 表示 permanent,永远开启) 可以打开这个功能。