Inhaltsverzeichnis
Dieses Shellscript mit grafischen Dialogboxen (kdialog) vereinfacht die Synchronisierung der Keepass Passwort-Datenbank zu einem Remoterechner.
Ggf. die von mir individuellen Hostnamen in der Funktion check_valid_host und show_host durch die eigenen ersetzen, sowie Pfade in den Variablenbelegungen an die eigenen Gegebenheiten anpassen.
Außerdem ist für das Funktionieren des Scriptes auch ein ssh-Key ohne Passwort nötig, sowie eine eigene Configdatei. Ggf. mit dem Kommando ssh-keygen erzeugen (zB. einen RSA-Key) und auf den Remoterechner per ssh-copy-id übertragen.
Desweiteren sollte eine PNG-Grafikdatei für die Anzeige im Hauptdialog vorhanden sein (Größe 128×128 Pixel) die in der Variablen $LOGO_FILE hinterlegt ist.
Konfigurationsdateien
RSA Key ohne Passwort generieren (2x ENTER drücken)
$ ssh-keygen -t rsa -f /home/michael/.ssh/id_rsa_pwdless
SSH Config erstellen
- $HOME/.ssh/config.pwdless
# fuer Shellscripte mit passwortloesem Zugriff auf Remoterechner IdentityFile /home/michael/.ssh/id_rsa_pwdless
$ ls -ld ~/.ssh/id_rsa_pwdless* -rw------- 1 michael michael 2602 Feb 11 07:22 /home/michael/.ssh/id_rsa_pwdless -rw-r----- 1 michael michael 571 Feb 11 07:22 /home/michael/.ssh/id_rsa_pwdless.pub
SSH Keys auf den Remoterechner transferieren.
$ ssh-copy-id -f <hostname_des_zielrechners>
Aufruf des Scriptes
# Algemein: $ ./run_keepass-sync <hostname_des_zielrechners> # Beispiel: $ ./run_keepass-sync raven
Screenshots
Scriptcode
- run_keepass_sync.sh
#!/bin/bash # ####################### # Variablenbelegung ####################### # USER_TMP_DIR="$HOME/tmp" KEEPASS_DIR="$HOME/Daten/Privat/Keepassxc" KEEPASS_BACKUP_DIR="$HOME/Daten/Privat/Keepassxc_Sicherheitskopie" KEEPASS_FILE="PasswortDatenbank.kdbx" KEEPASS_LOGFILE=$HOME/tmp/$(basename $0).log SOURCE_HOST=$(hostname) DESTINATION_HOST=$1 DUMMY_FILE="$HOME/tmp/dummy.txt" LOGO_FILE="$HOME/project/run_keepass_sync.png" # # Fuer einen passwortlosen ssh-Zugang ist ein eigener rsa-Key erforderlich # (id_rsa_pwdless* und config.pwdless), sowie ein ssh Configfile in ~/.ssh # SSH_CONFIG_FILE="$HOME/.ssh/config.pwdless" # ################ # Funktionen ################ # create_log() { # ggf. temporäres tmp Verzeichnis im $HOME erstellen if [ ! -d "$USER_TMP_DIR" ] then mkdir "$USER_TMP_DIR" fi # Altes Logfile löschen und neues erstellen if [ -e "$KEEPASS_LOGFILE" ] then rm $KEEPASS_LOGFILE touch $KEEPASS_LOGFILE print_timestamp start echo "[$(date '+%H:%M:%S')] Logfile $KEEPASS_LOGFILE angelegt am $(date '+%d.%m.%Y') (1)" >> $KEEPASS_LOGFILE else touch $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] Logfile $KEEPASS_LOGFILE angelegt am $(date '+%d.%m.%Y') (2)" >> $KEEPASS_LOGFILE fi } make_backupdir() { # Backupverzeichnis für rsync anlegen, wenn noch nicht vorhanden if [ ! -d "$KEEPASS_BACKUP_DIR" ] then mkdir $KEEPASS_BACKUP_DIR echo "[$(date '+%H:%M:%S')] Backupverzeichnis $KEEPASS_BACKUP_DIR angelegt" >> $KEEPASS_LOGFILE else echo "[$(date '+%H:%M:%S')] Backupverzeichnis $KEEPASS_BACKUP_DIR existiert bereits" >> $KEEPASS_LOGFILE fi } check_keepass_db() { # Test ob die Passwort-DB vorhanden ist am definierten Pfad if [ -e "$KEEPASS_DIR/$KEEPASS_FILE" ] then RC=0 echo "[$(date '+%H:%M:%S')] [RC=$RC] Passwort-Datenbank $KEEPASS_DIR/$KEEPASS_FILE existiert" >> $KEEPASS_LOGFILE else RC=1 echo "[$(date '+%H:%M:%S')] [RC=$RC] Passwort-Datenbank $KEEPASS_DIR/$KEEPASS_FILE existiert nicht!" >> $KEEPASS_LOGFILE return $RC fi } check_valid_host() { # Überprüfe ob valide Hostnamen angegeben wurden case $DESTINATION_HOST in neonlight|greenline|raven) if [ "$SOURCE_HOST" = "$DESTINATION_HOST" ] then RC=11 echo "[$(date '+%H:%M:%S')] [RC=$RC] SOURCE_HOST=$SOURCE_HOST -> DESTINATION_HOST=$DESTINATION_HOST" >> $KEEPASS_LOGFILE return $RC else RC=0 echo "[$(date '+%H:%M:%S')] [RC=$RC] SOURCE_HOST=$SOURCE_HOST -> DESTINATION_HOST=$DESTINATION_HOST" >> $KEEPASS_LOGFILE return $RC fi ;; *) RC=12 echo "[$(date '+%H:%M:%S')] [RC=$RC] DESTINATION_HOST=$DESTINATION_HOST" >> $KEEPASS_LOGFILE return $RC ;; esac } check_dest_host() { # Test auf Erreichbarkeit des Zielrechners echo "Verfügbarkeitstest" > $DUMMY_FILE echo "[$(date '+%H:%M:%S')] Simmulierter Pogrammaufruf: scp -F $SSH_CONFIG_FILE $DUMMY_FILE $DESTINATION_HOST:/tmp" >> $KEEPASS_LOGFILE scp -F $SSH_CONFIG_FILE $DUMMY_FILE $DESTINATION_HOST:/tmp RC=$? if [ "$RC" -eq 0 ] then echo "[$(date '+%H:%M:%S')] [RC=$RC] Zielrechner $DESTINATION_HOST ist verfügbar und hat eine Netzwerkverbindung im LAN bzw. WLAN" >> $KEEPASS_LOGFILE else echo "[$(date '+%H:%M:%S')] [RC=$RC] Zielrechner $DESTINATION_HOST ist nicht eingeschaltet oder hat keine Netzwerkverbindung im LAN bzw. WLAN" >> $KEEPASS_LOGFILE return $RC fi } create_logmessages() { # Einträge ins Logfile schreiben für die Fehlersuche echo "[$(date '+%H:%M:%S')] KEEPASS_BACKUP_DIR="$KEEPASS_BACKUP_DIR >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] KEEPASS_DIR="$KEEPASS_DIR >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] KEEPASS_FILE="$KEEPASS_FILE >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] LOGO_FILE="$LOGO_FILE >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] USER="$USER >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] SOURCE_HOST="$SOURCE_HOST >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] DESTINATION_HOST="$DESTINATION_HOST >> $KEEPASS_LOGFILE echo "[$(date '+%H:%M:%S')] Simmulierter Pogrammaufruf: rsync -v -r -c -g -p -t -l -H -b --backup-dir=$KEEPASS_BACKUP_DIR --delete --stats --progress -e 'ssh -F '$SSH_CONFIG_FILE'' $KEEPASS_DIR/$KEEPASS_FILE $USER@$DESTINATION_HOST:$KEEPASS_DIR/" >> $KEEPASS_LOGFILE } run_sync() { # Synchronisation anstossen via rsync echo "[$(date '+%H:%M:%S')] Synchronistaion der Passwort-Datenbank $KEEPASS_FILE nach Zielrechner $DESTINATION_HOST startet ..." >> $KEEPASS_LOGFILE rsync -v -r -c -g -p -t -l -H -b --backup-dir=$KEEPASS_BACKUP_DIR --delete --stats --progress -e 'ssh -F '$SSH_CONFIG_FILE'' $KEEPASS_DIR/$KEEPASS_FILE $USER@$DESTINATION_HOST:$KEEPASS_DIR/ >> $KEEPASS_LOGFILE RC=$? echo "[$(date '+%H:%M:%S')] [RC=$RC] RC von rsync" >> $KEEPASS_LOGFILE return $RC } show_passive_popup() { # Popup anzeigen bei (nicht)erfolgreicher Synchronisation if [ "$RC" = "0" ] then echo "[$(date '+%H:%M:%S')] [RC=$RC] Synchronisation der Passwort-Datenbank konnte erfolgreich durchgeführt werden" >> $KEEPASS_LOGFILE kdialog --passivepopup "Synchronisation der Passwort-Datenbank konnte erfolgreich durchgeführt werden" 5 else echo "[$(date '+%H:%M:%S')] [RC=$RC] Synchronisation der Passwort-Datenbank konnte nicht erfolgreich durchgeführt werden" >> $KEEPASS_LOGFILE kdialog --passivepopup "Synchronisation der Passwort-Datenbank konnte nicht erfolgreich durchgeführt werden" 5 fi } show_host() { # Ermittlung der Typen von Quell- und Zielrechner für die Ausgabe in der kdialog-Box if [ "$DESTINATION_HOST" = "greenline" ] then PC_TYP_DEST="Laptop" elif [ "$DESTINATION_HOST" = "raven" ] then PC_TYP_DEST="Laptop" elif [ "$DESTINATION_HOST" = "neonlight" ] then PC_TYP_DEST="Desktop-PC" else PC_TYP_DEST="unbekannter Zielrechner" fi if [ "$SOURCE_HOST" = "greenline" ] then PC_TYP_SOURCE="Laptop" elif [ "$SOURCE_HOST" = "raven" ] then PC_TYP_SOURCE="Laptop" elif [ "$SOURCE_HOST" = "neonlight" ] then PC_TYP_SOURCE="Desktop-PC" else PC_TYP_SOURCE="unbekannter Quellrechner" fi } check_proc() { # Testen ob Keepassxc auf dem lokalen Rechnern läuft PROC_ID_LOCAL=$(ps -U $USER|egrep keepassxc$ |awk '{print $1}') if [ "$PROC_ID_LOCAL" ] then echo "[$(date '+%H:%M:%S')] PROC_ID_LOCAL="$PROC_ID_LOCAL "Prozess keepassxc läuft noch" >> $KEEPASS_LOGFILE return else echo "[$(date '+%H:%M:%S')] PROC_ID_LOCAL=n/a" >> $KEEPASS_LOGFILE fi # Testen ob Keepassxc auf dem entfernten Rechnern läuft PROC_ID_REMOTE=$(ssh -F $SSH_CONFIG_FILE $DESTINATION_HOST ps -U $USER | egrep keepassxc$ | awk '{print $1}') if [ "$PROC_ID_REMOTE" ] then echo "[$(date '+%H:%M:%S')] PROC_ID_REMOTE="$PROC_ID_REMOTE "Prozess keepassxc läuft noch" >> $KEEPASS_LOGFILE else echo "[$(date '+%H:%M:%S')] PROC_ID_REMOTE=n/a" >> $KEEPASS_LOGFILE fi } print_timestamp() { # Timestamp (Start und Ende) ins Logfile schreiben TS_VALUE=$1 if [ "$TS_VALUE" = "start" ] then echo "[$(date '+%H:%M:%S')] ----------------------------------------------------- Start -----------------------------------------------------" >> $KEEPASS_LOGFILE elif [ "$TS_VALUE" = "end" ] then echo "[$(date '+%H:%M:%S')] ----------------------------------------------------- Ende ------------------------------------------------------" >> $KEEPASS_LOGFILE fi } init_progressbar() { # initieren der Fortschrittsanzeige progress=$(kdialog --title "Abgleich der Passwort-Datenbank" --progressbar "Abgleich der Passwort-Datenbank" 5) qdbus $progress showCancelButton false } run_progressbar() { # Fortschrittsanzeige aktualisieren bei jedem Schritt VALUE="$1" TEXT="$2" qdbus $progress Set "" value $VALUE > /dev/null qdbus $progress setLabelText "$VALUE. Schritt: $TEXT" > /dev/null } close_progressbar() { # Fortschrittsanzeige am Scriptende schließen qdbus $progress close > /dev/null } ################## # Hauptprogramm ################## # init_progressbar run_progressbar "1" "Verschiedene Vorbereitungen zur Synchronisation treffen" sleep 2 create_log check_valid_host if [ "$RC" -eq 11 ] then kdialog --title "Abgleich der Passwort-Datenbank" --detailederror "Achtung ein Fehler ist aufgetreten, der Name des Quell- und Zielrechners ist identisch. " "$(cat $KEEPASS_LOGFILE)" print_timestamp end close_progressbar exit 1 elif [ "$RC" -eq 12 ] then kdialog --title "Abgleich der Passwort-Datenbank" --detailederror "Achtung ein Fehler ist aufgetreten, es wurde ein ungültiger Namen für den Zielrechner angegeben." "$(cat $KEEPASS_LOGFILE)" print_timestamp end close_progressbar exit 13 fi run_progressbar "2" "Quell- und Zielrechner auf Erreichbarkeit überprüfen" check_dest_host if [ "$RC" -ne 0 ] then CHECK_DEST_HOST_DIALOG=$(kdialog --title "Abgleich der Passwort-Datenbank" --detailederror "Zielrechner ($DESTINATION_HOST) ist nicht eingeschaltet oder hat keine Netzwerkverbindung.\n\n1. Bitte den Zielrechner einschalten und/oder eine Netzwerkverbindung herstellen.\n2. Danach dieses Programm nochmals starten.\n" "$(cat $KEEPASS_LOGFILE)") print_timestamp end close_progressbar exit 1 fi run_progressbar "3" "Prüfe ob KeepassXC auf Quell- oder Zielrechner läuft" check_proc # Auf Rückgabewerte der Funktion check_proc mit entsprechenden Dialogboxen reagieren if [ "$PROC_ID_LOCAL" ] then CHECK_PROC_DIALOG=$(kdialog --title "Abgleich der Passwort-Datenbank" --detailederror "Auf diesem Rechner ($SOURCE_HOST) läuft noch der Passwortmanager.\n\n1. Bitte den Passwortmanager beenden.\n2. Danach dieses Programm nochmals starten.\n" "$(cat $KEEPASS_LOGFILE)") print_timestamp end close_progressbar exit 21 elif [ "$PROC_ID_REMOTE" ] then CHECK_PROC_DIALOG=$(kdialog --title "Abgleich der Passwort-Datenbank" --detailederror "Auf dem Zielrechner $DESTINATION_HOST läuft noch der Passwortmanager.\n\n1.Bitte den Passwortmanager auf dem Zielrechner $DESTINATION_HOST beenden.\n2. Danach dieses Programm nochmals starten.\n" "$(cat $KEEPASS_LOGFILE)") print_timestamp end close_progressbar exit 22 fi run_progressbar "4" "Prüfe ob KeepassXC DB im angegebenen Verzeichnis liegt" make_backupdir check_keepass_db # Auf Rückgabewert der Funktion check_keepass_db reagieren if [ "$RC" -ne 0 ] then CHECK_KEEPASS_DB_DIALOG=$(kdialog --title "Abgleich der Passwort-Datenbank" --detailederror "Die Datenbankdatei ($KEEPASS_FILE) für Keepassxc existiert nicht.\n" "$(cat $KEEPASS_LOGFILE)") print_timestamp end close_progressbar exit 2 fi show_host # Hauptdialogbox vor der Synchronisation der Passwort-Datenbank #SYNC_DIALOG=$(kdialog --title "Abgleich der Passwort-Datenbank" --yesnocancel "\nSoll die Passwort-Datenbank ($KEEPASS_FILE) vom Quell- zum Zielrechner synchronisiert werden?\nAchtung, dabei wird die Passwort-Datenbank auf dem Zielrechner überschrieben.\n\nVoraussetzung dafür ist, dass die Datenbank des Passwortmanagers im selben Verzeichnis auf Quell- und\nZielrechner abgelegt ist unter $KEEPASS_DIR.\n\nHinweis:\nQuelle ist dieser Rechner: Name $SOURCE_HOST ($PC_TYP_SOURCE)\nZiel ist der entfernte Rechner: Name $DESTINATION_HOST ($PC_TYP_DEST)\n") kdialog --title "Abgleich der Passwort-Datenbank" --yesnocancel "<center><img src=$LOGO_FILE></img><br></center>Soll die Passwort-Datenbank (Dateiname: $KEEPASS_FILE) vom Quell- zum Zielrechner synchronisiert werden?<br><br>Achtung, dabei wird die Passwort-Datenbank auf dem Zielrechner überschrieben. Voraussetzung für eine erfolgreiche Synchronisation ist, dass die Datenbank des Passwortmanagers im selben Verzeichnis auf Quell- und Zielrechner abgelegt ist:<br><center><b>$KEEPASS_DIR</b></center><br>Hinweis:<br>Quelle ist dieser Rechner: Name $SOURCE_HOST ($PC_TYP_SOURCE)<br>Ziel ist der entfernte Rechner: Name $DESTINATION_HOST ($PC_TYP_DEST)<br>" SYNC_DIALOG_CHECK=$? run_progressbar "5" "Synchronisation der KeepassXC Datenbank durchführen" # Auf Mausklicks in der Hauptdialogbox reagieren (JA, NEIN, ABBRECHEN) if [ "$SYNC_DIALOG_CHECK" = "0" ] then create_logmessages echo "[$(date '+%H:%M:%S')] SYNC_DIALOG_CHECK JA = "$SYNC_DIALOG_CHECK >> $KEEPASS_LOGFILE run_sync show_passive_popup $RC print_timestamp end close_progressbar elif [ "$SYNC_DIALOG_CHECK" = "1" ] then create_logmessages echo "[$(date '+%H:%M:%S')] SYNC_DIALOG_CHECK NEIN = "$SYNC_DIALOG_CHECK >> $KEEPASS_LOGFILE print_timestamp end close_progressbar exit 3 elif [ "$SYNC_DIALOG_CHECK" = "2" ] then create_logmessages echo "[$(date '+%H:%M:%S')] SYNC_DIALOG_CHECK ABBRECHEN = "$SYNC_DIALOG_CHECK >> $KEEPASS_LOGFILE print_timestamp end close_progressbar exit 4 fi #EOF