Alimentação segura de um programa com uma senha

9

Depois de entender o problema de usar uma senha na linha de comando , preciso encontrar uma maneira de alimentar um programa com uma senha sem que isso seja um problema (sem que a senha seja registrada em algum lugar).

Eu tenho um script bash que instala automaticamente um servidor LAMP inteiro a partir da fonte: Apache, FastCGI, PHP e MySQL. Essas instalações requerem uma senha, especialmente MySQL.

Como posso tornar o script totalmente automatizado sem revelar a senha?

Edit (9 de junho, 3:55 UTC):
Estou invocando o mysql com uma senha na linha de comando, 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" no nosso caso)
E executo ps aux | grep mysqlvia meu usuário comum (dor), que não me mostra a senha !
(Parte da) pssaída é:

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 isso é possível?

Dor
fonte
Consulte também unix.stackexchange.com/q/385339/135943 , mas observe que isso não o torna seguro!
Curinga

Respostas:

11

Em relação à sua atualização:

Quando um processo é iniciado, ele possui uma área dedicada da memória, na qual os argumentos são armazenados e um int que informa quantos argumentos foram passados.

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

O MySQL verifica se a senha foi passada na linha de comando -pe se foi copiada para uma nova variável que não é visível, em seguida, sobrescreva a região da memória com x'es.

Em termos simples, por exemplo:

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

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

Você pode encontrá-lo, por exemplo, no client/mysqladmin.cccódigo-fonte:

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

Quando psexecutado, ele lê a região de memória dos argumentos ( argv[N]) e, portanto, é xxxx.

Por um tempo muito curto, a senha fica visível, mas apenas por alguns ciclos de CPU.


Você pode atualizar a senha do MySQL usando a --init-fileopção e procedimento especiais . C.5.4.1.2 Redefinindo a senha raiz: sistemas Unix

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

Editar:

Como @Gilles dizer, você pode echo,printf ou o uso herede documentos a partir de um script.

Você também pode adicioná-lo ao .my.cnfseu diretório pessoal ou em um arquivo ( temporário ) e usar a --defaults-extra-fileopção (Acredite que você deve adicionar essa opção logo no início da linha de comando.) Opcionalmente, inclua também user. Observe também o extra no nome da opção, a menos que você queira usar apenas esse arquivo como configuração:

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

Opcionalmente, o [client]agrupamento faz mysqldpular a configuração.

Também é possível usar MYSQL_PWDvariável de ambiente, mas isso nunca deve ser usado, pois você pode listar o ambiente, em muitas psimplementações ps -e, no /proc/<PID>/environarquivo no Linux etc.

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

Mais sobre o tópico aqui .

Você também pode querer dar uma olhada no MySQL Configuration Utility, que permite armazenar a senha em um arquivo criptografado em seu diretório pessoal - .mylogin.cnf.

Runium
fonte
Existe uma maneira de alterar um token no mysql-initarquivo com a senha armazenada em uma variável bash? (sem ser revelada)
Dor
4
@Dor Algo parecido echo 'password=p4ssw0rd' >>mysql.cnfé seguro, porque echoé embutido, portanto a senha não aparece na linha de comando de nenhum processo. Um documento aqui também é seguro.
Gilles 'SO- stop be evil'
4

A solução típica é ler a senha de um arquivo ou da entrada padrão (ou de outro descritor de arquivo que precisaria ser passado como parâmetro).

Hauke ​​Laging
fonte
3

Alguns programas (linha de comando, ftppor exemplo) leem senhas /dev/tty, o arquivo especial por processo que representa o TTY de controle do processo. Isso permite que o programa não faça eco da senha de volta à tela e tenha um pouco mais de garantia sobre a origem da senha.

#!/bin/bash

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

echo $PASSWORD
Bruce Ediger
fonte