Tuve un error en el que un archivo de configuración para alguna aplicación no se incluía correctamente, así que para intentar aislar la línea problemática del archivo, copié el contenido antiguo en un archivo nuevo, unas pocas líneas a la vez.
Al final, había hecho un duplicado exacto del archivo, pero el antiguo aún no funcionaba, mientras que el nuevo funcionaba perfectamente bien.
Más concretamente, si uso el mv
comando para mover el archivo desde donde lo tengo almacenado al lugar donde quiere estar, se producen errores. Si copio cp
el archivo en el lugar que quiere, no hay errores.
Obviamente, cosas como diff
, file
o ls -l
no revelan diferencias entre los dos archivos porque uno es una copia del otro.en la medida en que cp
haga una copia exacta del archivo.
No puedo compartir demasiada información sobre el archivo porque es una cuestión de trabajo. La conclusión es que los comandos cp fileA fileB
y mv fileA fileB
producen un archivo B "diferente". Mi mejor suposición es que algún atributo de nivel súper bajo del archivo B queda atrás cp
(incluso cp -p
produce el mismo comportamiento).
¿En qué se diferencia mv de cp en relación con el contenido exacto del archivo resultante?
EDITAR: Con ls -l
:
-rw-r--r--. 1 root root 3389 Aug 8 22:53 fileA
-rw-r--r--. 1 root root 3389 Aug 8 23:03 fileB
EDITAR: La aplicación es mysql y el archivo es un archivo .cnf y el elemento de este archivo de configuración que fue específicamente de interés es el nombre del registro binario utilizado en la replicación de la base de datos maestro-esclavo. El "error" es "no está utilizando el registro binario" porque no hay ningún registro binario porque mysql nunca "leyó" ese elemento.
Mi pensamiento inicial fue que había un error de sintaxis en el archivo de configuración que hacía que no se leyera todo, lo que me llevó a recrearlo manualmente copiando bloques de texto.
EDITAR: Llegar a alguna parte... Finalmente algo diferente sobre los archivos.
ls -lZ
-rw-r--r--. root root unconfined_u:object_r:user_home_t:s0 server.cnf.bad
-rw-r--r--. root root unconfined_u:object_r:mysqld_etc_t:s0 server.cnf.good
Respuesta1
TL;DR: en un sistema dondeSELinuxestá en uso, los archivos utilizados por el sistema (es decir, demonios) deben copiarse o moverse con cp -aZ
y mv -Z
en lugar de cp -a
y mv
. Si esto no se hizo, uno debería simplemente usar restorecon -v -r
o restorecon -v -F -r
en el destino para pedirle al sistema que restaure los contextos SELinux predeterminados. Siempre es una buena idea utilizarrestorecon
al final de un script que funcionó en archivos de configuración clave.
RHEL y por tanto la mayoría de sus derivados.usar SELinux por defecto.
Entonces, para resolver su problema, si su sistema está basado en RHEL y usa el mariadb-server
paquete, simplemente hágalo en el paso final cuando el archivo esté en lalugar correcto:
# restorecon -v -F /etc/my.cnf.d/server.cnf
Relabeled /etc/my.cnf.d/server.cnf from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:mysqld_etc_t:s0
(Tenga en cuenta que sin -F
él no cambiaría unconfined_u
al configurado system_u
. No importaría para los sistemas comunes. Mi conocimiento de la diferencia y por qué no importa no llega tan lejos).
Sería simplemente más trabajo poner el contexto correcto en el archivo en unotrolugar.chcon
Puede hacer esto (ya sea indicándolo con -u
-t
etc., más simplemente copiando el contexto de otro archivo con --reference
):
# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 744 Apr 30 2017 /home/test/server.cnf.bad
# chcon -v -u system_u -t mysqld_etc_t /home/test/server.cnf.bad
changing security context of '/home/test/server.cnf.bad'
# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root system_u:object_r:mysqld_etc_t:s0 744 Apr 30 2017 /home/test/server.cnf.bad
Si sospecha que hay problemas con SELinux, busque /var/log/audit/audit.log
entradas con la palabra denied
relacionada con su proceso o archivo. Siempre puede pedirle temporalmente a SELinux que permita operaciones y luego restaurarlas, respectivamente setenforce Permissive
y setenforce Enforcing
para comparar el comportamiento. No lo dejes Permissive
especialmente para producción.
Varias explicaciones a continuación...
Ejemplo y qué se debe hacer al trabajar en archivos de configuración
Ejemplo de comportamiento con varias cp
opciones y mv
en un sistema habilitado para SELinux:
$ id
uid=1034(test) gid=1034(test) groups=1034(test)
$ pwd
/home/test
test@glasswalker:~$ ls -lZ foo
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 foo
$ cp foo /tmp/foo1
$ cp --preserve=context foo /tmp/foo2
$ cp -a foo /tmp/foo3
$ cp -aZ foo /tmp/foo4
$ mv foo /tmp/foo5
$ ls -lZ /tmp/foo?
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo1
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 /tmp/foo2
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 /tmp/foo3
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo4
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 /tmp/foo5
$ touch bar
$ ls -lZ bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:49 bar
$ mv -Z bar /tmp
$ ls -lZ /tmp/bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:49 /tmp/bar
Por lo tanto, usar cp -aZ
or mv -Z
funciona bien cuando los contextos de seguridad sí importan y aún conserva otros atributos. Un script que mueve archivos del sistema siempre debe usar la -Z
opción para cualquier comando cp
o mv
, o simplemente usarlo restorecon
en su paso final para evitar problemas inesperados.
¿Por qué esas diferencias?
El mv
comando mantiene un comportamiento consistente. Si sucediera en el mismo sistema de archivos, por supuesto, cualquier cosa adjunta a un archivo, incluido su contexto de seguridad, no se alteraría, ya que es solo un "cambio de nombre". Entonces, en dos sistemas de archivos, donde en realidad es una copia y luego se elimina, también copia sin cambios todo lo que está adjunto al archivo y lo conoce, incluido su contexto de seguridad, para mantener la coherencia.
El cp
comando por defecto simplementecreaun archivo nuevo, por lo que este archivo hereda el contexto selinux del padre como de costumbre, a menos que, por supuesto, se indique lo contrario con --preserve=context
el cual está incluido en -a
. --preserve=context
se puede restar -a
con la opción, -Z
por lo que la mejor opción al copiar arborescencias completas es usar -aZ
en lugar de -a
si SELinux sí importa.
De forma predeterminada, al crear un archivo, que es el caso habitual, este nuevo archivo hereda el contexto de su directorio SELinux, es por eso que todo funciona bien (fuera de tema: en el raro caso, el contexto del archivo debería ser diferente del contexto de su directorio solo por una regla sobre su nombre, al kernel no le importará, programas como el demoniorestorecond
será necesario para manejarlo).
¿Qué es SELinux?
SELinux es un mecanismo de control de acceso obligatorio (también conocido comoMAC) utilizado además de todos los demás mecanismos (permisos de Unix también conocidos comoCAD, Listas de control de acceso también conocidas comoLCAetc.). Cuando un proceso se ejecuta en un contexto de seguridad de proceso, hay una "matriz de reglas" para verificar si estoprocesoEl contexto puede realizar la operación solicitada (abrir, leer, escribir, mmap,...) en elarchivocontexto en el que intenta trabajar.
Ejemplo para el caso de OP: si el mysqld
contexto del proceso solo puede acceder a algunos tipos de contexto de archivos, incluidos mysqld_etc_t
pero no user_home_t
, el inicio mysqld
fallará porque no pudo leer su archivo de configuración con el user_home_t
tipo incorrecto.
En los sistemas habituales, esto no importa para el usuario interactivo/conectado, porque su contexto de proceso habitual no está limitado, lo que significa que no se aplicará ninguna regla SELinux. Cada demonio iniciado por systemd
u otros mecanismos similaresvoluntadrecibir un contexto de proceso, que se puede verificar con ps
la -Z
opción. Ejemplo en un sistema Debian que ejecuta SELinux:
# ps -Z -p $$
LABEL PID TTY TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 22498 pts/7 00:00:00 bash
# ps -Z -p $(pidof /sbin/getty)
LABEL PID TTY STAT TIME COMMAND
system_u:system_r:getty_t:s0 6158 tty1 Ss+ 0:00 /sbin/getty 38400 tty1
system_u:system_r:getty_t:s0 6159 tty2 Ss+ 0:00 /sbin/getty 38400 tty2
system_u:system_r:getty_t:s0 6160 tty3 Ss+ 0:00 /sbin/getty 38400 tty3
system_u:system_r:getty_t:s0 6161 tty4 Ss+ 0:00 /sbin/getty 38400 tty4
system_u:system_r:getty_t:s0 6162 tty5 Ss+ 0:00 /sbin/getty 38400 tty5
system_u:system_r:getty_t:s0 6163 tty6 Ss+ 0:00 /sbin/getty 38400 tty6
Respuesta2
Sí, hay una diferencia principal:
- cp hace una copia del archivo
- mv (si permanece dentro del sistema de archivos) simplemente mueve algunos punteros en el disco.
Pruebe lo siguiente:
touch a
ls -i a
cp a b
ls -i a b
mv a c
ls -i b c
Verá que b es un archivo nuevo con un nuevo número de inodo, mientras que c es el mismo archivo con el número de inodo del antiguo a.
Aún así, eso no explica tu extraño comportamiento.
Respuesta3
Esto es lo quepuedeestar sucediendo (compartes muy poca información sobre la aplicación o estos errores, así que solo puedo adivinar).
En Linuxel bloqueo obligatorio de archivos es poco común. Llamadas comoflock(2)
administrarconsultivoCerraduras. Esto significa que el kernel realiza un seguimiento de los bloqueos pero no los aplica, depende de las aplicaciones obedecerlos.
Si algo se bloquea fileA
y su aplicación obedece el bloqueo, puede rechazar el servicio. Supongamos que esto es lo que sucede.
El bloqueo afecta al inodo en lugar de a la ruta o al nombre. Mover (cambiar el nombre) el fileA
archivo bloqueado fileB
dentro de un único sistema de archivos no afecta al inodo, el archivo aún está bloqueado y la aplicación aún se niega a trabajar con él. Al copiar el archivo se crea un fileB
inodo separado que no está bloqueado y la aplicación funciona.
(Nota: mover un archivo a otro sistema de archivos es, de hecho, copiar+eliminar, por lo que debería romper el bloqueo, si lo hubiera).