Angenommen, ich habe sha1pass
einen Hash eines vertraulichen Kennworts in der Befehlszeile generiert. Ich kann verwenden sha1pass mysecret
, um einen Hash zu generieren, mysecret
aber das hat den Nachteil, dass mysecret
es jetzt in der Bash-Geschichte ist. Gibt es eine Möglichkeit, das Endziel dieses Befehls zu erreichen, ohne dass dies mysecret
im Klartext passwd
angezeigt wird, z. B. mithilfe einer Eingabeaufforderung im -Stil?
Ich bin auch an einer verallgemeinerten Methode interessiert, um vertrauliche Daten an einen Befehl weiterzuleiten. Die Methode würde sich ändern, wenn die vertraulichen Daten als Argument (z. B. in sha1pass
) oder in STDIN an einen Befehl übergeben werden.
Gibt es eine Möglichkeit, dies zu erreichen?
Bearbeiten : Diese Frage hat viel Aufmerksamkeit erregt und es wurden einige gute Antworten unten angeboten. Eine Zusammenfassung ist:
- Wie pro @ Kusalananda Antwort , im Idealfall würde man nie ein Passwort oder Geheim als Befehlszeilenargument zu einem Dienstprogramm geben muß. Dies ist in mehrfacher Hinsicht verwundbar, wie von ihm beschrieben, und man sollte ein besser gestaltetes Dienstprogramm verwenden, das in der Lage ist, die geheimen Eingaben auf STDIN zu übernehmen
- @ vfbsilvas Antwort beschreibt, wie Sie verhindern, dass Dinge im Bash-Verlauf gespeichert werden
- @ Jonathans Antwort beschreibt eine vollkommen gute Methode, um dies zu erreichen, solange das Programm seine geheimen Daten auf STDIN übertragen kann. Aus diesem Grund habe ich mich entschlossen, diese Antwort zu akzeptieren.
sha1pass
In meinem OP war dies nur ein Beispiel, aber die Diskussion hat ergeben, dass es bessere Tools gibt, die Daten zu STDIN aufnehmen. - Wie @R .. in seiner Antwort feststellt , ist die Verwendung der Befehlserweiterung für eine Variable nicht sicher.
Zusammenfassend habe ich @ Jonathans Antwort akzeptiert , da es die beste Lösung ist, vorausgesetzt, Sie haben ein gut gestaltetes und ansprechendes Programm, mit dem Sie arbeiten können. Die Übergabe eines Kennworts oder eines Geheimnisses als Befehlszeilenargument ist zwar grundsätzlich unsicher, die anderen Antworten bieten jedoch Möglichkeiten, um die einfachen Sicherheitsbedenken abzumildern.
sha1pass mysecret
ausgeführt werden, und somit wissen, wasmysecret
ist. (Dies funktioniert natürlich nur für einige Sekunden, während das Programm ausgeführt wird ...)Antworten:
Wenn Sie die Shell
zsh
oder verwendenbash
, verwenden Sie die Option -s für die integrierteread
Shell, um eine Zeile vom Endgerät zu lesen, ohne dass sie wiederholt wird.Dann können Sie eine ausgefallene Umleitung verwenden, um die Variable als stdin zu verwenden.
Wenn jemand rennt
ps
, wird er nur "sha1pass" sehen.Dies setzt voraus, dass
sha1pass
das Kennwort von stdin gelesen wird (in einer Zeile, wobei das Zeilentrennzeichen ignoriert wird), wenn kein Argument angegeben wird.quelle
sha1pass
der Standardeingabestrom nicht verwendet wird.sha1pass
war nur ein Beispiel in meinem OP und eindeutig nicht die beste Wahl dafür.ps
, sondern kann in eine temporäre Datei geschrieben werden - wenn man das vermeiden will, dann insshpass < <(printf '%s\n' "$VARIABLE")
Betracht gezogen werden könnte (daprintf
ist ein builtin, kein externer Befehl, der nicht an) weitergegeben wirdexecv
und über diesen erreichbar istps
.Im Idealfall geben Sie niemals ein Klartextkennwort in der Befehlszeile als Argument für einen Befehl ein. Dadurch wird das Kennwort zu einem Argument für den Befehl, und Befehlszeilenargumente können in der Prozesstabelle angezeigt werden, indem einfache Tools verwendet werden,
ps
die in einigen Überwachungsprotokollen verwendet werden.Allerdings gibt es durchaus Möglichkeiten, das eigentliche Passwort aus dem Befehlsverlauf der Shell zu entfernen.
Geben Sie dann das Passwort ein und drücken Sie Enter. Der
head
hier verwendete Befehl akzeptiert genau eine Eingabezeile, und die letzte eingegebene neue Zeile ist nicht Teil der Daten, an die übergeben wirdsha1pass
.So verhindern Sie das Echo der Zeichen:
Der
stty -echo
Befehl deaktiviert das Echo der eingegebenen Zeichen auf dem Terminal. Das Echo wird dann mit wiederhergestelltstty echo
.Um die Standardeingabe weiterzugeben, könnte der letzte Befehl geändert werden (dies wäre geschehen, wenn
sha1pass
Daten für die Standardeingabe akzeptiert worden wären , es scheint jedoch, als würde dieses Dienstprogramm die Standardeingabe ignorieren):Wenn Sie eine mehrzeilige Eingabe benötigen (in den obigen Abschnitten wird davon ausgegangen, dass eine einzelne Zeile ohne Zeilenumbruchzeichen am Ende übergeben werden soll), ersetzen Sie den gesamten
head
Befehl durchcat
und beenden Sie die Eingabe (vorausgesetztsomecommand
, sie liest sich bis zum Ende der Datei) mit Ctrl+D( folgenden, Returnwenn Sie ein Zeilenumbruchzeichen in die Eingabe aufnehmen möchten, oder zweimal, wenn nicht).Dies funktioniert unabhängig davon, welche Shell Sie verwenden (sofern es sich um eine Bourne-ähnliche oder eine RC-ähnliche Shell handelt).
Bei einigen Shells kann es vorkommen, dass die eingegebenen Befehle nicht in ihren Verlaufsdateien gespeichert werden, wenn vor dem Befehl ein Leerzeichen steht. In der Regel muss hierfür
HISTCONTROL
der Wert eingestellt werdenignorespace
. Dies wird von mindestensbash
undksh
unter OpenBSD unterstützt, aber nicht von zBksh93
oderdash
.zsh
Benutzer können diehistignorespace
Option oder ihreHISTORY_IGNORE
Variable verwenden, um ein zu ignorierendes Muster zu definieren.In Shells, die das Lesen mit unterstützen,
read
ohne Zeichen an das Terminal zu senden, können Sie auch verwendenDies hat jedoch offensichtlich immer noch das gleiche Problem mit der potenziellen Offenlegung des Kennworts in der Prozesstabelle.
Wenn das Dienstprogramm von der Standardeingabe liest und die Shell "here-strings" unterstützt, kann das oben Gesagte in geändert werden
Zusammenfassung der Kommentare unten:
Wenn Sie einen Befehl mit einem in der Befehlszeile angegebenen Kennwort ausführen, was bei allen oben genannten Befehlen mit Ausnahme des Befehls, der die Daten an den Befehl weiterleitet, der Fall ist, wird das Kennwort möglicherweise für alle Benutzer sichtbar,
ps
die gleichzeitig ausgeführt werden. Keiner der obigen Befehle speichert jedoch das eingegebene Kennwort in der Verlaufsdatei der Shell, wenn es von einer interaktiven Shell ausgeführt wird.Gut erzogene Programme, die Klartext-Passwörter lesen, lesen dies von ihrer Standardeingabe, aus einer Datei oder direkt vom Terminal.
sha1pass
Dies erfordert das Kennwort in der Befehlszeile, das entweder direkt eingegeben oder durch eine Form der Befehlsersetzung ersetzt wird.Verwenden Sie nach Möglichkeit ein anderes Werkzeug.
quelle
$(...)
ist Teil der Befehlszeile und in derps
Ausgabe sichtbar, außer auf einem System mit hard / proc.sha1pass
run with no password on the command line scheint eine Ausgabe zu erzeugen, ohne etwas zu lesen ... OP muss also ein anderes Tool auswählen.Wenn Sie so einstellen
HISTCONTROL
:und starte den Befehl mit einem Leerzeichen:
es wird nicht im Verlauf gespeichert.
quelle
Übergeben Sie sensible Daten über eine Pipe oder Here-Doc:
oder:
Es ist in Ordnung, dass sich Geheimnisse in (nicht exportierten) Shell-Variablen befinden, aber Sie können diese Variablen niemals in Befehlszeilen verwenden, nur in Here-Dokumenten und Shell-Interna.
Wie Kusalananda in einem Kommentar angemerkt hat, werden die Zeilen, die Sie für ein Here-Dokument eingeben, im Shell-Verlauf gespeichert, wenn Sie Befehle in eine interaktive Shell eingeben. Es ist also nicht sicher, dort ein Kennwort einzugeben, es sollte jedoch immer noch so sein sichere Verwendung von Shell-Variablen, die Geheimnisse enthalten; Der Verlauf enthält den Text
$secret
und nicht das, worauf er$secret
erweitert wurde.Die Verwendung von Befehlserweiterungen ist nicht sicher :
da die Ausgabe in der Befehlszeile enthalten und in der
ps
Ausgabe sichtbar ist (oder manuell aus / proc liest), außer auf Systemen mit gehärtetem / proc.Die Zuweisung zu einer Variablen ist auch in Ordnung:
quelle
command_with_secret_output
, den ich erlaubt , gibt Sie den geheimen Ausgang. Gibt es einen solchen Befehl, der hier ersetzt werden könnte?bash
Sitzung das Dokument in der Verlaufsdatei gespeichert wird.read
, zread -r secret
. Dann ist dein Geheimnis in$secret
. Sie können stty davor / danach ausführen, um die Eingabe auszublenden, wenn Sie möchten.sha1pass
grundsätzlich kaputt / unbrauchbar / unsicher zu sein, da es das Passwort von stdin oder einer Datei nicht lesen kann. Ich denke, es wird ein anderes Dienstprogramm benötigt, um das Problem zu lösen.read -rs
erledigt die Aufgabe (wenn Sie-r
Kennwörter mit umgekehrten Schrägstrichen verwenden möchten), aber dann können Sie das Kennwort möglicherweise wieder in der Prozessliste anzeigen (und dies hängt davon ab, ob die Prozessabrechnung aktiviert und wie konfiguriert ist) , auch in den Prozessabrechnungsprotokollen).Schreiben Sie einfach den Wert in eine Datei und übergeben Sie die Datei:
Ich bin mir nicht sicher, wie es
sha1pass
funktioniert, wenn es eine Datei als Eingabe nehmen kann, die Sie verwenden könnensha1pass < mysecret
. Wenn nicht, ist die Verwendungcat
möglicherweise ein Problem, da sie die letzte Zeile enthält. Wenn dies der Fall ist, verwenden Sie (wenn Ihrehead
Unterstützung-c
):quelle
cat | sha1pass
?cat mysecret | sha1pass
undsha1pass < mysecret
haben das gleiche Verhalten in Bezug auf endgültige Zeilenumbrüche.cat
fügt keine Zeilenumbrüche hinzu. Wennsha1pass
die Weitergabe des Kennworts über die Standardeingabe unterstützt wird, würde ich davon ausgehen, dass die letzte Zeile für sich ignoriert wird. Dateien mit Zeilen, die nicht durch Zeilenumbrüche abgeschlossen werden, sind in Unix schließlich unnatürlich. Es wäre daher umständlich, eine Datei zu erwarten, die nicht durch Zeilenumbrüche abgeschlossen wird.cat | sha1pass
scheint zu rennen,sha1pass
bevor ich die Möglichkeit habe, Eingaben zu machen. ii) Nein, natürlichcat mysecret
wird keine neue Zeile hinzugefügt, ich habe nie gesagtcat
, dass sie hinzugefügt wird , nur, dass sie diese enthält .< mysecret
entfernen. :)head -c-1
. Ich schätze, ich war nur verwirrt, warum ich es benutzecat mysecret | sha1pass
und schlage es später vorsha1pass < mysecret
. Ich denke, die Sorge ist, dass sha1pass sich über reguläre Dateien für stdin beschweren könnte; Ich bin mir nicht sicher warum.sha1pass
und eine manuelle oder nicht finden konnte ,-h
oder jede andere Form der Dokumentation in den wenigen Minuten , die ich verbrachte die Suche und so konnte nicht herausfinden , ob Laufensha1pass foo
behandeltfoo
als Input - String oder als Eingabedatei . Ich gab daher Optionen, um mit jeder Möglichkeit umzugehen.Wenn das, was terdon getan hat, möglich ist, dann ist das die beste Lösung, indem es die Standardeingabe durchläuft. Das einzige Problem ist, dass er das Passwort auf die Festplatte geschrieben hat. Wir können dies stattdessen tun:
Wie Kusalananda sagte,
stty -echo
stellt sicher, dass das, was Sie eingeben, erststty echo
wieder angezeigt wird, wenn Sie es erneut tun .head -1
erhält eine Zeile von der Standardeingabe und leitet sie an weitersha1pass
.quelle
ich würde ... benutzen
cat
würde von stdin bis lesenEOF
, was durch Drücken von Strg + D verursacht werden kann. Dann würde das Ergebnis als Argument an übergebensha1pass
quelle