![SELinux + logrotate + prerotate = 权限被拒绝](https://linux22.com/image/61471/SELinux%20%2B%20logrotate%20%2B%20prerotate%20%3D%20%E6%9D%83%E9%99%90%E8%A2%AB%E6%8B%92%E7%BB%9D.png)
我有一个(应该)相当简单的任务:晚上将一组自定义日志文件迁移到数据库。
我使用 logrotate (cron.daily) 进行简单的预轮换任务
/var/log/myapplog/*.log
{
daily
copytruncate
rotate 366
dateext
dateformat .%Y-%m-%d
compress
missingok
compresscmd /usr/bin/xz
compressoptions -ze9
compressext .xz
prerotate
/usr/local/myapp/bin/DBWriter $1
endscript
}
不幸的是 SELinux 并不这么认为。如果我setenforce 0
那么脚本就可以完美运行。轮换日志,将它们发送到数据库等
setenforce 1
,但是返回:
logrotate_script: line 1: /usr/local/myapp/bin/DBWriter: Permission denied
我尝试过更改 DBWriter 上的上下文,最近我将其设置为unconfined_u:unconfined_r:unconfined_t
也不起作用......
理想情况下,我需要保持 SELinux 启用。如果重要的话,DBWriter 也可以作为 java .jar 文件使用。但跑步也java -jar DBWriter.jar
有同样的结果。
提前致谢!
编辑:Win.T 下面的答案解决了我的问题。
semanage permissive -a logrotate_t
部分问题是我试图做的确切地SELinux 旨在防止什么:导致进程 A 执行未知文件 B 并对系统 C 造成严重破坏
项目设计的考虑和限制使我们走上了这条道路。
客户并不总是想听到安全性和面向未来等花哨的流行语。
答案1
查看/var/log/messages
和/var/log/audit/audit.log
(如果您正在auditd
跑步)。您还可以用来audit2allow
查看 SELinux 错误消息和可能的解决方案。
此外,尝试semanage permissive -a logrotate_t
允许 logrotate 运行并且不被 SELinux 拒绝。
答案2
如果您不确定它是 SELinux,请首先尝试暂时禁用 SELinux 强制sudo setenforce 0
SELinux 参考并运行失败的代码。如果是 SELinux 继续阅读..
我最近遇到了这个问题,并且对 SELinux 非常不熟悉,所以这对我来说是一个学习曲线。与使用chmod
& 的(DAC) 标准 posix 模式权限不同chown
,SELinux 的权限更加细化。在某些情况下,它会拒绝特定操作,例如通过 TCP/443 连接到互联网,或允许写入 /foo 和 /bar,但不写入其他内容等,具体取决于调用者(应用程序)。
要查看文件(MAC)强制访问控制权限ls -Z
或用户,id -Z
请使用以下格式的输出user:role:type:level
。
就我在 Centos7 上的情况而言,我在 logrotate.d conf 文件中调用了一个脚本,其中包含一个预旋转脚本,该脚本会在旋转之前上传日志文件。我有几次否认(登录到/var/log/audit/audit.log
)。我了解到您可以使用一些工具来生成要安装的特定策略包。我正在为我们的代码创建 .rpm 包,因此我将以下所有步骤添加到 .spec 文件中,以在安装期间生成并安装策略包。
你需要什么:policycoreutils-python、checkpolicy(可能已安装)
据我了解,如果您计划分发此安全策略,您的想法是您只想发送 *.te 文件并现场生成策略,因此如果策略依赖的定义得到更新,它们将在安装时继承。
#查找拒绝消息
watch "tail /var/log/audit/audit.log | grep 'denied'"
# 创建 te(类型强制)文件(人类可读的安全策略)
grep 1561055176.928:11371 /var/log/audit/audit.log|audit2allow -m myapp > myapp.te
# 你还可以 grep 一些失败并将它们全部通过管道传输到audit2allow
cat /var/log/audit/audit.log | grep logrotate | audit2allow -m myapp > myapp.te
# 您还可以使用audit2why 来稍微解释一下为什么修复步骤有时会失败
cat /var/log/audit/audit.log | grep logrotate | audit2why
警告在此步骤中,我发现audit2why报告如果我运行的话我的脚本会起作用setsebool -P nis_enabled 1
。虽然这听起来不错,但你应该总是查找运行这些命令的安全隐患。设置此项可能会扩大您的攻击面,因此用户要小心。
# 从类型强制文件构建策略模块
checkmodule -M -m -o myapp.mod myapp.te
# 从策略模块构建策略包
semodule_package -o myapp.pp -m myapp.mod
# 使用 root 权限加载策略包
semodule -i myapp.pp
我必须多次执行这些步骤,直到积累了代码运行所需的所有微小权限。
- 更新 -
我最终在 logrotate cron 任务之前内联运行脚本,这样我就不必扩展 logrotate_t 的权限。我将其置于预旋转中,因为我不想在失败时旋转文件,而此语法仍然满足这一要求。使用“&&”语法,如果第一个命令失败,则不会执行第二个命令。
10 * * * * root /usr/bin/sudo -i -u otheruser /opt/send_logs.sh && /usr/sbin/logrotate -f /path/to/myapp_logrotate.conf > /tmp/myapp_rotate.log 2&1