Ich habe eine db-gesteuerte Anwendung, die über ssh mit einem anderen Server kommunizieren muss. Die Web-App kann ein Schlüsselpaar generieren und dem Benutzer den Pubkey geben, oder sie kann den unverschlüsselten privaten Schlüssel in einem Feld in einem Webformular akzeptieren. Anschließend verschlüsselt es den Schlüssel mit reversibler Verschlüsselung und speichert ihn in seiner Datenbank.
Wenn die Web-App mit dem SSH-Server kommuniziert, muss ich den privaten Schlüssel entschlüsseln und ihn auf die eine oder andere Weise für SSH bereitstellen. Ich könnte eine sichere temporäre Datei mit erstellen mktemp
, ssh darauf zeigen und dann die Datei zerstören, aber das ist zusätzliche Arbeit, die den Schlüssel auf eine neue Weise verfügbar macht, die anscheinend nicht notwendig sein sollte. Ich habe mir angesehen man ssh
, man ssh-agent
und man ssh-add
, aber es scheint keine Möglichkeit zu geben, den Schlüssel zu verwenden, ohne ihn zuerst einer Datei hinzuzufügen. Was vermisse ich?
quelle
Antworten:
Wenn Sie die vorhandenen Tools wie
ssh
/ verwenden möchten,ssh-agent
müssen Sie den Schlüssel als Datei bereitstellen.Eine andere, vielleicht praktikablere Lösung besteht darin, entweder a direkt zu implementieren
ssh
Client in Ihrer Anwendung zu und von Bibliotheken von Drittanbietern wie JSch abhängig zu sein oder entwederssh
/ssh-agent
zu erweitern, um den Schlüssel direkt aus Ihrer Datenbank zu empfangen und zu entschlüsseln.quelle
Dateien sind die Hauptmethode für den Datenaustausch zwischen Anwendungen. Es muss keine Festplattendatei sein. Dies kann eine Datei im temporären Speicher oder eine Pipe sein. Sie können eine Schlüsseldatei füttern
ssh-add
über ihre Standardeingabe , solange die Schlüsseldatei nicht kennwortgeschützt ist¹ (und da die Schlüsseldatei verschlüsselt gespeichert wurde, gibt es keinen Grund, ob sie darüber hinaus kennwortgeschützt ist).Alternativ können Sie nichts Besonderes tun und die Datei in ein speichergestütztes Dateisystem wie
/run
(/dev/shm
oder/tmp
oder was auch immer Ihre Distribution bietet) schreiben .Alternativ können Sie die private Schlüsseldatei ohne externe Verschlüsselung aufbewahren, sondern ein Kennwort eingeben. Verwenden Sie ein langes, zufällig generiertes Kennwort und speichern Sie dieses Kennwort in der Datenbank.
¹ Drosseln Sie experimentell
ssh-add
kennwortgeschützte Schlüsseldateien, die nicht durchsucht werden können, z. B. Named Pipes.quelle
Entschuldigung, keine Antwort, aber zu lang für einen Kommentar, der meiner Meinung nach vorhanden ist.
Wichtig ist, was Sie erreichen möchten, indem Sie den Schlüssel verschlüsselt in der Datenbank speichern.
Ein Angreifer, der auf die temporäre private Schlüsseldatei zugreifen kann, kann auch den Speicher des SSH-Client-Prozesses lesen (und somit trotzdem auf die Schlüsseldaten zugreifen), da beide Daten grundsätzlich die gleichen Zugriffsberechtigungen haben müssen - versuchen Das Ausblenden der Datei scheint sie nicht sicherer zu machen.
Wenn Sie unterschiedliche Benutzer für die Datenbank-, Webapp- und SSH-Verbindung verwenden, indem Sie den Schlüssel in der Datenbank speichern, in der Webapp entschlüsseln und an SSH weiterleiten, öffnen Sie nur potenzielle Angriffsmethoden, indem Sie den Schlüssel über den gesamten Prozess verteilen. Wenn Sie nur einen Benutzer für all diese verwenden (db, app, ssh), gewinnen Sie nichts außer der Komplexität des Codes.
Der einzige Vorteil scheint eine einfachere Übertragung des Systems auf einen anderen Host und ein potenzieller Gewinn für den Fall zu sein, dass die Datenbankdaten gestohlen werden, die Webanwendung (die AFAIU enthält den Entschlüsselungsalgorithmus und das Kennwort) jedoch nicht. Aber ist das wahrscheinlich?
Wenn Sie den Schlüssel schützen möchten, können Sie auch die interne Verschlüsselung der Schlüssel durch ssh verwenden und diese beim Starten Ihres Dienstes in einen ssh-Agenten laden (denken Sie daran, ihn zu entfernen, wenn er beendet wird!). Aber denken Sie auch hier daran, dass der ssh-Agent die Schlüssel im Speicher unverschlüsselt hält, damit sie möglicherweise gelesen werden können. Nochmals: Ist dies das Problem, das Sie lösen möchten?
Wenn Sie nur die Kommunikation zwischen zwei Computern schützen müssen, ist dies
stunnel
möglicherweise besser als ssh.Und schließlich zur Frage: Für OpenSSH ( portabel ) sollte das Schreiben eines einfachen Patches, mit
ssh
dem der Schlüssel wiesshd
bei derAuthorizedKeysCommand
Option aus einem anderen Prozess gelesen werden kann, relativ einfach sein.quelle
Ich habe versucht, dieses Problem zu lösen, als ich Schlüsselpaare generiert und mit Python in einer Datenbank gespeichert habe. Im Folgenden sind einige der Schritte aufgeführt, die ich letztendlich ausgeführt habe, nämlich das Starten
ssh-agent
und Interagieren damit. Es ist in Python, aber vermutlich können Sie es in alles andere übersetzen. Ein weiteres Merkmal ist, dass keines dieser Elemente verwendet wirdshell=True
, sodass sie vor Injektionsangriffen sicherer sind.Das löst ein
ssh-agent
Programm aus, das nur für unser Programm bestimmt ist, und löscht es (ich glaube, es lädt meine Benutzerschlüssel hinein, bin mir aber nicht sicher). Die Umgebungsvariable, dieSSH_AUTH_SOCK
normalerweise von festgelegt wirdssh-agent
(aber die wir manuell erstellt haben), geben wir an andere weiter Programme.Als nächstes geben wir
ssh-add
ihm den privaten Schlüssel (hier wird erdr.private_key
als Zeichenfolge gespeichert , aber ich muss ihn serialisieren, damit ich ihn als ASCII codiere).Wenn ich jetzt eine SSH-verwendende Anwendung verwende, z. B. Git, beziehe ich mich darauf, denselben SSH-Agent-Socket zu verwenden:
und es funktioniert gut. Die einzige "temporäre Datei" ist der Socket, der von verwendet wird. Sie
ssh-agent
wird jedoch erstellt, sodass nur der Eigentümer über Berechtigungen verfügt. Sie wird entfernt, wenn Sie den Agenten beenden.quelle