Bezpieczne karmienie programu hasłem

9

Po zrozumieniu problemu z użyciem hasła w wierszu poleceń muszę znaleźć sposób, aby podać hasło programu bez problemu (bez zapisania hasła gdzieś).

Mam skrypt bash, który automatycznie instaluje cały serwer LAMP ze źródła: Apache, FastCGI, PHP i MySQL. Te instalacje wymagają hasła, zwłaszcza MySQL.

Jak mogę w pełni zautomatyzować skrypt bez ujawniania hasła?

Edycja (9 czerwca, 3:55 UTC):
Wzywam mysql z hasłem w wierszu poleceń, poprzez 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" w naszym przypadku)
I wykonuję ps aux | grep mysqlprzez mojego zwykłego użytkownika (dor), który nie pokazuje mi hasła !
(Niektóre z) psdane wyjściowe to:

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

Jak to możliwe?

Dor
źródło
Zobacz także unix.stackexchange.com/q/385339/135943 , ale pamiętaj, że to nie czyni go bezpiecznym!
Wildcard

Odpowiedzi:

11

W odniesieniu do twojej aktualizacji:

Po uruchomieniu procesu ma on dedykowany obszar pamięci, w którym przechowywane są argumenty, oraz liczbę całkowitą, która podaje liczbę argumentów, które zostały przekazane.

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

MySQL sprawdza, czy hasło zostało przekazane w wierszu poleceń -p, a jeśli zostało skopiowane do nowej, niewidocznej zmiennej, następnie nadpisuje ten obszar pamięci xznakami „es”.

W prostych słowach np .:

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

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

Można go znaleźć np. W client/mysqladmin.cckodzie źródłowym:

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

Po psuruchomieniu odczytuje region pamięci argumentów ( argv[N]) i tak jest xxxx.

Przez bardzo krótki czas hasło jest widoczne, ale tylko przez kilka cykli procesora.


Możesz zaktualizować hasło MySQL za pomocą specjalnej --init-fileopcji i procedury. C.5.4.1.2. Resetowanie hasła roota: systemy uniksowe

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

Edytować:

Jak @Gilles powiedzieć można echo,printf lub użycie heredokument ze skryptu.

Możesz również dodać to do .my.cnfswojego katalogu domowego lub w ( tymczasowym ) pliku i użyć --defaults-extra-fileopcji. (Uwierz, że musisz dodać tę opcję wcześnie w wierszu poleceń.) Opcjonalnie możesz także dołączyć użytkownika. Zwróć także uwagę na dodatkowe w nazwie opcji, chyba że chcesz użyć tylko tego pliku jako konfiguracji:

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

Opcjonalnie [client]grupowanie powoduje mysqldpominięcie konfiguracji.

Można również użyć MYSQL_PWDzmiennej środowiskowej, ale nigdy nie należy jej używać, ponieważ można wyświetlić listę środowiska, w wielu psimplementacjach przez ps -e, w /proc/<PID>/environpliku w systemie Linux itp.

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

Więcej na ten temat tutaj .

Możesz także zajrzeć do narzędzia konfiguracyjnego MySQL, które umożliwia przechowywanie hasła w zaszyfrowanym pliku w katalogu domowym - .mylogin.cnf.

Runium
źródło
Czy istnieje sposób na zmianę tokena w mysql-initpliku za pomocą hasła przechowywanego w zmiennej bash? (bez ujawnienia)
Dor
4
@Dor Coś podobnego echo 'password=p4ssw0rd' >>mysql.cnfjest bezpieczne, ponieważ echojest wbudowane, więc hasło nie pojawia się w wierszu poleceń żadnego procesu. Dokument tutaj jest również bezpieczny.
Gilles „SO - przestań być zły”,
4

Typowym rozwiązaniem jest odczytanie hasła z pliku lub ze standardowego wejścia (lub z innego deskryptora pliku, który musiałby zostać przekazany jako parametr).

Hauke ​​Laging
źródło
3

Niektóre programy ( ftpna przykład wiersz poleceń ) odczytują hasła /dev/tty, specjalny plik na proces reprezentujący kontrolujący TTY proces. Pozwala to programowi nie wyświetlać hasła z powrotem na ekranie i mieć nieco większą pewność co do tego, skąd ono pochodzi.

#!/bin/bash

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

echo $PASSWORD
Bruce Ediger
źródło