Usando mysqldump en el trabajo cron sin contraseña de root

14

Si inicio sesión con la contraseña de root en mi casilla, simplemente puedo escribir

mysqldump --all-bases de datos y obtendré el "Dump" esperado.

Configuré un trabajo en cron.daily para ejecutarlo y volcarlo en una unidad de respaldo. El problema que tengo es que, aunque el usuario se está ejecutando como root, recibo el siguiente mensaje

mysqldump: Error obtenido: 1045: Acceso denegado para el usuario 'root' @ 'localhost' (usando la contraseña: NO)

cuando intentas conectarte. Yo no quiero codificar la contraseña de root base de datos MySQL en el guión (que lo haría).

Teniendo en cuenta que solo puedo escribir "mysqldump" en la línea de comando en mi shell bash, debe haber alguna forma de moverse usando el parámetro -u. Ya tengo #! / Bin / bash en la parte superior del script.

¿Qué me estoy perdiendo aquí para que esto no pida la contraseña de root a la base de datos?

Software Mech
fuente

Respuestas:

12

Para conectarse al servidor mysql debe proporcionar credenciales. Puede especificarlos en un archivo de configuración, pasarlos a través de la línea de comandos o simplemente crear una cuenta que no requiera credenciales.

Por supuesto, la opción sin contraseña nunca debe usarse, la línea de comando de paso no es excelente porque cualquiera que pueda ejecutar ps puede ver la línea de comando.

La opción recomendada es crear un archivo de configuración mysql con las credenciales y luego proteger ese archivo con permisos del sistema de archivos para que solo su usuario de respaldo pueda acceder a él.

El hecho de poder iniciar sesión en el servidor mysql mientras está conectado de manera interactiva como root parece sugerir que no tiene establecida una contraseña de root o que tiene un archivo de configuración que su script no encuentra. Si tiene un .my.cnf, es posible que deba señalarlo manualmente. Si su cuenta raíz no tiene una contraseña establecida, le recomiendo encarecidamente que lo arregle.

Actualización (2016-06-29) Si está ejecutando mysql 5.6.6 o superior, debe consultar la herramienta mysql_config_editor que le permite almacenar credenciales en un archivo cifrado. Gracias a Giovanni por mencionarme esto.

Zoredache
fuente
1
Ese método todavía requiere una contraseña sin cifrar en texto sin formato para estar en el sistema. Eso es lo que estoy tratando de evitar.
Mech Software
> no tiene establecida una contraseña de root o tiene un archivo de configuración que su script no encuentra. El autor declara claramente que hay una contraseña mysql para root, y que está intentando acceder a la base de datos sin proporcionarla al comando mysqldump: "(usando la contraseña: NO)". De ahí el error de acceso denegado.
monomyth
1
@monomyth, el autor también afirma que puede iniciar sesión sin una contraseña mientras está conectado de forma interactiva como root. Esto me dice que algo no está bien.
Zoredache
2
@Mech Software, no tiene mucho sentido tratar de protegerse de la cuenta raíz. Si alguien tiene la cuenta raíz, simplemente puede reiniciar mysql y omitir por completo el sistema de permisos.
Zoredache
1
La razón por la que pude iniciar sesión fue porque la cuenta raíz tenía un .my.cnf especificado con 600 permisos, así que así es como el shell estaba obteniendo acceso. Sin embargo, cron debe ignorar el archivo, así que usé el parámetro en esta publicación para señalarlo.
Mech Software
3

La seguridad no debe hacerse a través de la oscuridad. Si temes que alguien tenga acceso a tu cuenta de root, no importa si la contraseña de mysql de root está almacenada en el script, ya que tienes todos tus datos disponibles en volcados de mysql o archivos de base de datos. Entonces, la verdadera pregunta es ¿qué estás tratando de proteger?

Si no desea que otros obtengan una contraseña que les permita cambiar los datos en su base de datos, deberá crear un usuario con los permisos adecuados .

Si no desea que esa cuenta mysql sea vista por ninguna cuenta local, excepto los permisos de archivos del conjunto raíz en ese script para que sean 0700 y el propietario de la raíz.

monomito
fuente
1
Supongo que lo que aún no entiendo es que si puedo escribir (desde el indicador raíz) mysqldump sin ingresar una contraseña, ¿por qué no puedo ejecutarlo a través del trabajo cron de la misma manera? Qué pieza falta que requiere el parámetro -p. No estoy tratando de "ocultar" la contraseña, prefiero nunca tenerla ingresada. Algo particular en el inicio de sesión raíz está permitiendo el acceso, entonces, ¿por qué no se puede replicar con cron?
Mech Software
Si ve que puede iniciar sesión sin una contraseña y con una contraseña utilizando el mismo usuario "root", es posible que haya múltiples usuarios root en su base de datos mysql. Algunos de ellos pueden no tener una contraseña establecida. Puede eliminar la contraseña de 'root' @ 'localhost', pero no solo cron podrá conectarse a su base de datos, sino a cualquier persona con una cuenta local. Esto no es diferente (o peor) que tener una contraseña en un script de texto claro.
monomyth
Creo que el punto es que MechSoftware estaba haciendo que ser root esencialmente te da acceso de lectura a los archivos de la base de datos, y no están encriptados. Por lo tanto, exigir la contraseña de MySQL raíz del usuario raíz solo para imprimir de manera bonita los datos a los que esencialmente ya pueden acceder es "seguridad a través de la oscuridad". Además, los permisos son muy fáciles de estropear, por ejemplo, si alguien les está fijando de forma recursiva para un directorio, si hay un enlace simbólico al archivo etc
Septagram
2

Su uso de shell puede hacerlo porque tiene un shell para ejecutarlo, es decir, cuando inicia sesión, todos los scripts de shell en su perfil se ejecutan.

Cron no tiene tales lujos. Cuando inicia sesión (como root), iniciará sesión con un shell predeterminado. Esto evita que alguien inicie sesión de forma remota, pero también significa que no se ejecutan scripts de inicio de sesión automático.

Puede configurar un shell para que se ejecute cron, editar el crontab y agregar las variables SHELL y HOME, por ejemplo.

SHELL=/bin/bash
HOME=/root

si no están configurados, cron se ejecutará con el shell y el directorio de inicio especificados en / etc / passwd (que probablemente no sean nada, posiblemente / bin / sh).

Si desea ver el entorno en el que se ejecuta cron, agregue un trabajo cron que exporta env a un archivo, por ejemplo:

$crontab -e
* * * * * env > /tmp/crontabenv.log
:wq
gbjbaanb
fuente
1

Si el script es ejecutado por root, puede crear un archivo /root/.my.cnf con permisos 600 y los siguientes contenidos:

[client]
user = DBUSERNAME
password = DBPASSWORD

(donde ingresas tu nombre de usuario y contraseña de MySQL, por supuesto).

Este archivo será leído automáticamente por cualquier herramienta de línea de comandos mysql, si se ejecuta como root. Ya no es necesario proporcionarlo en la línea de comandos. Los 600 permisos lo protegen contra miradas indiscretas.

Martijn Heemels
fuente
1
Encontré que este era el caso de CÓMO pude usar mysqldump sin la contraseña. Entonces esto resolvió el misterio de cómo SHELL lo está haciendo, entonces ¿por qué cron no lo está leyendo?
Mech Software
1
mysqldump cuando se ejecuta desde cron puede no ser capaz de localizar el archivo .my.cnf. El remedio es agregar un parámetro mysqldump para leer explícitamente las opciones en el archivo.my.cnf, es decir, --defaults-extra-file = / root / .my.cnf. Aprendí esto de otras dos respuestas en Stack Overflow. Ver stackoverflow.com/a/602054/854680 y stackoverflow.com/a/890554/854680
MikeOnline
1

Cron puede ser muy frustrante para depurar. Cuando se ejecutan los trabajos cron, no tienen un entorno establecido como el que das por sentado con un shell.

Consejos para cron:

  • use rutas completas para todo: "ECHO = / bin / echo", etc.: (defina variables en la parte superior para que sea más fácil)
  • configure MAILTO, para que reciba un correo electrónico de cada trabajo (o haga que los trabajos redirijan stderr / stdout a un archivo)

Si su usuario root puede hacerlo desde el shell, cron debería poder hacerlo. Asegúrese de especificar explícitamente el archivo de configuración para usar en la línea de comandos.


fuente
0

Aunque varias de estas respuestas son útiles, varias son confusas porque el usuario raíz de Unix y el usuario raíz de mysql no son iguales y, básicamente, no tienen otra relación que no sea que ambos usan el nombre de usuario 'root'. Tal vez eso sea obvio, pero parece que algunas respuestas combinan los dos.

Lo que podría ser una opción útil (¿tal vez existe?) Para mysqld sería permitir que los programas cliente como mysql o mysqldump, etc., que se ejecutan como raíz de Unix accedan a root @ localhost de mysqld sin una contraseña sin tener que almacenar la contraseña de root @ localhost (mysql) en un archivo my.cnf o similar.

Sé que eso pone un poco nervioso, pero el razonamiento es que cualquiera que se ejecute como unix root local (para el servidor mysqld) puede eludir la seguridad de mysqld de todos modos, con bastante facilidad. Y tener un my.cnf con la contraseña de root de mysqld 7x24 o incluso crear / eliminar un my.cnf con la contraseña de root de mysql (¿de dónde viene esa contraseña?) Sobre la marcha (por ejemplo, hacer un mysqldump) me pone nervioso.

Requeriría algo de infraestructura y pensamiento porque uno tendría que confiar en mysql / mysqldump / etc para transmitir a mysqld que realmente cree que está siendo ejecutado por una cuenta raíz local de Unix.

Pero, por ejemplo, limitar solo el socket unix de mysqld, sin TCP, podría ayudar, al menos como una opción muy recomendada de esta opción. Eso podría establecer que el cliente se ejecuta localmente, aunque eso probablemente no sea suficiente. Pero podría ser el comienzo de una idea. Quizás enviar un descriptor de archivo a través de un zócalo Unix podría ser otra pieza (busque en Google si eso suena como una locura).

PD No, no voy a tratar de hacer una lluvia de ideas aquí sobre cómo algo de eso podría funcionar en un sistema operativo no Unix, aunque la idea probablemente se traduzca en otros sistemas operativos.

Barry Shein
fuente
1
Poner las credenciales /root/.my.cnfcon los permisos adecuados resuelve perfectamente el problema.
Michael Hampton
No estoy de acuerdo, ahora cualquiera que pueda acceder a ese archivo, incluso a través de algún otro defecto del sistema, tiene la raíz de mysql pw. Y está ahí para ser atacado las 24 horas del día, los 7 días de la semana, y en una ubicación de archivo fija (aunque ciertamente no tendría que estar en / root). Pero, por ejemplo, quien ejecuta volcados del sistema de archivos, o puede acceder a uno, puede sacarlo de un archivo de volcado del sistema de archivos. En ese caso, suena como una tentación para un empleado descontento. Creo que es un objetivo razonable que no existan contraseñas de texto sin cifrar en un sistema, en ningún lugar.
Barry Shein
Tal vez sea así, pero la propuesta que ha hecho es mucho peor, ya que permite que cualquier usuario local finja trivialmente ser root.
Michael Hampton
No, mi propuesta era que ya tenían que ser unix root en el servidor local, en cuyo caso el mysqld local confía en que mysql o mysqldump, etc. (cliente) se ejecutan como unix root y les permite proceder como si se hubieran autenticado como mysql root . Como dije, si ya son unix root local para el servidor, de todos modos pueden omitir la contraseña de root de mysql con algunos comandos bien documentados ("recuperación de contraseña de root de mysql").
Barry Shein