selinux开启导致rsyslog无法输出日志到自定义文件的问题
目录一、故障现象二、故障原因三、解决方法一、故障现象在一台centos6上配置了环境,想输出iptables一些感兴趣的记录到log文件里,按照网上的一些教程,打算在数据盘中创建一个目录来存储iptables的日志,并据此配置了iptables,并在 /etc/rsyslog.d/ 中创建了rsyslog的配置文件:# 配置好iptalbes规则对80端口的新...
目录
一、故障现象
在一台centos6上配置了环境,想输出iptables一些感兴趣的记录到log文件里,按照网上的一些教程,打算在数据盘中创建一个目录来存储iptables的日志,并据此配置了iptables,并在 /etc/rsyslog.d/ 中创建了rsyslog的配置文件:
# 配置好iptalbes规则对80端口的新建连接写入日志,并添加日志前缀
# 需按照顺序匹配原则,80端口日志记录要在80端口的accpet规则之前
[root@localhost ~]# iptables -S
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j LOG --log-prefix "##Firewall##"
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
[root@localhost data]# vi /etc/rsyslog.d/iptables.conf
# 在iptalbes规则中设定日志前缀,并在rsyslog根据关键字筛选日志
# stop 是在rsyslog v5以后启用的新关键字,v5包括以前版本使用"~"符号来结束
:msg, contains, "##Firewall##" /data/log/iptables/iptables.log
& stop
用service rsyslogd restart重启rsyslogd服务,让配置生效。开始测试,结果发现log文件中什么都没有,根本没有写入日志,很奇怪。
二、故障原因
经过一顿折腾,终于在 /var/log/message发现蛛丝马迹。
[root@localhost data]# tail -n 100 /var/log/message
****** 以上皆略 ******
localhost rsyslogd-2039: Could not open output file '/data/log/iptables/iptables.log' [try http://www.rsyslog.com/e/2039 ]
无法打开配置的log文件,仔细查看了目录权限,没有问题。没办法上网搜索,在一个帖子中说关闭selinux即可。这时才想起查看selinux状态,自然是开启了。
[root@localhost data]# sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 24
Policy from config file: targeted
关闭selinux可以解决问题,那么追本溯源一下,为什么selinux导致了这个问题。因为自定义的路径的context不满足rsyslogd的访问权限,所以被selinux禁止访问了。
[root@localhost data]# ls -Z /data/log
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 log
对比/var/log/,发现所有运行rsyslogd访问的文件或目录的context都拥有var_log_t类型。系统根据规则自动对创建的文件或目录赋予指定的context。如果规则中没有我们自定义的路径,自然也就没办法给予var_log_t类型,rsyslogd就没有权限访问。如下图显示了部分默认拥有var_log_t权限的文件或目录。
[root@localhost data]# semanage fcontext -l | grep :var_log_t
/var/log/.* all files system_u:object_r:var_log_t:s0
/nsr/logs(/.*)? all files system_u:object_r:var_log_t:s0
/var/webmin(/.*)? all files system_u:object_r:var_log_t:s0
/var/log/secure[^/]* all files system_u:object_r:var_log_t:s0
/opt/zimbra/log(/.*)? all files system_u:object_r:var_log_t:s0
/var/log directory system_u:object_r:var_log_t:s0
/var/log/dmesg regular file system_u:object_r:var_log_t:s0
/var/log/syslog regular file system_u:object_r:var_log_t:s0
三、解决方法
知道了原因,我们只需要给自定义的文件添加到规则中,然后修复文件、目录的context,路径自然就获得了对应的类型,问题解决。
# 根据需要添加自定义的文件或目录
[root@localhost data]# semanage fcontext -a -t var_log_t "/data/log(/.*)?"
[root@localhost data]# semanage fcontext -a -t var_log_t "/data/log/.*"
[root@localhost data]# semanage fcontext -a -t var_log_t -f -d "/data/log"
# 修复目录及其子文件目录的context
[root@localhost data]# restorecon -Rv /data/log
# 重启rsyslogd,此时selinux可以运行rsyslog访问自定义的路径了
[root@localhost data]# service rsyslogd restart
更多推荐
所有评论(0)