目录

一、故障现象

二、故障原因

三、解决方法


一、故障现象

      在一台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

 

 

Logo

更多推荐