如何让apache在启用SELinux的情况下在用户主目录中旋转日志?

我们的开发机器有多个用户,他们的各个站点都存储在/home/username/apache 。 在这些文件夹中,像conf这样的子文件夹包含虚拟主机configuration,包含日志的日志,包含实际networking文件的public等。

我想更改日志,而不是单个日志文件:

 CustomLog "/home/user/apache/domain.tld/logs/web.log" combined 

我们把日志分成日志:

 CustomLog "|/usr/sbin/rotatelogs -l /home/user/apache/domain.tld/logs/%Y%m%d_web.log 86400" combined 

但是,当我把这个configuration,重新启动apache,然后重新加载页面,同时拖尾audit.log ausearch ,我看到像这样的错误:

 ---- type=SYSCALL msg=audit(06/06/2014 14:16:51.401:406272) : arch=x86_64 syscall=open success=no exit=-13(Permission denied) a0=7fff70a92460 a1=80441 a2=1b6 a3=7fff70a92110 items=0 ppid=64542 pid=64617 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1193 comm=rotatelogs exe=/usr/sbin/rotatelogs subj=unconfined_u:system_r:httpd_rotatelogs_t:s0 key=(null) type=AVC msg=audit(06/06/2014 14:16:51.401:406272) : avc: denied { search } for pid=64617 comm=rotatelogs name=home dev=md2 ino=7208961 scontext=unconfined_u:system_r:httpd_rotatelogs_t:s0 tcontext=system_u:object_r:home_root_t:s0 tclass=dir 

我想我可以解决这个问题,就像我已经修改了其他SELinux问题(比如允许apache写入文件),但是尝试了几次之后,我仍然得到了上面的错误。 我试过httpd_log_thttpd_rotatelogs_exec_tvar_log_t无济于事。

我正在用chcon命令做这个。

我错过了什么?

实际问题

翻译您提供的日志的第二行:

带有PID 64617的rotatelogs进程尝试在设备md2和inode 7208961上的主目录中进行search。访问被拒绝。

rotatelogs进程的安全上下文是: unconfined_u:system_r:httpd_rotatelogs_t:s0

主目录的安全上下文是: system_u:object_r:home_root_t:s0

您需要允许rotatelogs读取主目录。 允许httpd这么做很容易( setsebool -P httpd_enable_homedirs=1 ),但不幸的是,rotatelogs不会从httpdinheritance它的types。 更糟糕的是,rotatelogs没有setsebool参数。

而这还不是全部! 您还需要允许rotatelogs一直search到所需的目录,并允许它执行其任务所需的所有操作 – 无论是文件本身还是包含它们的目录。

总之,你需要写一个本地政策。

一步一步的解决scheme

使用以下内容在任何地方创build一个名为homelogs.te的types实施文件:

 module homelogs 1.0; require { type httpd_rotatelogs_t; type home_root_t; type user_home_t; type user_home_dir_t; class dir { add_name getattr open read remove_name search write }; class file { create getattr open read rename unlink write }; } #============= httpd_rotatelogs_t ============= allow httpd_rotatelogs_t home_root_t:dir search; allow httpd_rotatelogs_t user_home_dir_t:dir search; allow httpd_rotatelogs_t user_home_t:dir { add_name getattr open read remove_name search write }; allow httpd_rotatelogs_t user_home_t:file { create getattr open read rename unlink write }; 

现在编译它:

make -f /usr/share/selinux/devel/Makefile homelogs.pp

并安装它:

semodule -i homelogs.pp

现在,rotatelogs应该具有在用户家中的子目录中执行其任务所需的所有权限。


如何编写本地政策

这是为那些谁想要更多的细节,我如何写本地政策。 你有两个select来编写这个策略。

audit2allow

如果您完全不policycoreutils-python编写本地策略,则可以使用policycoreutils-python软件包中提供的audit2allow工具来帮助您编写一个。

运行rotatelogs时要修复SELinux权限拒绝,可以运行该命令

 grep rotatelogs /var/log/audit/audit.log | audit2allow -M homelogs 

将包含“rotatelogs”的审计日志提供给audit2allow 。 该工具将自动分析SELinux权限拒绝,并创build一个types强制文件,以及编译的策略包( .pp )文件。 此时,您可以通过运行以下命令来简单安装创build的Policy Package:

 semodule -i homelogs.pp 

就这样,你已经修复了与rotatelogs有关的所有SELinux问题…对吧?

这种方法的问题audit2allow不能预测需要什么权限; 它只能分析已被拒绝的权限。

到目前为止,只有在家里(字面/home )目录中的search拒绝已经遇到,所以audit2allow只会解决这个问题。 想想每次遇到下一个被拒绝的权限时,您将不得不重新运行该工具多less次。 根据rotatelogsconfiguration,可能需要几周时间才能拒绝并logging特定权限。 例如,rotatelogs需要多长时间才能尝试删除旧的日志文件并触发取消链接权限?

迈克尔·汉普顿(Michael Hampton)在评论中指出,通过将SELinux更改为“允许模式”可以缓解这个问题:

 setenforce 0 

在这种模式下,SELinux会警告和logging操作,但不执行策略。 这允许rotatelogs执行所有的任务,而SELinux仍然logging所有权限拒绝。 然后,可以在审计日志上运行audit2allow ,安装自动创build的策略, setenforce 1返回到强制模式,并完成。

之前还不知道Permissiive模式可以这样使用,我手动编写了本地策略,如下所述。 没有必要手工做,但希望阅读有点教育。

手动创build

通过对Type Enforcement文件的一些了解,您可以通过手工编写来解决权限问题。 我创build了一个Type Enforcement文件(扩展名为.te )。 types强制文件的位置并不重要。

types强制文件有三个部分。

模块部分

 module homelogs 1.0; 

模块部分列出了您将使用本地策略创build的模块的名称和版本。 该名称应该是唯一的,否则你将replace一个已经存在的同名模块。 您可以使用semodule -l来检查已安装模块的名称。

需求部分

 require { type httpd_rotatelogs_t; type home_root_t; type user_home_t; type user_home_dir_t; class dir { add_name getattr open read remove_name search write }; class file { create getattr open read rename unlink write }; } 

如上所述:

在该模块可以安装之前,这个[部分]通知策略加载器在系统策略中需要哪些types,类和angular色。 如果这些字段中的任何一个未定义,则semodule命令将失败。

在你的情况下,rotatelogs将与几种types交互。 在rotatelogs可执行文件和所需path的目录上运行ls -Z后,我发现需要以下types:

  • httpd_rotatelogs_t
  • home_root_t
  • user_home_t
  • user_home_dir_t

你还需要与一些进行交互。 类的完整列表及其权限在这里 。 对于你的情况,我们只能使用class fileclass dir 。 您还必须列出您将与之交互的每个课程的权限 。 根据完整的列表,我select了要求这些类和权限(一对夫妇可能不是必要的,但我错误地允许):

class dir:

  • add_name – 将文件添加到目录
  • getattr – 获取文件的文件属性,如访问模式。 (例如stat,一些ioctl …)
  • open – 打开一个目录
  • read – 读取文件内容
  • remove_name – 从目录中删除文件
  • search – search访问
  • write – 一般写入权限; 需要添加或删除

类文件:

  • create
  • getattr – 获取文件的文件属性,如访问模式。 (例如stat,一些ioctl …)
  • open – 打开一个文件
  • read – 读取文件内容
  • rename – 重命名文件
  • unlink – 删除硬链接(删除)
  • write – 写入文件

规则部分

 allow httpd_rotatelogs_t home_root_t:dir search; allow httpd_rotatelogs_t user_home_dir_t:dir search; allow httpd_rotatelogs_t user_home_t:dir { add_name getattr open read remove_name search write }; allow httpd_rotatelogs_t user_home_t:file { create getattr open read rename unlink write }; 

规则部分相当容易阅读。 例如:

allow httpd_rotatelogs_t user_home_t:dir { add_name getattr open read remove_name search write };

大致意思是:

允许使用types为httpd_rotatelogs_t的命令对types为user_home_t的目录执行add_name,geattr,open,read,remove_name,search和write操作。

请注意,每个类都需要一个单独的规则,因为不同的类将拥有与它们相关的不同权限。

编译和安装

这是多余的,但我会再次提及。 您需要将types强制文件编译成策略包。 运行make ,Type Enforcement文件需要位于当前的工作目录中。

make -f /usr/share/selinux/devel/Makefile homelogs.pp

最后,将策略包安装为一个模块:

semodule -i homelogs.pp


编写自定义策略的有用资源:

  • 在哪里可以findSELinux权限拒绝细节
  • 定制SELinux策略
  • 创build您自己的策略模块文件
  • SELinux对象类和权限参考

不能在上面的优秀答案中添加评论,所以我将不得不添加一个新的“答案”:

如果由于缺less/usr/share/selinux/devel/Makefile文件而无法编译新创build的模块,请确保安装了selinux-policy-devel软件包:

yum install selinux-policy-devel

现在该文件将存在,您可以继续。