文件访问:一个程序打开失败,但另一个程序打开成功

文件访问:一个程序打开失败,但另一个程序打开成功

这是最不寻常的事情。我试图用不同的 my.cnf 启动 mysqld(这样我就可以运行两个 MySQL 守护进程而不会发生冲突)。该文件是 /etc/mysql/my2.cnf,但 mysql 不会打开它。

当我运行此命令时:

sudo -u mysql strace /usr/sbin/mysqld --defaults-file=/etc/mysql/my2.cnf

我在输出中看到这一点:

stat("/etc/mysql/my2.cnf", {st_mode=S_IFREG|0644, st_size=3574, ...}) = 0
open("/etc/mysql/my2.cnf", O_RDONLY)    = -1 EACCES (Permission denied)

但是,当我将命令更改为:

sudo -u mysql strace cat /etc/mysql/my2.cnf > /dev/null

我在输出中看到这一点:

fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
open("/etc/mysql/my2.cnf", O_RDONLY)    = 3

相同的用户 - 相同的内核调用 - 不同的结果!

我检查了文件权限和扩展权限:

# ls -l $PWD/my2.cnf
-rw-r--r-- 1 root root 3574 2011-07-08 10:04 /etc/mysql/my2.cnf
# lsattr $PWD/my2.cnf
-----------------e- /etc/mysql/my2.cnf

我是不是被 AppArmour 或 SELinux 的某些部分影响了?我在日志(包括 daemon.log、syslog 或消息)中没有看到类似的东西。

我该如何解决这个问题?

答案1

没有人回答,所以我就告诉我的发现。

简而言之,问题如下:当文件/etc/mysql/my2.cnf被访问时cat,我们会看到以下内容:

open("/etc/mysql/my2.cnf", O_RDONLY)    = 3

然而,当mysqld进行相同的调用时,它会得到不同的答案:

open("/etc/mysql/my2.cnf", O_RDONLY)    = -1 EACCES (Permission denied)

因此,答案就在内核中。内核中的某些东西区分了对 open(2) bycat和 by 的调用mysqld。唯一想到的就是 AppArmor。

搜索系统上的软件包,结果显示有多个与 AppArmor 相关的软件包。列出软件包中的文件后,出现了命令apparmor_status;运行该命令后,发现mysqld确实包含在 AppArmor 中:

# apparmor_status
apparmor module is loaded.
6 profiles are loaded.
6 profiles are in enforce mode.
   /sbin/dhclient3
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/connman/scripts/dhclient-script
   /usr/sbin/mysqld
   /usr/sbin/ntpd
   /usr/sbin/tcpdump
0 profiles are in complain mode.
3 processes have profiles defined.
3 processes are in enforce mode :
   /usr/sbin/mysqld (22699) 
   /usr/sbin/mysqld (6808) 
   /usr/sbin/ntpd (2800) 
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

阅读 apparmor(7) 的手册页显示配置文件存储在 中/etc/apparmor.d;查看此目录会找到文件usr.sbin.mysqld。这原来是要修改的文件。

修改文件很简单,复制原始标准目录和文件的条目并将它们放入新目录和文件中。完成后,使用 激活新配置service apparmor restart

我从未在系统日志中看到任何有关“审计”的消息(来自 AppArmor)。原因是消息发送到/var/log/audit/audit.log而不是syslogmessages。此文件包含如下条目:

type=APPARMOR_DENIED msg=audit(1310141055.025:256):  operation="mknod" pid=28765 parent=28764 profile="/usr/sbin/mysqld" requested_mask="c::" de
nied_mask="c::" fsuid=104 ouid=104 name="/var/log/mysql2/error.log"
type=APPARMOR_DENIED msg=audit(1310141055.025:257):  operation="open" pid=28765 parent=28764 profile="/usr/sbin/mysqld" requested_mask="r::" den
ied_mask="r::" fsuid=104 ouid=104 name="/var/lib/mysql2/mysql/plugin.frm"
type=APPARMOR_DENIED msg=audit(1310141055.035:258):  operation="open" pid=28765 parent=28764 profile="/usr/sbin/mysqld" requested_mask="rw::" de
nied_mask="rw::" fsuid=104 ouid=104 name="/var/lib/mysql2/ibdata1"
type=APPARMOR_DENIED msg=audit(1310141097.085:259):  operation="open" pid=28780 parent=28779 profile="/usr/sbin/mysqld" requested_mask="::r" den
ied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141177.636:260):  operation="open" pid=28841 parent=28840 profile="/usr/sbin/mysqld" requested_mask="::r" den
ied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141614.953:261):  operation="open" pid=28903 parent=28902 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141665.113:262):  operation="open" pid=28916 parent=28915 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310141739.863:263):  operation="open" pid=28926 parent=28925 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/my2.cnf"
type=APPARMOR_DENIED msg=audit(1310142253.323:264):  operation="open" pid=28962 parent=19377 profile="/usr/sbin/mysqld" requested_mask="::r" denied_mask="::r" fsuid=104 ouid=0 name="/etc/mysql/conf2.d/"

这证明了我的推理和调查:AppArmor 拒绝了 open(2) 请求。

现在我知道要寻找什么了,我找到了与此相关的博客条目 -一篇文章从 2008 年开始。

相关内容