Acesso a arquivos: a abertura falha para um programa, mas não para outro

5

Essa é a coisa mais incomum. Eu estou tentando iniciar o mysqld com um my.cnf diferente (para que eu possa ter dois daemons do MySQL rodando sem conflito). O arquivo é /etc/mysql/my2.cnf mas o mysql não irá abri-lo.

Quando eu executo este comando:

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

Eu vejo isso na saída:

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)

No entanto, quando eu altero o comando para:

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

Eu vejo isso na saída:

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

Mesmo usuário - mesma chamada ao kernel - resultados diferentes!

Eu verifiquei as permissões de arquivo e as permissões estendidas:

# 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

Estou sendo mordido por alguma parte do AppArmour ou do SELinux? Eu não vi nada parecido nos logs (incluindo daemon.log, syslog ou mensagens).

Como corrijo este problema?

    
por Mei 08.07.2011 / 18:23

1 resposta

4

Ninguém respondeu, então vou contar o que descobri.

O problema, em resumo, é o seguinte: quando o arquivo /etc/mysql/my2.cnf é acessado por cat , vemos isto:

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

No entanto, quando mysqld faz a mesma chamada, recebe uma resposta diferente:

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

Assim, a resposta está no kernel. Algo no kernel estava diferenciando entre uma chamada para abrir (2) por cat e por mysqld . A única coisa que me veio à mente foi o AppArmor.

Pesquisando os pacotes no sistema, surgiram vários relacionados ao AppArmor. Listar arquivos nos pacotes ativou o comando apparmor_status ; a execução disso mostrou que mysqld é realmente coberto pelo 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.

A leitura das páginas man do apparmor (7) mostrou que os perfis foram armazenados em /etc/apparmor.d ; olhando para este diretório, aparece o arquivo usr.sbin.mysqld . Isso acaba sendo o arquivo a ser modificado.

Modificar o arquivo é simples, copiando as entradas dos diretórios e arquivos padrão originais e transformando-os em novos diretórios e arquivos. Feito isso, ative a nova configuração com um service apparmor restart .

Eu nunca vi nenhuma mensagem no syslog sobre "audit" (do AppArmor). A razão para isso foi que as mensagens foram para /var/log/audit/audit.log em vez de syslog ou messages . Este arquivo continha entradas como estas:

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

Isso prova meu raciocínio e investigação: o AppArmor estava rejeitando as solicitações abertas (2).

Agora que eu sabia o que procurar, encontrei entradas de blog relacionadas a isso - um artigo de todo o caminho de volta em 2008.

    
por Mei 09.07.2011 / 01:12