web-dev-qa-db-fra.com

Accès aux fichiers: l'ouverture échoue pour un programme mais pas pour un autre

C'est la chose la plus inhabituelle. J'essaie de démarrer mysqld avec un autre my.cnf (donc je peux avoir deux démons MySQL fonctionnant sans conflit). Le fichier est /etc/mysql/my2.cnf mais mysql ne l'ouvrira pas.

Lorsque j'exécute cette commande:

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

Je vois cela dans la sortie:

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)

Cependant, lorsque je change la commande en:

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

Je vois cela dans la sortie:

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

Même utilisateur - même appel au noyau - résultats différents!

J'ai vérifié les autorisations de fichier - et les autorisations étendues:

# 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

Suis-je en train de mordre par une partie d'AppArmour ou de SELinux? Je n'ai rien vu de tel dans les journaux (y compris daemon.log, syslog ou messages).

Comment résoudre ce problème?

5
Mei

Personne n'a répondu, alors je vais dire ce que j'ai découvert.

Le problème en bref est le suivant: lorsque le fichier /etc/mysql/my2.cnf est accessible par cat, nous voyons ceci:

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

Cependant, lorsque mysqld fait le même appel, il obtient une réponse différente:

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

Ainsi, la réponse réside dans le noyau. Quelque chose dans le noyau faisait la différence entre un appel à open (2) par cat et par mysqld. La seule chose qui m'est venue à l'esprit était AppArmor.

La recherche des packages sur le système a révélé plusieurs problèmes liés à AppArmor. La liste des fichiers dans les packages a révélé la commande apparmor_status; l'exécution de cela a montré que mysqld est en effet couvert par 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.

La lecture des pages de manuel pour apparmor (7) a montré que les profils étaient stockés dans /etc/apparmor.d; regarder ce répertoire fait apparaître le fichier usr.sbin.mysqld. Cela s'avère être le fichier à modifier.

La modification du fichier est simple, copiant les entrées des répertoires et fichiers standard d'origine et les transformant en nouveaux répertoires et fichiers. Une fois cela fait, activez la nouvelle configuration avec un service apparmor restart.

Je n'ai jamais vu de messages dans syslog sur "audit" (depuis AppArmor). La raison en est que les messages ont été envoyés à /var/log/audit/audit.log au lieu de syslog ou messages. Ce fichier contenait des entrées comme celles-ci:

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/"

Cela prouve mon raisonnement et mon enquête: AppArmor rejetait les demandes ouvertes (2).

Maintenant que je savais quoi chercher, j'ai trouvé des entrées de blog à ce sujet - n article depuis 2008.

4
Mei