Alimentation sécurisée d'un programme avec un mot de passe


9

Après avoir compris le problème de l'utilisation d'un mot de passe dans la ligne de commande , je dois trouver un moyen d'alimenter un programme avec un mot de passe sans que cela soit un problème (sans que le mot de passe soit enregistré quelque part).

J'ai un script bash qui installe automatiquement un serveur LAMP entier à partir de la source: Apache, FastCGI, PHP & MySQL. Ces installations nécessitent un mot de passe, en particulier MySQL.

Comment rendre le script entièrement automatisé sans révéler le mot de passe?

Edit (9 juin, 3:55 UTC):
J'invoque mysql avec un mot de passe sur la ligne de commande, via 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" dans notre cas)
Et j'exécute ps aux | grep mysqlvia mon utilisateur habituel (dor), qui ne me montre pas le mot de passe !
(Une partie de) la pssortie est:

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

Comment est-ce possible?


Voir aussi unix.stackexchange.com/q/385339/135943 , mais notez que cela ne le rend pas sûr!
Wildcard

Réponses:


11

Concernant votre mise à jour:

Lorsqu'un processus est démarré, il a une zone de mémoire dédiée où les arguments sont stockés et un int qui indique combien d'arguments ont été passés.

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

MySQL vérifie si le mot de passe a été passé sur la ligne de commande -pet s'il l'a copié dans une nouvelle variable qui n'est pas visible, puis écrasez cette région de mémoire avec x'es.

En termes simples, par exemple:

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

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

Vous pouvez le trouver par exemple dans client/mysqladmin.ccle code source:

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

Lorsqu'il est psexécuté, il lit la région mémoire des arguments, ( argv[N]), et c'est ainsi xxxx.

Pendant très peu de temps, le mot de passe est visible, mais seulement pour quelques cycles CPU.


Vous pouvez mettre à jour le mot de passe MySQL en utilisant l' --init-fileoption et la procédure spéciales . C.5.4.1.2. Réinitialisation du mot de passe root: systèmes Unix

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

Éditer:

Comme le dit @Gilles , vous pouvez echo,printf ou utiliser un heredocument à partir d'un script.

Vous pouvez également l'ajouter à .my.cnfvotre répertoire personnel ou dans un fichier ( temporaire ) et utiliser l' --defaults-extra-fileoption. (Croyez que vous devez ajouter cette option au début de la ligne de commande.) Incluez également éventuellement l'utilisateur. Notez également le supplément dans le nom de l'option, sauf si vous souhaitez utiliser uniquement ce fichier comme configuration:

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

Facultativement, le [client]regroupement fait mysqldsauter la configuration.

On peut également utiliser MYSQL_PWDla variable d'environnement, mais cela ne devrait jamais être utilisé car vous pouvez lister l'environnement, dans de nombreuses psimplémentations par ps -e, dans le /proc/<PID>/environfichier sur Linux, etc.

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

Plus d'informations sur le sujet ici .

Vous voudrez peut-être également jeter un œil à l' utilitaire de configuration MySQL qui vous permet de stocker le mot de passe dans un fichier crypté dans votre répertoire personnel - .mylogin.cnf.


Existe-t-il un moyen de modifier un jeton dans le mysql-initfichier avec le mot de passe stocké dans une variable bash? (sans être révélé)
Dor

4
@Dor Quelque chose comme echo 'password=p4ssw0rd' >>mysql.cnfest sûr, car il echoest intégré, donc le mot de passe n'apparaît sur la ligne de commande d'aucun processus. Un document ici est également sûr.
Gilles 'SO- arrête d'être méchant'

4

La solution typique consiste à lire le mot de passe à partir d'un fichier ou d'une entrée standard (ou d'un autre descripteur de fichier qui devrait être passé en paramètre).


3

Certains programmes (ligne de commande ftppar exemple) lisent les mots de passe /dev/tty, le fichier spécial par processus qui représente le TTY de contrôle du processus. Cela permet au programme de ne pas renvoyer le mot de passe à l'écran et d'avoir un peu plus d'assurance sur la provenance du mot de passe.

#!/bin/bash

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

echo $PASSWORD
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.