Sicheres Füttern eines Programms mit einem Passwort

9

Nachdem ich das Problem mit der Verwendung eines Kennworts in der Befehlszeile verstanden habe , muss ich einen Weg finden, ein Programm mit einem Kennwort zu füttern, ohne dass dies ein Problem darstellt (ohne dass das Kennwort irgendwo aufgezeichnet wird).

Ich habe ein Bash-Skript, das automatisch einen gesamten LAMP-Server von der Quelle installiert: Apache, FastCGI, PHP und MySQL. Diese Installationen erfordern ein Passwort, insbesondere MySQL.

Wie kann ich das Skript vollständig automatisieren, ohne das Passwort preiszugeben?

Bearbeiten (9. Juni, 3:55 UTC):
Ich rufe MySQL mit einem Passwort in der Befehlszeile über root auf:

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" in unserem Fall)
Und ich führe ps aux | grep mysqlüber meinen regulären Benutzer (dor) aus, der mir das Passwort nicht anzeigt !
(Einige von) psAusgaben sind:

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

Wie ist das möglich?

Dor
quelle
Siehe auch unix.stackexchange.com/q/385339/135943 , aber beachten Sie, dass dies nicht sicher ist!
Wildcard

Antworten:

11

In Bezug auf Ihr Update:

Wenn ein Prozess gestartet wird, verfügt er über einen dedizierten Speicherbereich, in dem Argumente gespeichert sind, und ein int, das angibt, wie viele Argumente übergeben wurden.

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

MySQL prüft, ob das Kennwort in der Befehlszeile von übergeben -pwurde und ob es in eine neue Variable kopiert wurde, die nicht sichtbar ist, und überschreibt diesen Speicherbereich mit x'es.

In einfachen Worten zB:

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

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

Sie finden es zB im client/mysqladmin.ccQuellcode:

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

Beim psAusführen liest es den Speicherbereich der Argumente ( argv[N]) und ist es somit xxxx.

Für eine sehr kurze Zeit ist das Passwort sichtbar, aber nur für einige CPU-Zyklen.


Sie können das MySQL-Passwort mithilfe der speziellen --init-fileOption und Prozedur aktualisieren . C.5.4.1.2. Zurücksetzen des Root-Passworts: Unix Systems

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

Bearbeiten:

Wie @Gilles sagen, können Sie echo,printf oder die Verwendung hereDokument aus einem Skript.

Sie können dies auch zu .my.cnfIhrem Home-Verzeichnis oder in einer ( temporären ) Datei hinzufügen und die --defaults-extra-fileOption verwenden. (Glauben Sie, dass Sie diese Option früh in der Befehlszeile hinzufügen müssen.) Optional auch Benutzer einschließen. Beachten Sie auch das Extra im Optionsnamen, es sei denn, Sie möchten nur diese Datei als Konfiguration verwenden:

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

Optional überspringt die [client]Gruppierung mysqlddie Konfiguration.

Man kann auch MYSQL_PWDUmgebungsvariablen verwenden, aber das sollte niemals verwendet werden, da man die Umgebung in vielen psImplementierungen von ps -ein der /proc/<PID>/environDatei unter Linux usw. auflisten kann.

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

Mehr zum Thema hier .

Vielleicht möchten Sie auch einen Blick auf das MySQL-Konfigurationsdienstprogramm werfen, mit dem Sie das Kennwort in einer verschlüsselten Datei in Ihrem Home-Verzeichnis speichern können .mylogin.cnf.

Runium
quelle
Gibt es eine Möglichkeit, ein Token in der mysql-initDatei mit dem Kennwort zu ändern , das in einer Bash-Variablen gespeichert ist? (ohne enthüllt zu werden)
Dor
4
@Dor So etwas echo 'password=p4ssw0rd' >>mysql.cnfist sicher, da es integriert echoist, sodass das Kennwort in keinem Befehl in der Befehlszeile angezeigt wird. Ein hier Dokument ist auch sicher.
Gilles 'SO - hör auf böse zu sein'
4

Die typische Lösung besteht darin, das Kennwort aus einer Datei oder aus der Standardeingabe (oder aus einem anderen Dateideskriptor, der als Parameter übergeben werden müsste) zu lesen.

Hauke ​​Laging
quelle
3

Einige Programme ( ftpz. B. die Befehlszeile ) lesen Kennwörter aus /dev/ttyder prozessspezifischen Spezialdatei, die den Prozess darstellt, der TTY steuert. Auf diese Weise kann das Programm das Kennwort nicht an den Bildschirm zurücksenden und ein wenig mehr Sicherheit darüber haben, woher das Kennwort stammt.

#!/bin/bash

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

echo $PASSWORD
Bruce Ediger
quelle