Seit Jahren nutze ich jetzt schon Unison, um ein Verzeichnis zwischen zwei entfernten Rechnern (Home & Office) zu synchronisieren. Mein Server in der Cloud dient dafür als zentrale Datenquelle. Zwecks Datensicherheit sind die Verzeichnisse der beiden Rechner verschlüsselt, aber das Verzeichnis in der Cloud leider nicht. Das wollte ich jetzt mal ändern :)

Meine Idee war, dass nur wenn Unison loslegt, das verschlüsselte Laufwerk auf dem Server gemountet wird und danach wieder abgestöpselt (unmount) wird. Falls ein Hacker oder Admin auf den Rechner käme, könnte er erst einmal nicht so einfach auf das Laufwerk zugreifen. Speziell für Debian Stretch musste ich noch ein paar Extras ausführen, mehr dazu unten.

Als verschlüsseltes Laufwerk nutze ich eine Containerdatei, die mit LUKS verschlüsselt wird. Mit folgenden Befehlen kann man eine solche in dem Home-Verzeichnis des Cloud-Server anlegen:

# legt eine 8G Container-Datei an
dd if=/dev/zero of=container_file bs=1G count=8

# mit /sbin/ kann man es auch als normaler User ausführen
/sbin/cryptsetup -c aes-xts-plain64 -s 512 -h sha512 -y luksFormat container_file

# Container als Loop-Device einbinden
udisksctl loop-setup -f container_file
> Mapped file container_file as /dev/loop0.

# Loop-Device freigeben
udisksctl unlock -b /dev/loop0
> Passphrase: 
> Unlocked /dev/loop0 as /dev/dm-0.

# Formatieren - nur als Root möglich
su
mkfs.ext4 -m 0 /dev/dm-0
exit

# mounten
udisksctl mount -b /dev/dm-0
> Mounted /dev/dm-0 at /media/username/xxxxx-yyyyy-zzzzz.
  
# jetzt noch einmal die Berechtigung des Mount-Pfad ändern 
su
chown -R myuser:mygroup /media/username/xxxxx-yyyyy-zzzzz
exit

# Das Laufwerk ist jetzt eingebunden

# mit diesen Befehlen wird das Laufwerk wieder unmounted
udisksctl unmount -b /dev/dm-0
udisksctl lock -b /dev/loop0
udisksctl loop-delete -b /dev/loop0

Anschließend habe ich in dem Home-Verzeichnis des Cloud-Servers zwei Script zum Einhängen und Aushängen angelegt.

/home/user/bin/container_mount.sh:

#!/bin/bash

# Pfad im System
mediapath="/media/username/xxxxx-yyyyy-zzzzz"

if [ -d "$mediapath" ]
  then
    echo "containerfile is mountet!"
    exit 1
  else
    echo "no media"
fi
 
echo "Setup Loop"
udisksctl loop-setup -f /home/username/container_file
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "unlock"
udisksctl unlock -b /dev/loop0
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "mount"
udisksctl mount -b /dev/dm-0
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "ready"
exit 0

/home/user/bin/container_unmount.sh:

#!/bin/bash

# Pfad im System
mediapath="/media/username/xxxxx-yyyyy-zzzzz"

if [ -d "$mediapath" ]
  then
    echo "containerfile is mountet!"
   
  else
    echo "no media"
    exit 1
fi
 
echo "unmount"
udisksctl unmount -b /dev/dm-0
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "lock"
udisksctl lock -b /dev/loop0
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "Delete Loop"
udisksctl loop-delete -b /dev/loop0
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "ready"
exit 0

So, jetzt kann man praktisch schon mit Unison arbeiten. Per SSH das Laufwerk mounten, Unison ausführen und Laufwerk wieder unmounten. Das ganze habe ich dann noch in einem Script auf den beiden Rechnern eingebettet.

#!/bin/bash

echo "sync shared"
ssh -t myserver /home/user/bin/container_mount.sh 
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

unison-gtk
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

ssh -t myserver /home/user/bin/container_unmount.sh 
rc=$?; if [[ $rc != 0 ]]; then echo "ERROR"; exit $rc; fi

echo "ready"
exit 0

Mit dem Script kann ich jetzt mit einem Klick und der Angabe eines Passwort meine Verzeichnisse syncen. SSH arbeitet bei mir mit einen SSH-KEY, sodass ich für die SSH-Verbindung kein Passwort angeben muss. Selbstverständlich müsst ihr natürlich Server-, Pfad- und Username für euch ändern.

Fazit

Ich weiß, dass das natürlich noch besser gehen würde, aber estmal liegen keine sensiblen Daten mehr lesbar auf dem Server. Der nächste Schritt sollte sein, dass die mount-Script nicht auf dem Server liegen, sondern alle Kommandos per SSH kommen. Ich werde mich mal bei Gelegenheit daran machen. :)

Desktop Starter

Für den Desktop habe ich dann noch ein Icon erstellt:

[Desktop Entry]
Name=My Unison
Exec=/home/user/sync_shared.sh
Comment=Custom Unison Sync
Terminal=true
Type=Application
Icon=/usr/share/pixmaps/unison-gtk.svg

Debian Stretch

Unter Debian Stretch fehlten ein paar wichtige Pakete und zum ausführen von udisks musste ich die PolicyKit modifizieren.

# als Root
apt-get install cryptsetup busybox udisks2 policykit-1 

# Datei erstellen
vi /etc/polkit-1/localauthority/50-local.d/10-udisks.pkla 

Mit folgendem Inhalt:

[udisks]
Identity=unix-user:myuser
Action=org.freedesktop.udisks2.loop-setup;org.freedesktop.udisks2.encrypted-unlock;org.freedesktop.udisks2.filesystem-mount
ResultAny=yes
ResultInactive=yes
ResultActive=yes

Jetzt noch einmal PolicyKit neustarten:

systemctl restart polkit

Ab jetzt sollten die Befehle oben mit udisks laufen.