Verschlüsseln unserer Backups: Bis zur Ziellinie

Veröffentlicht: 2017-09-02

Hinweis: Dieser technische Beitrag wurde von unserer Datenbankadministratorin Silvia Botros verfasst. Sehen Sie sich hier einige ihrer anderen DBA-Beiträge an.

Vor einem Jahr arbeitete SendGrid hart an der SOC2-Zertifizierung. Alle waren beteiligt. Es gab Geschichten auf fast jedem Lieferteam-Board mit einem SOC2-Tag, da wir alle bis zum Ende des dritten Quartals zertifiziert werden wollten. Wie Sie sich vorstellen können, gab es als Verantwortlicher für Datenbanken definitiv einiges an Arbeit für diesen Teil des Stacks.

Auf meiner Aufgabenliste für dieses unternehmensweite Vorhaben stand die Verschlüsselung unserer Backups. Da ich mit DBA-Tools vertraut bin und weiß, dass xtrabackup von Percona bereits Verschlüsselung unterstützt, war es vorhersehbar, dass ich dies als ersten Versuch bei dieser Aufgabe tun würde.

Beim Testen dieses Ansatzes hatte ich ein paar wichtige Dinge im Visier:

  • Offensichtlich musste das Backup verschlüsselt werden
  • Der Aufwand für die Erstellung der Sicherung musste bekannt und akzeptabel sein
  • Der Aufwand für die Entschlüsselung des Backups zum Zeitpunkt der Wiederherstellung musste bekannt und akzeptabel sein

Das bedeutete, dass ich zunächst in der Lage sein musste, nachzuverfolgen, wie lange meine Backups dauern.

Sicherungszeit verfolgen

SendGrid verwendet Graphite für seine Infrastrukturmetriken, und während die überwiegende Mehrheit über Sensu gesendet wird, ist Graphite einfach genug, um Metriken direkt über Bash-Zeilen zu senden – sehr praktisch, da die Backup-Skripte in Bash sind. Beachten Sie, dass das direkte Senden von Metriken an Graphite nicht super skalierbar ist, aber da diese Backups höchstens einmal pro Stunde ausgeführt werden, war das für meine Bedürfnisse in Ordnung.

Dieser Teil erwies sich als relativ einfach.

Um zu erklären, was in dieser letzten Zeile passiert ist, sende ich Graphite den Pfad der Metrik, die ich sende (stellen Sie sicher, dass sie eindeutig ist), den Metrikwert und dann die aktuelle Zeit im Epochenformat. Ich habe mich der Einfachheit halber für Netcat entschieden, und ich gebe ihm ein Timeout von 1 Sekunde, da es sonst nie beendet wird. Die „Graphite-URL“ ist unser DNS-Endpunkt für Graphite im Rechenzentrum.

Jetzt, da ich eine Vergleichsgrundlage hatte, konnten wir mit dem Testen von Verschlüsselungsmethoden beginnen.

Nach der ausführlichen Dokumentation von Percona, wie man das macht, begann ich mit der Herstellung eines Schlüssels. Wenn Sie diese Dokumentationsseite sorgfältig lesen, wird Ihnen vielleicht etwas klar.

Dieser Schlüssel muss direkt an das Backup-Tool übergeben werden, und es ist derselbe Schlüssel, der den Snapshot entschlüsseln kann. Dies wird als symmetrische Verschlüsselung bezeichnet und ist aufgrund des gleichen Schlüssels in beide Richtungen weniger sicher als asymmetrische Verschlüsselung. Ich beschloss, weiter zu testen, um zu sehen, ob die Einfachheit dies immer noch zu einem praktikablen Ansatz macht.

Tests mit sehr kleinen DBs, einigen hundert MB, waren erfolgreich. Das Tool funktioniert wie erwartet und dokumentiert, aber das war eher ein Funktionstest und die eigentliche Frage war: „Wie hoch ist die Strafe der Verschlüsselung auf unseren größeren DBs?“ Die älteren Instanzen bei SendGrid waren auf Größen von 1-2 TB bis zu einem einzelnen 18-TB-Biest angewachsen. Was ich für die kleinen Instanzen verwenden wollte, musste auch für die größeren operativ akzeptabel sein.

Hier wurden Tests und Benchmarks interessant

Mein erstes Testobjekt von beträchtlicher Größe ist eine Datenbank, die wir haben und die 1 TB auf der Festplatte ist. Sehr schnell stieß ich auf ein unerwartetes Problem. Mit minimalen Verschlüsselungseinstellungen (1 Thread, Standard-Chunk-Größen) sah ich, dass die Sicherungen mit diesem Fehler fehlschlugen:

Zu dieser Zeit verwendeten diese Datenbanken 512 MB als Größe der Transaktionsprotokolldatei, und dies ist ein ziemlich ausgelasteter Cluster, sodass diese Dateien fast jede Minute rotierten. Normalerweise würde sich dies in der DB-Leistung bemerkbar machen, aber es wurde größtenteils durch das Wunder der Solid State Drives maskiert. Scheint so, als würden wir keine parallelen Verschlüsselungsthreads setzen (lesen Sie: einen verwenden), dass wir so viel Zeit damit verbringen, `.ibd`-Dateien zu verschlüsseln, dass die innodb-Redo-Log-Rollen unter uns die Sicherung unterbrachen.

Versuchen wir es also noch einmal mit einer Reihe von Verschlüsselungsthreads. Als ersten Versuch habe ich es mit 50 Threads versucht. Der Trick hier besteht darin, den optimalen Punkt der schnellen Verschlüsselung zu finden, ohne um die CPU zu konkurrieren. Ich habe auch die Größe der `ib_logfiles` auf jeweils 1 GB erhöht.

Dies war ein erfolgreicherer Test, den ich gerne über Nacht brauen ließ. In den ersten Nächten schien alles gut. Es war an der Zeit, ein Backup zu erstellen, das nicht zu sehr wächst, aber die durchschnittliche Box-Last während des Backup-Prozesses zeigte definitiv die hinzugefügten Schritte.

Als ich jedoch zum Testen von Wiederherstellungen überging, stellte ich fest, dass der Wiederherstellungsprozess derselben Sicherungen nach Hinzufügen der Verschlüsselung von 60 auf 280 Minuten gestiegen war – was eine erhebliche Strafe für unsere versprochene Wiederherstellungszeit im Katastrophenfall bedeutete.

Wir mussten das auf einen vernünftigeren Zeitrahmen zurückführen.

Hier glänzten Teamwork und einfachere Problemlösungen. Einer unserer InfoSec-Teammitglieder entschied sich zu prüfen, ob diese Lösung vereinfacht werden kann. Also führte er weitere Tests durch und kam mit etwas Einfacherem und Sichererem zurück. Ich hatte noch nichts über gpg2 gelernt und so wurde dies auch für mich zu einer Lernübung.

Das Gute an gpg2 ist, dass es asymmetrische Verschlüsselung unterstützt. Wir erstellen ein Schlüsselpaar, bei dem es private und öffentliche Teile gibt. Der öffentliche Teil wird verwendet, um jeden Stream oder jede Datei zu verschlüsseln, die Sie gpg2 zuführen möchten, und das private Geheimnis kann zum Entschlüsseln verwendet werden.

Die Änderung an unseren Backup-Skripten zum Hinzufügen von Verschlüsselung destilliert dazu. Einige Argumente wurden entfernt, um das Lesen zu erleichtern:

Auf der anderen Seite müssen wir beim Wiederherstellen eines Backups einfach sicherstellen, dass sich ein akzeptabler geheimer Schlüssel im Schlüsselbund des Hosts befindet, und dann diesen Befehl verwenden:

Da ich auch neu bei gpg2 war, wurde dies zu einer Lerngelegenheit für mich. Colin, unser großartiges InfoSec-Teammitglied, testete weiterhin Sicherungen und Wiederherstellungen mit gpg2, bis er bestätigte, dass die Verwendung von gpg2 mehrere Vorteile gegenüber der Verwendung der integrierten Komprimierung von xtrabackup hat, darunter:

  • Es war asymmetrisch
  • Seine geheime Verwaltung zur Entschlüsselung lässt sich relativ leicht drehen (mehr dazu weiter unten)
  • Es ist werkzeugunabhängig, was bedeutet, dass jede andere Art von Sicherung, die xtrabackup nicht verwendet, dieselbe Methode verwenden könnte
  • Es wurden mehrere Kerne für die Entschlüsselung verwendet, was uns bessere Wiederherstellungszeiten ermöglichte

Immer Raum für Verbesserungen

Ein Punkt, an dem ich noch Verbesserungspotenzial sehe, ist der Umgang mit dem Geheimnis, das diese Dateien entschlüsseln kann. Im Moment haben wir sie in unserer Enterprise-Passwortverwaltungslösung, aber es von dort zu bekommen und dann zum Testen von Backups zu verwenden, ist ein manueller Prozess. Als nächstes planen wir, Vault by Hashicorp zu implementieren und damit nahtlos und auf den designierten Hosts den geheimen Schlüssel zur Entschlüsselung abzurufen und ihn dann aus dem lokalen Ring zu entfernen, damit er für automatisierte Tests leicht verfügbar und dennoch geschützt ist.

Letztendlich haben wir alle unsere Datenbank-Backups rechtzeitig an unsere SOC2-Anforderungen angepasst, ohne die Backup-Leistung oder die SLA für die Notfallwiederherstellung zu opfern. Es hat mir viel Spaß gemacht, mit unserem InfoSec-Team an dieser Aufgabe zu arbeiten, und ich habe neue Tools gelernt. Außerdem ist es immer schön, wenn die einfachste Lösung am Ende die geeignetste für die eigene Aufgabe ist.