JensBlawatt

Bitwarten SSH Key Management

Ich verwalte alle meine Passwörter mit dem Passwortmanager Bitwarden. Meine SSH Keys habe ich allerdings bisher nicht im Bitwarden gespeichert, obwohl sich neben Logins auch Attachments zu einzelnen Einträgen hinterlegen lassen. Daher wäre es theoretisch möglich gewesen. Allerdings ist die Verwendung nicht so ganz komfortabel, wenn man die Keys mit dem SSH-Client auf der Konsole verwenden möchte. Denn die Keys liegen dann im Bitwarden und nicht mehr im .ssh-Verzeichnis. Um die Keys aber dennoch komfortabel verwenden zu können, sie aber nirgends auf dem Rechner speichern zu müssen, lassen sie sich über eine einfache Folge von Befehlen zu einem laufenden ssh-agent hinzufügen.

Um diese Lösung nutzen zu können, benötigt man folgende Tools:

Hier ein Beispiel zum Vorgehen.

Zu erst starten wir einen SSH-Agent für die aktuelle Session:

$ eval $(ssh-agent)
Agent pid 24439

Im Anschluss müssen wir den Bitwarden Key Store öffnen und die geöffente Session in der Variable $BW_SESSION speichern.

$ export BW_SESSION=$(bw unlock --raw)

Jetzt führen wir eine Kombination von Befehlen aus, die wir aneinander pipen:

  1. Abfragen des Items in sich der SSH-Key als Attachment befindet
  2. aus JSON Rückgabe die ID des Items extrahieren und nur diese ausgeben
  3. über die Bitwarden CLI den Inhalt des Attachments zum eben abgefragen Item ermitteln
  4. den Inhalt des privaten Schlüssels über ssh-add zum aktuellen SSH-Agent hinzufügen
$ bw get item ITEM_NAME \
    | jq ".id" -r \
    | xargs bw get attachment ATTACHMENT_NAME --raw --itemid \
    | ssh-add - 

Damit dies nicht immer manuel ausgeführt werden muss, habe ich mir ein Helfer Script erstellt, das als gist zur Verfügung steht:

#!/bin/sh

#
# sh bitwarden-ssh-key-add.sh UNIQUE_ITEM_NAME ATTACHMENT_NAME
#

set -e

ITEM_NAME=$1;
ATTACHMENT_NAME=$2;

if [ -z "$SSH_AGENT_PID" ]; then
    >&2 echo "There is no ssh-agent running in this session.";
    exit 1;
fi

if [ -z "$ITEM_NAME" ]; then
    >&2 echo "There is not item name defined in \$1.";
    exit 1;
fi

if [ -z "$ATTACHMENT_NAME" ]; then
    >&2 echo "There is not attachment name defined in \$2.";
    exit 1;
fi

if [ -z "$BW_SESSION" ]; then
    export BW_SESSION=$(bw unlock --raw);
fi

ITEM_ID=$(bw get item $ITEM_NAME | jq ".id" -r);

if [ -z "$ITEM_ID" ]; then
    exit 1;
fi

ATTACHMENT_RAW=$(bw get attachment $ATTACHMENT_NAME --raw --ITEM_ID $ITEM_ID);

if [ -z "$ATTACHMENT_RAW" ]; then
    exit 1;
fi

echo "$ATTACHMENT_RAW" | ssh-add - ;