Sichere, verschlüsselte Off-Site-Backups - die Empfängerseite

Vor einem Jahr hatte ich beschrieben, wie ich ein verschlüsseltes Backup auf einen Rechner im Netz mit Duplicity mache. Duplicity erledigt die eigentliche Backup-Aufgabe und die Verschlüsselung mit gpg. Anschließend werden diese Daten per sftp auf das entfernte System geschoben. Was man hierbei beachten kann, möchte ich hier quasi als Follow-Up-Artikel dokumentieren.

Authentisierung per ssh-Key

Das Naheliegendste zuerst: Für ein automatisch laufendes Backupskript sollte es natürlich nicht nötig sein, ein Passwort einzugeben. Für diesen Zweck habe ich einen ssh-Key generiert, welcher auf dem zu sichernden Rechner unverschlüsselt vorliegt und dessen Public-Key-Gegenstück auf dem Server in die Datei `~/.ssh/authorized_keys` eingetragen wurde. Mit Hilfe des Parameters `--ssh-options="-oIdentityFile=/root/.ssh/id_dsa-backup"` wird duplicity angewiesen, die entsprechende Option für die Schlüsselverwendung an ssh durchzureichen.

Zugriffsbeschränkung auf dem Datenserver

Im Fall, daß das System kompromittiert wird, ist ein unverschlüsselter ssh-Key natürlich das Sprungbrett auf ein weiteres System. Um dem entgegenzutreten, habe ich auf der Datenserver-Seite den zugehörigen Account durch folgende Einträge in der ssh-Konfiguration `/etc/ssh/sshd_config` eingeschränkt:

Match Group remotebak
  ChrootDirectory /var/backups/remote/%u/chroot
  ForceCommand internal-sftp

Alle solchen Backup-Accounts habe ich der Gruppe "remotebak" hinzugefügt und ihre Home-Verzeichnisse in `/var/backups/remote/username` angelegt. Durch die obige Konfiguration wird für alle User der Gruppe erzwungen, daß nur ein Zugriff via sftp erfolgen kann (also keine interaktiven Shell-Zugriffe); außerdem wird der Zugriff durch eine Change-root-Umgebung auf das Unterverzeichnis `chroot` eingeschränkt.
Wieso aber der Klimmzug mit dem weiteren Unterverzeichnis? Grund hierfür ist die Bedingung für die chroot-Umgebung, daß das chroot-Verzeichnis samt all seiner Stammverzeichnisse root gehören muß. Ich wollte aber sicherstellen, daß über den sftp-Zugang ausschließlich die Backup-Daten zugreifbar sind, gleichzeitig wollte ich aber das Homeverzeichnis (mit dem .ssh-Verzeichnis) der Übersichtlichkeit wegen an derselben Stelle haben. Daher sieht die Verzeichnis- und Dateistruktur für den Backup-User server1 wie folgt aus:

Verzeichnis/Datei Owner
/var/backups/remote/server1 root
/var/backups/remote/server1/.ssh/... server1
/var/backups/remote/server1/chroot root
/var/backups/remote/server1/chroot/data server1

So ist ssh mit der Ownership des ssh-Keys und des chroot-Verzeichnisses glücklich, gleichzeitig ist sichergestellt, daß der User über sftp ausschließlich in das data-Verzeichnis schreiben kann.

Mehr Paranoia: Backup-Daten in Sicherheit bringen

Bis hierher ist sichergestellt, daß ein Angreifer, der den zu sichernden Rechner kompromittiert hat, keinen problemlosen Shellzugriff auf den Datenrechner erhält. Die Möglichkeit des Vandalismus ist damit allerdings noch nicht ausgeschlossen - er kann sämtliche Backup-Daten löschen und so ein Wiederherstellen des Systems unmöglich machen.
Eine Möglichkeit wäre es, die Daten täglich automatisch wegzukopieren - was allerdings eine erhebliche Platzverschwendung wäre. Eine Möglichkeit wäre es, neue Metadaten zu kopieren und die eigentlichen Daten in ein anderes Verzeichnis außerhalb der Changeroot-Umgebung wegzuschieben. Alternativ kann man (sofern das Dateisystem erweiterte Attribute erlaubt) die Dateien gegen jegliche Veränderung schützen:

cd /var/backups/remote
for i in * ; do
  pushd $i > /dev/null
  cd chroot/data
  for j in * ; do
    chmod +i $j
  done
  popd > /dev/null
done

Das Skript ist nur eine Skizze, es muß als root ausgeführt werden, Fehlerfälle werden hier nicht abgefragt, Unterverzeichnisse von data nicht berücksichtigt (duplicity legt von sich aus keine an)... aber ich denke, es vermittelt die Idee :-)
Einziger Wehrmutstropfen: Die Expiry von Duplicity-Backups (Löschen alter Daten) funktioniert nun natürlich nicht mehr rein clientseitig, da die Dateien gegen Löschen geschützt sind. Einzige Lösung ist ein weiteres Skript, was solche alten Daten wegräumt - oder gelegentliche Handarbeit.