Alimentar de forma segura un programa con una contraseña

9

Después de comprender el problema con el uso de una contraseña en la línea de comando , necesito encontrar una manera de alimentar un programa con una contraseña sin que sea un problema (sin que la contraseña se registre en alguna parte).

Tengo un script bash que instala automáticamente un servidor LAMP completo desde la fuente: Apache, FastCGI, PHP y MySQL. Estas instalaciones requieren una contraseña, especialmente MySQL.

¿Cómo puedo hacer que el script sea completamente automático sin revelar la contraseña?

Editar (9 de junio, 3:55 UTC):
estoy invocando mysql con una contraseña en la línea de comando, a través de root:

root@dor-desktop:/home/dor# PASS=`cat /home/dor/tmpf/pass`
root@dor-desktop:/home/dor# mysql -u root -p"$PASS"
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6

(PASS = "p4ssw0rd" en nuestro caso) ¡
Y ejecuto a ps aux | grep mysqltravés de mi usuario habitual (dor), que no me muestra la contraseña !
(Algunos de) psresultados son:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3562  0.0  0.0  34156  2864 pts/0    S+   05:53   0:00 mysql -u root -px xxxxxx

¿Como es eso posible?

Insecto
fuente
Consulte también unix.stackexchange.com/q/385339/135943 , pero tenga en cuenta que esto no lo hace seguro.
Comodín el

Respuestas:

11

Con respecto a su actualización:

Cuando se inicia un proceso, tiene un área de memoria dedicada donde se almacenan los argumentos y un int que indica cuántos argumentos se pasaron.

MEMORY
argc    2
argv[0] program_name
argv[1] foo
argv[2] bar

MySQL verifica si la contraseña se pasó en la línea de comando -py si se copió a una nueva variable que no es visible, luego sobrescriba esa región de memoria con x'es.

En términos simples, por ejemplo:

argc 2
argv[1] -p
argv[2] p4ssw0rd

new_var = copy(argv[2]);
argv[2] = "xxxxx";

Puede encontrarlo, por ejemplo, en client/mysqladmin.ccel código fuente:

  case 'p':
      ...
      opt_password=my_strdup(argument,MYF(MY_FAE));
      while (*argument) 
          *argument++= 'x';     /* Destroy argument */

Cuando se psejecuta, lee la región de memoria de los argumentos, ( argv[N]), y así es xxxx.

Por un tiempo muy corto la contraseña es visible, pero solo por unos pocos ciclos de CPU.


Puede actualizar la contraseña de MySQL utilizando la --init-fileopción y el procedimiento especiales. C.5.4.1.2. Restablecer la contraseña de root: sistemas Unix

mysqld_safe --init-file=/home/me/mysql-init &

Editar:

Como @Gilles decir, que pueda echo,printf o el uso herede documentos desde un script.

También puede agregar esto a .my.cnfsu directorio de inicio o en un archivo ( temporal ) y usar la --defaults-extra-fileopción. (Cree que debe agregar esa opción al principio de la línea de comando). Opcionalmente, también incluya user. También tenga en cuenta el extra en el nombre de la opción a menos que quiera usar solo ese archivo como configuración:

[client]
user=foo
password='password!'
shell> chmod 400 my_tmp.cnf
shell> mysql --defaults-extra-file=my_tmp.conf -...

Opcionalmente, la [client]agrupación hace que se mysqldomita la configuración.

También se puede usar MYSQL_PWDla variable de entorno, pero eso nunca se debe usar, ya que puede enumerar el entorno, en muchas psimplementaciones ps -e, en el /proc/<PID>/environarchivo en Linux, etc.

tr '\0' '\n' < /proc/<PID>/environ

Más sobre el tema aquí .

También es posible que desee echar un vistazo a la Utilidad de configuración de MySQL que le permite almacenar la contraseña en un archivo cifrado en su directorio de inicio .mylogin.cnf.

Runium
fuente
¿Hay alguna manera de cambiar un token en el mysql-initarchivo con la contraseña que se almacena en una variable bash? (sin ser revelado)
Dor
44
@Dor Algo así echo 'password=p4ssw0rd' >>mysql.cnfes seguro, ya que echoestá integrado, por lo que la contraseña no aparece en la línea de comandos de ningún proceso. Un documento aquí también es seguro.
Gilles 'SO- deja de ser malvado'
4

La solución típica es leer la contraseña de un archivo o de una entrada estándar (o de otro descriptor de archivo que debería pasarse como parámetro).

Hauke ​​Laging
fuente
3

Algunos programas (línea de comando, ftppor ejemplo) leen contraseñas del /dev/ttyarchivo especial por proceso que representa el TTY que controla el proceso. Esto permite que el programa no repita la contraseña en la pantalla y tenga un poco más de seguridad sobre el origen de la contraseña.

#!/bin/bash

stty -F /dev/tty -echo 
read PASSWORD < /dev/tty

echo $PASSWORD
Bruce Ediger
fuente