Sichere Methode zum Ändern des Kennworts eines Benutzers über Python-Skript / nicht interaktiv

7

Fragen

  1. Gibt es eine sicherere / bessere Möglichkeit, das Kennwort eines Benutzers nicht interaktiv über ein Python-Skript festzulegen? Meine aktuelle Lösung verwendet chpasswdein Fabric- Skript. Eine andere Möglichkeit wäre, Pexpect aus dem Fabric- Skript heraus zu verwenden.
  2. Ist meine derzeitige Methode zum Festlegen des Kennworts ein Sicherheitsrisiko? Das potenzielle Sicherheitsrisiko, das ich sehe, besteht darin, dass das Kennwort auf meinem lokalen Terminal wie folgt als Klartext angezeigt wird :
    [xxx.xx.xx.xxx] run: echo "johnsmith:supersecretpassw0rd" | chpasswd.
    Da ich das Fabric- Skript nur von meinem Laptop aus ausführe , denke ich nicht, dass dies ein Sicherheitsproblem ist, aber ich bin an den Eingaben anderer interessiert.

Hintergrund

Ich habe ein Python-Skript mit Fabric erstellt , um ein frisch erstelltes Slicehost Ubuntu-Slice zu konfigurieren . Falls Sie mit Fabric nicht vertraut sind, verwendet es Paramiko , einen Python SSH2-Client, um den Remotezugriff "für Anwendungsbereitstellungs- oder Systemverwaltungsaufgaben " bereitzustellen.

Eines der ersten Dinge, die ich mit dem Fabric- Skript tun muss, ist, einen neuen Administrator zu erstellen und sein Kennwort festzulegen. Im Gegensatz zu Pexpect kann Fabric keine interaktiven Befehle auf dem Remote-System verarbeiten. Daher muss das Kennwort des Benutzers nicht interaktiv festgelegt werden. Derzeit verwende ich den chpasswdBefehl, der den Benutzernamen und das Passwort als Klartext liest.

Aktueller Code

# Fabric imports and host configuration excluded for brevity
root_password = getpass.getpass("Root's password given by SliceManager: ")
admin_username = prompt("Enter a username for the admin user to create: ")
admin_password = getpass.getpass("Enter a password for the admin user: ")
env.user = 'root'
env.password = root_password
# Create the admin group and add it to the sudoers file
admin_group = 'admin'
run('addgroup {group}'.format(group=admin_group))
run('echo "%{group} ALL=(ALL) ALL" >> /etc/sudoers'.format(
    group=admin_group)
)
# Create the new admin user (default group=username); add to admin group
run('adduser {username} --disabled-password --gecos ""'.format(
    username=admin_username)
)
run('adduser {username} {group}'.format(
    username=admin_username,
    group=admin_group)
)
# Set the password for the new admin user
run('echo "{username}:{password}" | chpasswd'.format(
    username=admin_username,
    password=admin_password)
)

E / A des lokalen Systemterminals

$ fab config_rebuilt_slice
Root's password given by SliceManager: 
Enter a username for the admin user to create: johnsmith
Enter a password for the admin user: 
[xxx.xx.xx.xxx] run: addgroup admin
[xxx.xx.xx.xxx] out: Adding group `admin' (GID 1000) ...
[xxx.xx.xx.xxx] out: Done.
[xxx.xx.xx.xxx] run: echo "%admin ALL=(ALL) ALL" >> /etc/sudoers
[xxx.xx.xx.xxx] run: adduser johnsmith --disabled-password --gecos ""
[xxx.xx.xx.xxx] out: Adding user `johnsmith' ...
[xxx.xx.xx.xxx] out: Adding new group `johnsmith' (1001) ...
[xxx.xx.xx.xxx] out: Adding new user `johnsmith' (1000) with group `johnsmith' ...
[xxx.xx.xx.xxx] out: Creating home directory `/home/johnsmith' ...
[xxx.xx.xx.xxx] out: Copying files from `/etc/skel' ...
[xxx.xx.xx.xxx] run: adduser johnsmith admin
[xxx.xx.xx.xxx] out: Adding user `johnsmith' to group `admin' ...
[xxx.xx.xx.xxx] out: Adding user johnsmith to group admin
[xxx.xx.xx.xxx] out: Done.
[xxx.xx.xx.xxx] run: echo "johnsmith:supersecretpassw0rd" | chpasswd
[xxx.xx.xx.xxx] run: passwd --lock root
[xxx.xx.xx.xxx] out: passwd: password expiry information changed.

Done.
Disconnecting from [email protected]... done.
Matthew Rankin
quelle
Zu Ihrer Information: chpasswd kann mit der Option -e verschlüsselte Passwörter verwenden. Sie können ein Passwort mit verschlüsseln grub-crypt. Jemand anderes erwähnt openssl passwd. Der Unterschied zwischen beiden besteht darin, dass openssl passwdKennwörter nur mit herkömmlichem Unix cryptoder MD5 verschlüsselt werden können und grub-cryptsha-256 und sha-512 unterstützt werden.
Jonathan

Antworten:

3

Sie übergeben das Kennwort in der Befehlszeile, die Sie ausführen. Diese sind möglicherweise nicht nur in Ihrem Terminal sichtbar, sondern auch für andere Benutzer, die den Befehl 'ps' ausgeben (dies kann von der Systemkonfiguration abhängen). Und das Passwort ist Klartext.

Ich kenne Fabric nicht, aber wenn es Ihnen die Möglichkeit gibt, mit ausgeführten Befehlen über deren stdin / stdout (wie subprocess.Popen()) zu kommunizieren , ist es wahrscheinlich eine bessere Wahl, dies anstelle von 'echo username: password | ... zu verwenden. '.

Sie können auch den Kennwort-Hash in Ihrem Python-Skript erstellen (mithilfe des cryptModuls und "$ 1 $ XXXXXXXX $" ("X" sind zufällige Zeichen) salt) und diesen an übergeben chpasswd -e. Das Nur-Text-Passwort wird dann nie angezeigt oder protokolliert.

Jacek Konieczny
quelle
2

Normalerweise generiere ich für die nicht interaktive Kennworteinstellung ein zufälliges Kennwort, setze es auf eine Variable und übergebe die Variable dann an meinen Befehl. Ich muss nicht kreativ mit Passwörtern umgehen und kein Standardkennwort in einer Nur-Text-Datei hinterlassen.

Hier ist ein Rezept für den aktiven Status zum Generieren von zufälligen Passwörtern .

Was die Sicherheit angeht, halte ich es nicht für ein großes Problem, ein Passwort auf Ihrem eigenen Terminal zu drucken (mit dem Zufallspasswort möchten Sie das trotzdem, damit Sie das erstellte pwd zur Kenntnis nehmen können). .

Gibt es etwas anderes, das Fabric mit ssh macht? - Die meisten Sachen, die durch ssh reisen, sollten sowieso verschlüsselt sein.

snk
quelle
@Steve: "Gibt es etwas anderes, das Fabric mit ssh macht?" Nichts, was mir bewusst ist. Fabric verwendet Paramiko als SSH-Modul, daher stimme ich zu, dass alles über SSH verschlüsselt werden sollte.
Matthew Rankin
2

Wenn Sie chpasswd from with in einer Fabric verwenden, stellen Sie sicher, dass Sie nicht das Nur-Text-Kennwort über die Befehlszeile verwenden. Es ist nicht nur der Standard, in dem das Passwort angezeigt wird, sondern es wird auch in / var / log / Secure geschrieben. In Fabric können Sie verwenden

with hide('running', 'output', 'error'):
     <your task here>

Stellen Sie außerdem sicher, dass Sie eine Hash-Zeichenfolge zusammen mit dem Befehl chpasswd verwenden, damit das Kennwort auch in den sicheren Protokollen nicht im Klartext angezeigt wird. Entscheiden Sie sich zuerst für das zu verwendende Kennwort und generieren Sie die Hash-Zeichenfolge. Sie könnten dafür openssl verwenden.

openssl passwd -1

Auf diese Weise werden Sie aufgefordert, ein Kennwort einzugeben und den MD5-Hash zu generieren. und Sie können dies in Ihrem Skript wie folgt verwenden.

echo "<user>:<MD5-hash>" | chpasswd -e

Das Flag -e im obigen Befehl teilt chpasswd mit, dass das Kennwort verschlüsselt ist.

sabs6488
quelle
1

Die kommende Version 1.0 von Fabric (ab sofort im Git-Zweig erhältlich) ermöglicht interaktive Sitzungen mit dem Remote-Ende.

Florian Ledermann
quelle
0

Könnten Sie einfach Ihr neues Slice automatisch konfigurieren und sich dann sofort anmelden und das Passwort ändern? Manchmal ist der einfachste Ansatz der beste.

Alternativ können Sie das verschlüsselte Kennwort lokal generieren und das verschlüsselte Kennwort einfach in die Datei / etc / shadow schreiben. Auf diese Weise verwenden Sie überhaupt keinen Klartext.

Beachten Sie jedoch, dass Sie Ihrem lokalen System vertrauen müssen, wenn Sie das ursprüngliche Kennwort eingeben.

Könnten Sie übrigens eine Kopie Ihrer automatischen Konfiguration zur Verfügung stellen, damit ich sie verwende, anstatt alles von Grund auf neu zu schreiben? Zur Zeit mache ich alles per Bash.

etwas wie das?

sed 's/^root:.*$/root:$PASSWD:13063::::::/' /etc/shadow > /etc/shadow
Val Neekman
quelle