背景:我有一台 CentOS 6 LAMP 服务器。最近服务器每隔几天就开始变得无响应。最初,mysqld 会抛出 nagios 警报,我什至无法 ssh 进入服务器,需要进行硬重置。 Mysqltuner 引导我增加缓冲池,这似乎有帮助。现在症状已更改为 nagios 抛出 apache http down 警报。这次我能够 ssh 进入服务器,但 apache 无法重新启动,需要重新启动。
查看 /var/log/messages 和 /var/log/audit/audit.log 后,我发现有数百个 AVC 错误。 audit.log 每天有几 MB,而我的其他服务器只有 kb 大小。这可能是解决根本问题的线索吗?
典型的 /var/log/messages 条目是这样的:
Mar 31 16:50:39 web1 setroubleshoot: SELinux is preventing /bin/ps from getattr access on the directory /proc/<pid>. For complete SELinux messages. run sealert -l be51d126-d70e-491f-9ec8-f897677d9989
通过 sealert 运行结果如下:
SELinux is preventing /bin/ps from getattr access on the directory /proc/<pid>.
***** Plugin catchall (100. confidence) suggests ***************************
If you believe that ps should be allowed getattr access on the <pid> directory 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:
# grep ps /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
这是audit.log 中的典型条目:
type=SYSCALL msg=audit(1427837702.229:721164): arch=c000003e syscall=4 success=no exit=-13 a0=8164d0 a1=3eaee11cc0 a2=
3eaee11cc0 a3=8164d6 items=0 ppid=2792 pid=2800 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48
fsgid=48 tty=(none) ses=4294967295 comm="ps" exe="/bin/ps" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1427837702.219:721127): avc: denied { getattr } for pid=2800 comm="ps" path="/proc/875" dev=proc
ino=9349054 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=dir
更新 好吧,几个月后又发生了。我还没有弄清楚为什么我的 LAMP 服务器时常冻结(我怀疑 MySQL,因为这是第一个抛出 nagios 警报的服务),但我知道为什么 SE Linux 警报(来自我最初的问题)正在发生的情况:托管的站点之一是 Magento 在线商店,每五分钟触发一次的 cron.php 脚本每次都会导致 SE Linux 错误。
所以我更新的问题是:除了我的消息和审核日志中的大量条目之外,还有什么值得担心的吗?
答案1
我终于能够缩小范围并解决问题。这是两个问题的结合:
服务器上的 Magento 站点在 vhosts 文件中被禁用。但 Magento cron 作业仍在运行、失败并导致所有 AVC 错误。删除孤立的 cron 作业可以阻止 AVC 错误。
然而,正如 Manuel Faux 在评论中指出的那样,SELinux 错误与服务器的随机崩溃无关。但是,随着 AVC 条目不再混乱我的日志文件,我能够在服务器冻结之前在 mysql 日志中找到以下内容:
InnoDB:警告:长时间信号量等待:--线程140485795231488已在btr0sea.c第1706行等待241.00秒信号量:在文件btr0sea.c第178行中创建的0x5583b18处RW锁存器上的X锁
那些关于信号量等待的日志让我想到了这一点相关问题。所以最终的解决方案是innodb_adaptive_hash_index = 0
在mysql配置中设置。
作为进一步的步骤,我还创建了每周 mysqlcheck 来优化所有数据库。几周过去了,mysql 或 SELinux 没有发生自发崩溃,也没有出现更多疯狂的错误日志。