在centos下使用logrotate对应用日志进行分割管理时,直接执行logrotate命令分割没有问题,当列为执行计划时,出现了error: stat of /root/tomcat/logs/catalina.out failed: Permission denied的错误。从网上搜索结果来看时因为SELinux权限控制导致的。那就关键看看SELinux如何控制文件的访问了。
因此从系统日志进行分析
root用户收到的系统邮件
from root@localhost.localdomain Wed May 15 03:42:05 2019
Return-Path: <root@localhost.localdomain>
X-Original-To: root
Delivered-To: root@localhost.localdomain
Received: by localhost.localdomain (Postfix, from userid 0)
id 324936004BCE; Wed, 15 May 2019 03:42:05 +0800 (CST)
From: Anacron <root@localhost.localdomain>
To: root@localhost.localdomain
Content-Type: text/plain; charset="UTF-8"
Subject: Anacron job 'cron.daily' on localhost.localdomain
Message-Id: <20190514194205.324936004BCE@localhost.localdomain>
Date: Wed, 15 May 2019 03:42:05 +0800 (CST)
/etc/cron.daily/logrotate:
error: stat of /root/tomcat/logs/catalina.out failed: Permission denied
上述日志看到了计划任务执行失败,接下来再看看SELinux的日志
sealert -a /var/log/audit/audit.log
获取到如下日志:
SELinux is preventing /usr/sbin/logrotate from getattr access on the file /root/tomcat/logs/catalina.out.
***** Plugin catchall (100. confidence) suggests **************************
If you believe that logrotate should be allowed getattr access on the catalina.out 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 'logrotate' --raw | audit2allow -M my-logrotate
# semodule -i my-logrotate.pp
Additional Information:
Source Context system_u:system_r:logrotate_t:s0-s0:c0.c1023
Target Context unconfined_u:object_r:admin_home_t:s0
Target Objects /root/tomcat/logs/catalina.out [ file ]
Source logrotate
Source Path /usr/sbin/logrotate
Port <Unknown>
Host <Unknown>
Source RPM Packages logrotate-3.8.6-15.el7.x86_64
Target RPM Packages
Policy RPM selinux-policy-3.13.1-229.el7_6.12.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name localhost.localdomain
Platform Linux localhost.localdomain 3.10.0-862.el7.x86_64
#1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64
Alert Count 30
First Seen 2019-04-27 03:16:01 CST
Last Seen 2019-05-15 03:42:01 CST
Local ID 8690a525-bc91-4f0d-a291-c65c9c0efbfe
Raw Audit Messages
type=AVC msg=audit(1557862921.927:446): avc: denied { getattr } for pid=12757 comm="logrotate" path="/root/tomcat/logs/catalina.out" dev="dm-0" ino=34525231 scontext=system_u:system_r:logrotate_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=SYSCALL msg=audit(1557862921.927:446): arch=x86_64 syscall=lstat success=no exit=EACCES a0=1e37d50 a1=7fff432dd030 a2=7fff432dd030 a3=ffffffffffffba17 items=0 ppid=12755 pid=12757 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=43 comm=logrotate exe=/usr/sbin/logrotate subj=system_u:system_r:logrotate_t:s0-s0:c0.c1023 key=(null)
Hash: logrotate,logrotate_t,admin_home_t,file,getattr
从上述日志可以得出结论进程logrotate的type:logrotate_t与文件catalina.out的type:admin_home_t不匹配。
既然SELinux是讲究策略配置的,那我们配置一下策略不久可以了吗?
但是从网上找了半天,基本上没有介绍如何配置策略的,仔细阅读日志有个惊奇的发现,在日志的开头其实给出了策略配置命令!
allow this access for now by executing:
# ausearch -c 'logrotate' --raw | audit2allow -M my-logrotate
# semodule -i my-logrotate.pp
这两条命令其实就是策略配置的命令,第一条是从日志中获取logrotate执行失败的缘由,并分析为策略生成策略模块文件,第二条就是将策略模块导入系统。在执行命令是所在的目录下会生成两个文件my-logrotate.te和my-logrotate.pp,my-logrotate.pp为编译后的模块文件,my-logrotate.te为策略源文件。
有些SELinux命令系统没有默认安装,请自行搜索如何安装吧。
扩展知识:
1)Audit2allow
很重要的一个以python写的命令,主要用来处理日志,把日志中的违反策略的动作的记录,转换成 access vector,对开发安全策略非常有用。在refpolicy里,它的功能比以前有了很大的扩展。
[root@python log]# cat dmesg | audit2allow -m local > local.te
2)checkmodule -m -o local.mod local.te
编译模块
[root@python log]# checkmodule -m -o local.mod local.te
checkmodule: loading policy configuration from local.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 5) to local.mod
3)semodule_package
创建新的模块
[root@python log]# semodule_package -o local.pp -m local.mod
4)semodule
可以显示,加载,删除 模块
加载的例子:
[root@python log]# semodule -i local.pp
sesearch [-A] [-g] [-t] [-b]
-A :列出后面数据中,允许[读取或放行]的相关数据
-t:后面还要接类别,如-t httpd_t
-b:后面还要接SELinux的规则, httpd_enable_ftp_server
[root@localhost ~]# sesearch -A -s crond_t | grep spool
allow crond_t cron_spool_t : file { ioctl read getattr lock open } ;
allow crond_t var_spool_t : dir { ioctl read getattr lock search open } ;
allow daemon user_cron_spool_t : file { ioctl read write getattr lock append } ;
allow crond_t system_cron_spool_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow crond_t system_cron_spool_t : dir { ioctl read getattr lock search open } ;
allow crond_t cron_spool_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow 后面接着主机进程以及文件的SELinux type 意思是说,crond_t 可以读取system_cron_spool_t、 cron_spool_t 、 cron_spool_t 的文件/目录类型等。
以下摘自百度百科
定制策略
编辑
FC4,RHEL4等都是采用策略1.X版本的,并且是提供策略源代码的RPM包。从FC5开始策略的版本从1.X 升级到2.X。2.X版本的refpolicy(reference policy)最大的一个变化就是引进模块(module)这个概念,同一套策略源代码就可以支持Multi-LevelSecurity(MLS)和non-MLS。
标准的FC5里不提供源代码的RPM包。FC5提供的audit2allow,semanage,semodule也是可以开发一些简单的策略模块的。但是,要是作策略模块的开发,增加一个ROLE之类的,最好还是下载refpolicy的源代码。
⒌1策略源文件的安装
从CVS服务器下载的源代码是最新的,如果遇到象make的时候出错,那么最好就是把你系统里和SELinux有关的那些包更新到最新的状态。
安装好了的源代码目录结构如下图所示:
每一个模块有3个文件构成,比如上图的sudo.fc 就是和 命令sudo相关的文件的定义标签,(file context rabel),sudo.te是Type Enforcement定义,包括TE访问规则等,sudo.if是一个外部模块调用这个模块的接口定义。
[root@python src]# cd /etc/selinux/refpolicy/src/policy
[root@python policy]# cp build.conf build.
[root@python policy]# vi build.conf
[root@python policy]# diff build.conf build.
32c32
< DISTRO = redhat
---
> #DISTRO = redhat
43c43
< MONOLITHIC=n
---
> MONOLITHIC=y
[root@python src]# make conf
[root@python src]# make
这样,在/etc/selinux/refpolicy/src/policy下生成很多的以pp为后缀的文件,这些就是SELinux模块。接下来我们修改/etc/sysconfig/selinux,设成SELINUXTYPE=refpolicy,然后reboot.
启动后,确认策略的适用情况, 现在的版本是20。
[fu@python ~]$ /usr/sbin/sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: permissive
Policy version: 20
Policy from config file: refpolicy
⒌2给程序定制domain
开发程序策略的一般步骤
⒈给文件,端口之类的object赋予type 标签
⒉设置 Type Enforcement (Domain 迁移,访问许可)
⒊策略加载
⒋permissive模式下运行程序
⒌确认日志,用audit2allow生成访问许可
⒍重复1,2,3,4,5动作,直到没有违反的日志出现
⒎切换到enforcing模式,正式运用
因为我们所常用的那些服务的策略模块都已经有了,修改的时候也比较简单。在这里我就举个一般的例子。用点对点下载的朋友估计都跟我一样,在Linux上用 azureus,Amule来下载东西吧。
接下来以azureus为例,介召如何在FC5里追加一个azureus.pp模块。我们在追加azureus.pp模块之前,azureus是在系统给用户设好的user_t domain里运行。
[fu@python azureus]$ ps -efZ|grep azureus
user_u:user_r:user_t fu 1751 1732 0 22:28 pts/3 00:00:00 /bin/bash ./azureus
接下来我们在追加3个文件。
1)azureus.fc
在这里我只定义一个文件,实际要是真的用的,还要定义azureus_t能写的目录等。
[root@python apps]# more azureus.fc
/home/fu/azureus -- gen_context(user_u:object_r:azureus_exec_t,s0)
2)azureus.te
[root@python apps]# more azureus.te
policy_module(azureus,1.0.0)
type azureus_t;
type azureus_exec_t;
role user_r types azureus_t;
require {
type user_t;
};
domain_type(azureus_t)
domain_entry_file(azureus_t,azureus_exec_t)
domain_auto_trans(user_t,azureus_exec_t,azureus_t)
3)azureus.if
实际上没有别的模块要调用azureus,所以这个文件就是空文件也不要紧。
[root@python apps]# more azureus.if
# policy/modules/apps/azureus.if
## Myapp example policy
##
## Execute a domain transition to run azureus.
##
##