SELinux 相关
Table of Contents
1. 常见坑
1.1. 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
1.2. 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 1
或 setsebool -P httpd_can_network_connect on
( -P
表示 permanent,永远开启 ) 可以打开这个功能。