本来我只是想用python写个CGI程序(Python中会运行shell脚本,shell脚本有IO操作)由Apache服务器执行的,结果牵出一堆的权限问题。执行shell的之后明明/var/www/下某个目录属于apache用户而且是755的,写入文件却Permission Denied。CGI子进程用户都是apache。以前听说过SELinux,终于有一天被它拦住了。解决问题的过程中搜索了很多文档,把有价值的保存下来,防止链接失效。
How To
https://wiki.centos.org/HowTos/SELinux#head-ad837f60830442ae77a81aedd10c20305a811388
5.5 Allowing Access to a Port 端口号权限
We may want a service such as Apache to be allowed to bind and listen for incoming connections on a non-standard port. By default, the SELinux policy will only allow services access to recognized ports associated with those services. If we wanted to allow Apache to listen on tcp port 81, we can add a rule to allow that using the ‘semanage‘ command:
我们有时候允许某些服务(例如Apache)绑定监听非标准的端口号(80)。默认情况下,SELinux仅允许服务使用这些服务关联的端口号,如果希望允许Apache监听81端口,我们需要使用semanage
命令增加一条规则。
# semanage port -a -t http_port_t -p tcp 81
补充:man semanage-port 发现我们能添加端口号范围,但是文档中对于range的格式没有明确说明。参考SE,range使用横线分隔,例如semanage port -a -t http_port_t -p tcp 8000-8999
。根据SE中的回答,我们删除range的时候必须是添加时的range:semanage port --delete -t http_port_t -p tcp 8000-8999
A full list of ports that services are permitted access by SELinux can be obtained with:
服务能使用的所有端口号列表能通过如下方式获得
# semanage port -l
Booleans
- 以下部分翻译成开关
Boolean的解释:https://www.axivo.com/resources/selinux-booleans-explained.22/
I recently upgraded several servers to CentOS 6.6 release including live AXIVO site and to my surprise, all PHP related applications stopped working. After a closer look at servers logs, I noticed several denied AVC and SYSCALL into audit logs related to PHP-FPM and Nginx.
最近我升级到了CentOS 6.6,然而所有PHP相关的程序都挂了。在仔细查看了服务器日志之后,我在audit logs中发现了多个与PHP-FPM和nginx相关的AVC和SYSCALL拒绝(错误)。
This tutorial will help you identify the audit rules and Booleans related to an action or command blocked by Selinux in Red Hat 6.6+. Start by validating who is the culprit:
这个教程将帮助你找到那个audit规则和Boolean。首先确认犯人:
# ausearch -i -ts recent
# ausearch -i -c nginx
# ausearch -i -c php-fpm
Next, analyze the policy package:
# ausearch -c nginx | audit2allow -m nginx
module nginx 1.0;
require {
type httpd_t;
class process { execmem setrlimit };
}
#============= httpd_t ==============
#!!!! This avc can be allowed using the boolean ‘httpd_execmem‘
allow httpd_t self:process execmem;
#!!!! This avc is allowed in the current policy
allow httpd_t self:process setrlimit;
# ausearch -c php-fpm | audit2allow -m php-fpm
module php-fpm 1.0;
require {
type mysqld_port_t;
type httpd_t;
type memcache_port_t;
class process setrlimit;
class tcp_socket name_connect;
}
#============= httpd_t ==============
#!!!! This avc can be allowed using one of the these booleans:
# httpd_can_network_relay, httpd_can_network_memcache, httpd_can_network_connect
allow httpd_t memcache_port_t:tcp_socket name_connect;
#!!!! This avc can be allowed using one of the these booleans:
# httpd_can_network_connect, httpd_can_network_connect_db
allow httpd_t mysqld_port_t:tcp_socket name_connect;
#!!!! This avc can be allowed using the boolean ‘httpd_setrlimit‘
allow httpd_t self:process setrlimit;
The above example shows clearly what Boolean should be enabled. Verify the status of a specific Boolean and enable it, if necessary:上面的信息很明确的说明了那个Boolean需要被打开。按照它的提示,验证是否打开,如果没有则打开:
# sestatus -b | grep httpd_setrlimit
httpd_setrlimit off
# setsebool -P httpd_setrlimit on
# sestatus -b | grep httpd_setrlimit
httpd_setrlimit on
Be careful what Boolean you enable. For example, httpd_execmem allows Nginx/PHP-FPM to execute programs requiring memory addresses that are both executable and writeable. Enabling this Boolean is not recommended from a security standpoint, as it reduces the protection against buffer overflows. Even if I noticed several alerts into audit logs, I only enabled the following httpd Booleans (beside the ones set to On by default):请小心打开这些开关,例如httpd_execmem
允许nginx/PHP-FPM执行程序,而且这些程序需要能够执行和写入的内存空间。出于安全考虑,不推荐打开这个开关,因为它降低了溢出的保护。即使我发现了多个audit日志中的警告,但我还是只开启了下面几个开关:
- httpd_can_network_connect - allows Nginx connections to Network using TCP 允许Nginx使用TCP连接网络
- httpd_can_sendmail - allows Nginx to send mail, commonly related to PHP Sendmail 允许Nginx发送邮件,一般和PHP Sendmail相关
- httpd_enable_cgi - allows Nginx to run PHP CGI related programs 允许Nginx运行PHP CGI相关程序
- httpd_setrlimit - allows Nginx to adjust the number of file descriptors 允许Nginx调整文件描述符上限
To list all Nginx related Booleans, run:列出所有Nginx相关的Boolean
# sestatus -b | grep httpd
I did not enabled httpd_can_network_relay because is needed only when Nginx is set as a forward/remote proxy. I also kept httpd_can_network_connect_db and httpd_can_network_memcache disabled because I already allow connections with httpd_can_network_connect.我没有启用httpd_can_network_relay,因为只有做代理时才需要。另外将httpd_can_network_connect_db和httpd_can_network_memcache保持关闭因为我已经打开了httpd_can_network_connect
You could also generate and install a non-base policy package:
# ausearch -c nginx | audit2allow -M nginx
# semodule -i nginx.pp
# chmod 0600 /etc/selinux/targeted/modules/active/modules/nginx.pp
# ausearch -c php-fpm | audit2allow -M php-fpm
# semodule -i php-fpm.pp
# chmod 0600 /etc/selinux/targeted/modules/active/modules/php-fpm.pp
This is useful when no Booleans are defined, for example the Postfix postdrop denials.
查看Boolean的信息
使用 semanage
命令查看这些boolean的描述
> semanage boolean -l | grep httpd_can_network_connect
httpd_can_network_connect_db (off , off) Allow HTTPD scripts and modules to connect to databases over the network.
httpd_can_network_connect (off , off) Allow HTTPD scripts and modules to connect to the network using TCP.
最好的方法是查看sesearch
和seinfo
,在较新的系统 (Fedora/RHEL7)上则使用sepolicy
命令。另外有部分man page已经有了:man httpd_selinux
。sesearch
和seinfo
需要安装包setools-cmdline
。sepolicy
在policycoreutils-python
包。
boolean httpd_can_network_connect_db
sesearch -A -s httpd_t -b httpd_can_network_connect_db -p name_connect
allow httpd_t postgresql_port_t : tcp_socket { recv_msg send_msg name_connect } ;
allow httpd_t mssql_port_t : tcp_socket name_connect ;
allow httpd_t oracle_port_t : tcp_socket name_connect ;
allow httpd_t mysqld_port_t : tcp_socket { recv_msg send_msg name_connect } ;
allow httpd_t gds_db_port_t : tcp_socket name_connect ;
sesearch
打印出设置httpd_can_network_connect_db
之后发生了什么:打开httpd_can_network_connect_db
开关之后,httpd_t将能连接上标记为postgresql_port_t/mssql_port_t/oracle_port_t/mysqld_port_t/gds_db_port_t的端口号。通过seinfo
命令将这些端口类型转成端口定义(semanage port -l
也行):
> seinfo --port | grep -e postgresql_port_t -e mysqld_port_t -e oracle_port_t -e gds_db_port_t | grep tcp
portcon tcp 3050 system_u:object_r:gds_db_port_t:s0
portcon tcp 1186 system_u:object_r:mysqld_port_t:s0
portcon tcp 3306 system_u:object_r:mysqld_port_t:s0
portcon tcp 63132-63164 system_u:object_r:mysqld_port_t:s0
portcon tcp 1521 system_u:object_r:oracle_port_t:s0
portcon tcp 2483 system_u:object_r:oracle_port_t:s0
portcon tcp 2484 system_u:object_r:oracle_port_t:s0
portcon tcp 5432 system_u:object_r:postgresql_port_t:s0
> sepolicy network -t postgresql_port_t
postgresql_port_t: tcp: 5432
boolean httpd_can_network_connect
> sesearch -A -s httpd_t -b httpd_can_network_connect -p name_connect
Found 1 semantic av rules:
allow httpd_t port_type : tcp_socket name_connect ;
The above command shows that httpd_can_network_connect allows httpd_t to connect to all tcp socket types that have the port_type attribute.
httpd_can_network_connect允许httpd连接所有具备port_type属性的tcp socket。
> seinfo -aport_type -x | wc -l
245
Using seinfo above would show you that port_type is the attribute of all port types, meaning that turning on the httpd_can_network_connect boolean, allows the httpd_t domain to connect to ALL tcp network ports.
seinfo命令显示port_type是所有端口类型的属性,所以打开这个开关就表示http_t能连接所有tcp网络端口。
Bottom Line httpd_can_network_connect_db allows httpd_t to connect to an additional 10 ports while httpd_can_network_connect adds thousands.
结论:httpd_can_network_connect_db允许httpd_t连接10多个端口,而httpd_can_network_connect是几千个(基本上所有的吧)
原文地址:https://www.cnblogs.com/gdme1320/p/9609899.html