Verwendung von mysqldump im Cron-Job ohne root-Passwort

14

Wenn ich mich mit dem root-Passwort an meiner Box anmelde, kann ich einfach tippen

mysqldump --all-databases und ich bekomme den erwarteten "Dump".

Ich richte in cron.daily einen Job ein, um diesen auszuführen und auf ein Sicherungslaufwerk zu sichern. Das Problem, das ich habe, ist, dass, obwohl der Benutzer als root ausgeführt wird, die folgende Meldung angezeigt wird

mysqldump: Got error: 1045: Zugriff für Benutzer 'root' @ 'localhost' verweigert (mit Passwort: NO)

beim Versuch, eine Verbindung herzustellen. Ich möchte das Root-Passwort der MySQL-Datenbank im Skript nicht hart codieren (wer würde das tun ?).

Wenn man bedenkt, dass ich einfach "mysqldump" in die Befehlszeile meiner Bash-Shell eingeben kann, muss es eine Möglichkeit geben, sich mit dem Parameter -u zurechtzufinden. Ich habe bereits #! / Bin / bash oben im Skript.

Was fehlt mir hier, damit ich nicht nach dem root-Passwort für die Datenbank frage?

Mech Software
quelle

Antworten:

12

Um eine Verbindung zum MySQL-Server herzustellen, müssen Sie Anmeldeinformationen eingeben. Sie können sie in einer Konfigurationsdatei angeben, über die Befehlszeile übergeben oder einfach ein Konto erstellen, für das keine Anmeldeinformationen erforderlich sind.

Natürlich sollte die Option no-password niemals verwendet werden. Die Pass-by-Befehlszeile ist nicht besonders gut, da jeder, der ps ausführen kann, möglicherweise die Befehlszeile sehen kann.

Die empfohlene Option besteht darin, eine mysql-Konfigurationsdatei mit den darin enthaltenen Anmeldeinformationen zu erstellen und diese Datei dann mit Dateisystemberechtigungen zu schützen, damit nur Ihr Sicherungsbenutzer darauf zugreifen kann.

Wenn Sie sich beim mysql-Server anmelden können, während Sie interaktiv als root angemeldet sind, scheint dies darauf hinzudeuten, dass Sie entweder kein root-Passwort festgelegt haben oder dass Sie eine Konfigurationsdatei haben, die von Ihrem Skript nicht gefunden wird. Wenn Sie eine .my.cnf haben, müssen Sie möglicherweise manuell darauf verweisen. Wenn für Ihr Root-Konto kein Kennwort festgelegt wurde, empfehlen wir Ihnen dringend, dieses Problem zu beheben.

Update (29.06.2016) Wenn Sie mysql 5.6.6 oder höher ausführen, sollten Sie sich das Tool mysql_config_editor ansehen , mit dem Sie Anmeldeinformationen in einer verschlüsselten Datei speichern können. Vielen Dank an Giovanni , der mir das gesagt hat.

Zoredache
quelle
1
Diese Methode erfordert weiterhin ein unverschlüsseltes Passwort im Klartext, um auf dem System zu sein. Das versuche ich zu vermeiden.
Mech Software
> Sie haben entweder kein Root-Passwort festgelegt, oder Sie haben eine Konfigurationsdatei, die von Ihrem Skript nicht gefunden wird. Der Autor gibt eindeutig an, dass es ein MySQL-Passwort für root gibt und dass er versucht, auf die Datenbank zuzugreifen, ohne es dem Befehl mysqldump mitzuteilen: "(using password: NO)". Zugriff verweigert daher Fehler.
Monomythos
1
@monomyth, der Autor gibt außerdem an, dass er sich ohne Passwort anmelden kann, während er interaktiv als root angemeldet ist. Das sagt mir, dass etwas nicht stimmt.
Zoredache
2
@Mech Software, Es macht nicht viel Sinn, sich vor dem Root-Account zu schützen. Wenn jemand über das Root-Konto verfügt, kann er einfach das MySQL neu starten und das Berechtigungssystem vollständig umgehen.
Zoredache
1
Der Grund, warum ich mich anmelden konnte, war, dass für das Root-Konto eine .my.cnf mit 600 Berechtigungen angegeben wurde. Auf diese Weise erhielt die Shell Zugriff. cron muss jedoch die Datei ignorieren, also habe ich den Parameter in diesem Beitrag verwendet, um darauf zu verweisen.
Mech Software
3

Sicherheit sollte nicht durch Dunkelheit erfolgen. Wenn Sie befürchten, dass jemand Zugriff auf Ihr Root-Konto hat, spielt es keine Rolle, ob das MySQL-Passwort von Root im Skript gespeichert ist, da alle Ihre Daten in MySQL-Dumps oder in Datenbankdateien verfügbar sind. Die eigentliche Frage ist also, was Sie schützen wollen.

Wenn Sie nicht möchten, dass andere Benutzer ein Kennwort erhalten, mit dem sie Daten in Ihrer Datenbank ändern können, müssen Sie einen Benutzer mit den entsprechenden Berechtigungen erstellen .

Wenn Sie nicht möchten, dass dieses MySQL-Kennwort von einem lokalen Konto außer dem Root-Konto angezeigt wird, setzen Sie die Dateiberechtigungen für dieses Skript auf 0700 und den Eigentümer auf root.

Monomythos
quelle
1
Ich vermute, was ich immer noch nicht verstehe, ist, dass ich mysqldump ohne Kennworteingabe (über die Root-Eingabeaufforderung) eingeben kann. Warum kann ich es dann nicht auf die gleiche Weise über den Cron-Job ausführen? Welches Teil fehlt, erfordert den Parameter -p. Ich versuche nicht, das Passwort zu "verschleiern", ich möchte es nur lieber nie eingeben lassen. Etwas Besonderes am Root-Login selbst ist, dass der Zugriff zugelassen wird. Warum kann dies nicht mit cron repliziert werden?
Mech Software
Wenn Sie feststellen, dass Sie sich ohne Kennwort und mit einem Kennwort unter Verwendung desselben "Root" -Nutzers anmelden können, befinden sich möglicherweise mehrere Root-Benutzer in Ihrer mysql-Datenbank. Für einige von ihnen ist möglicherweise kein Kennwort festgelegt. Sie können das Passwort aus dem 'root' @ 'localhost' entfernen, aber dann kann nicht nur cron eine Verbindung zu Ihrer Datenbank herstellen, sondern jeder mit einem lokalen Konto. Dies ist nicht anders (oder schlimmer) als ein Passwort in einem Klartext-Skript zu haben.
Monomythos
Ich denke, der Punkt, den MechSoftware gemacht hat, ist, dass Sie als Root im Wesentlichen Lesezugriff auf Datenbankdateien haben und diese nicht verschlüsselt sind. Daher ist es "Sicherheit durch Unbekanntheit", wenn der Root-Benutzer nur ein Root-MySQL-Passwort benötigt, um die Daten auszudrucken, auf die er im Wesentlichen bereits zugreifen kann. Außerdem können Berechtigungen sehr leicht durcheinander gebracht werden, z. B. wenn jemand sie rekursiv für ein Verzeichnis einstellt, wenn ein symbolischer Link zur Datei vorhanden ist usw.
Septagram
2

Ihre Shell-Verwendung kann dies tun, da Sie eine Shell haben, von der aus Sie sie ausführen können. Wenn Sie sich anmelden, werden alle Ihre Shell-Skripte in Ihrem Profil ausgeführt.

Cron hat keinen solchen Luxus. Wenn es sich anmeldet (als root), wird es sich mit einer Standard-Shell anmelden. Dies verhindert, dass sich jemand remote anmeldet, bedeutet aber auch, dass keine automatischen Anmeldeskripts ausgeführt werden.

Sie können eine Shell festlegen, unter der cron ausgeführt werden soll, die crontab bearbeiten und die Variablen SHELL und HOME hinzufügen, z.

SHELL=/bin/bash
HOME=/root

Wenn diese nicht gesetzt sind, wird cron mit dem in / etc / passwd angegebenen Shell- und Home-Verzeichnis ausgeführt (wahrscheinlich nichts, möglicherweise / bin / sh).

Wenn Sie sehen möchten, wie der Umgebungs-Cron ausgeführt wird, fügen Sie einen Cron-Job hinzu, der env in eine Datei exportiert, z.

$crontab -e
* * * * * env > /tmp/crontabenv.log
:wq
gbjbaanb
quelle
1

Wenn das Skript von root ausgeführt wird, können Sie eine Datei /root/.my.cnf mit den Berechtigungen 600 und den folgenden Inhalten erstellen :

[client]
user = DBUSERNAME
password = DBPASSWORD

(wo Sie natürlich Ihren MySQL-Benutzernamen und Ihr Passwort eingeben).

Diese Datei wird automatisch von jedem mysql-Befehlszeilentool gelesen, wenn es als root ausgeführt wird. Sie müssen es nicht mehr in der Befehlszeile bereitstellen. Die 600 Berechtigungen schützen es vor neugierigen Blicken.

Martijn Heemels
quelle
1
Ich stellte fest, dass dies der Fall war, wie ich mysqldump ohne das Passwort ausführen konnte. Das hat also das Rätsel gelöst, wie die SHELL es macht. Warum liest cron es also nicht?
Mech Software
1
Wenn mysqldump von cron ausgeführt wird, kann die Datei .my.cnf möglicherweise nicht gefunden werden. Die Abhilfe besteht darin, einen mysqldump-Parameter hinzuzufügen, um die Optionen in der.my.cnf-Datei explizit zu lesen, dh --defaults-extra-file = / root / .my.cnf. Siehe stackoverflow.com/a/602054/854680 und stackoverflow.com/a/890554/854680
MikeOnline,
1

Das Debuggen von Cron kann sehr frustrierend sein. Wenn die Cron-Jobs ausgeführt werden, ist für sie keine Umgebung festgelegt, die für eine Shell selbstverständlich ist.

Tipps für Cron:

  • Nutze die vollständigen Pfade zu allem - "ECHO = / bin / echo" usw. (definiere die Variablen oben, um es einfacher zu machen)
  • Stellen Sie MAILTO ein, damit Sie von jedem Job eine E-Mail erhalten (oder die Jobs leiten stderr / stdout in eine Datei um).

Wenn Ihr Root-Benutzer dies von der Shell aus tun kann, sollte cron dies können. Stellen Sie sicher, dass Sie die in der Befehlszeile zu verwendende Konfigurationsdatei explizit angeben.


quelle
0

Obwohl einige dieser Antworten hilfreich sind, sind einige verwirrend, da der Unix-Root-Benutzer und der MySQL-Root-Benutzer nicht identisch sind und im Grunde keine Beziehung haben, außer dass beide den Anmeldenamen 'root' verwenden. Möglicherweise ist das offensichtlich, aber es scheint, dass einige Antworten die zwei vereinen.

Eine nützliche Option für mysqld wäre, Client-Programmen wie mysql oder mysqldump etc, die als Unix-Root ausgeführt werden, den Zugriff auf mysqlds root @ localhost ohne Kennwort zu ermöglichen, ohne das Kennwort von root @ localhost (mysql) speichern zu müssen in einer my.cnf-Datei oder ähnlichem.

Ich weiß, das macht einige nervös, aber die Überlegung ist, dass jeder, der als lokaler (auf dem mysqld-Server) Unix-Root läuft, die Sicherheit von mysqld ohnehin recht leicht umgehen kann. Und wenn ich eine my.cnf mit dem mysqld-root-Passwort 7x24 habe oder sogar eine my.cnf mit dem mysql-root-Passwort (woher kommt dieses Passwort?) Im laufenden Betrieb erstelle / lösche (z. B. um einen mysqldump durchzuführen), bin ich nervös.

Es würde etwas Infrastruktur und Nachdenken erfordern, da man mysql / mysqldump / etc vertrauen müsste, um an mysqld zu übermitteln, dass es wirklich glaubt, dass es von einem lokalen Unix-Root-Konto ausgeführt wird.

Aber zum Beispiel könnte eine Beschränkung auf den Unix-Socket von mysqld, kein TCP, helfen, zumindest als dringend empfohlene Option dieser Option. Dies könnte darauf hinweisen, dass der Client lokal ausgeführt wird, obwohl dies wahrscheinlich nicht ausreicht. Aber es könnte ein Anfang einer Idee sein. Vielleicht könnte ein Dateideskriptor über einen Unix-Socket gesendet werden (google es, wenn das wie verrücktes Gerede klingt.)

PS: Nein, ich werde hier nicht versuchen, mir Gedanken darüber zu machen, wie dies auf einem Nicht-Unix-Betriebssystem funktionieren könnte, obwohl die Idee wahrscheinlich auf andere Betriebssysteme übertragen werden kann.

Barry Shein
quelle
1
Wenn Sie die Anmeldeinformationen /root/.my.cnfmit den richtigen Berechtigungen eingeben, wird das Problem behoben.
Michael Hampton
Ich bin anderer Meinung, jetzt hat jeder, der Zugriff auf diese Datei hat, auch über einen anderen Systemfehler, das mysql-root-pw. Und es ist rund um die Uhr verfügbar, um angegriffen zu werden, und an einem festen Speicherort für Dateien (obwohl es nicht unbedingt in / root sein müsste). Wer zum Beispiel Dateisystem-Dumps ausführt oder Zugriff auf eines hat, kann es herausholen eine Dateisystem-Dump-Datei. In diesem Fall klingt es wie eine Versuchung für einen verärgerten Mitarbeiter. Ich denke, es ist ein vernünftiges Ziel, dass auf einem System nirgendwo Klartext-Passwörter existieren.
Barry Shein
Vielleicht, aber der Vorschlag, den Sie gemacht haben, ist viel schlimmer, da jeder lokale Benutzer trivialerweise so tun kann, als wäre er root.
Michael Hampton
Nein, mein Vorschlag war, dass sie bereits Unix-Root auf dem lokalen Server sein müssen. In diesem Fall vertraut die lokale mysqld der Ausführung von mysql oder mysqldump etc (client) als Unix-Root und lässt sie so fortfahren, als ob sie sich als mysql-Root authentifiziert hätten . Wie gesagt, wenn sie bereits Unix-Root-lokal auf dem Server sind, können sie das MySQL-Root-Passwort trotzdem mit ein paar gut dokumentierten Befehlen umgehen ("MySQL-Root-Passwort-Wiederherstellung").
Barry Shein