Vorhandenes MD-RAID1 im laufenden Betrieb verschlüsseln

aus PUG, der Penguin User Group
Wechseln zu: Navigation, Suche

Vorhanden ist ein MD-RAID1 über zwei Partitionen je 400GB auf zwei Festplatten. Dieses soll im laufenden Betrieb auf LUKS-Verschlüsselung umgestellt werden.

Das ursprüngliche Ziel war, die Umstellung mit Hilfe einer externen Festplatte ohne Verlust der Redundanz durchzuführen. Diese Idee habe ich wieder verworfen, da ich große Mengen an temporärem Platz auf externen Platten benötigt hätte. Da ich ein vernünftiges Backup habe, habe ich mich entschlossen, die Redundanz für den Zeitraum der Umstellung aufzugeben.

Ursprungskonstellation

Das MD-Device /dev/md1 ist als Physical Volume in der Volume Group vg00 eingerichtet:

/dev/sda2 \
           --> /dev/md1 --> vg00
/dev/sdb2 /

Schritt 1: Eine der ursprünglichen Festplatten freimachen

Zunächst hebe ich die Festplattenspiegelung auf:

mdadm /dev/md1 --fail /dev/sdb2
mdadm /dev/md1 --remove /dev/sdb2

Jetzt sieht die Konstellation so aus:

/dev/sda2 --> /dev/md1 (degraded) --> vg00
/dev/sdb2 --> Unbenutzt

Schritt 3: Neues RAID1 einseitig aufsetzen

Jetzt lege ich ein degraded RAID1 (mit nur einer Festplatte) auf der freigewordenen /dev/sdb2 an:

mdadm --create /dev/md2 --raid-devices=2 --level=1 /dev/sdb2 missing

Das neue Device wird in die /etc/mdadm/mdadm.conf eingetragen:

mdadm --detail --scan  | grep '/dev/md2' >> /etc/mdadm/mdadm.conf 

Damit bin ich bei folgendem Stand:

/dev/sda2 --> /dev/md1 (degraded) --> vg00
/dev/sdb2 --> /dev/md2 (degraded) --> Unbenutzt

Schritt 4: Neues RAID1 verschlüsseln

Über das neue /dev/md2 wird jetzt die Verschlüsselungsebene gelegt. Da ich dieses Device später wieder in /dev/md1 umbenennen werde, arbeite ich hier schon mit dem Namen md1_crypt. Für den Anfang lege ich das Kennwort für die Verschlüsselung in einer Datei ab.

touch /etc/luks.key
chmod 600 /etc/luks.key
echo foo > /etc/luks.key
cryptsetup luksFormat /dev/md2 /etc/luks.key
cryptsetup luksOpen --key-file /etc/luks.key /dev/md2 md1_crypt 

Jetzt habe ich ein verschlüsseltes RAID1 (wenn auch nur mit einer Festplatte):

/dev/sda2 --> /dev/md1 (degraded) --> vg00
/dev/sdb2 --> /dev/md2 (degraded) --> /dev/mapper/md1_crypt --> Unbenutzt

An diesem Punkt lohnt sich ein vorläufiger Eintrag in die /etc/crypttab:

md1_crypt /dev/md2 /etc/luks.key luks

Schritt 5: Verschlüsseltes RAID1 der Volume Group hinzufügen

Damit bin ich auch schon so weit, daß ich meiner Volume Group ein neues Physical Volume hinzufügen kann:

pvcreate /dev/mapper/md1_crypt
vgextend vg00 /dev/mapper/md1_crypt

Womit ich die Zielkonstellation schon fast zur Hälfte erreicht habe:

/dev/sda2 --> /dev/md1 (degraded) --> vg00
/dev/sdb2 --> /dev/md2 (degraded) --> /dev/mapper/md1_crypt --> vg00

Schritt 6: Migration der Daten

Während die letzten Schritte schnell mit ein paar Sekunden Laufzeit ausgeführt wurden, kommen jetzt die langwierigsten Schritte der ganzen Maßnahme. Zunächst lasse ich die Daten der vg00 vom alten unverschlüsselten Physical Volume /dev/md1 auf das neue, verschlüsselte Physical Volume /dev/mapper/md1_crypt umziehen:

pvmove -v /dev/md1 /dev/mapper/md1_crypt

Ich lasse diesen Befehl in einer screen-Session laufen, denn dieser Schritt dauert relativ lange und außer der von pvmove ausgegebenen Prozentzahl ist es schwierig, eine vernünftige Fortschrittsanzeige zu bekommen. Obwohl die Daten im Rohzustand von einer Platte zur anderen geschoben werden und nicht in irgendwelche Netzwerkprotokolle übersetzt werden müssen, sollte man sich hier nicht auf weniger als 1-2 Stunden einstellen.

Die Volume Group ist jederzeit in einem definierten Zustand und die Migration kann bedenkenlos unterbrochen werden. Dank der vorher gemachten Einträge in /etc/crypttab und /etc/mdadm/mdadm.conf sollte das System sogar rebootfest sein.

Am Ende entferne ich /dev/md1 aus der Volume Group vg00:

vgreduce vg00 /dev/md1

Am Ende dieses Schritts sieht der Stand wie folgt aus:

/dev/sda2 --> /dev/md1 (degraded) --> Unbenutzt
/dev/sdb2 --> /dev/md2 (degraded) --> /dev/mapper/md1_crypt --> vg00

Schritt 7: Wiederherstellen der Spiegelung

Jetzt kann die leere Hülle des alten /dev/md1 komplett entfernt werden:

mdadm --stop /dev/md1

Der Eintrag für /dev/md1 kann aus /etc/mdadm/mdadm.conf gelöscht werden:

perl -i.bak -ne 'm#^ARRAY /dev/md1#||print' /etc/mdadm/mdadm.conf

Die freigewordene Partition wird /dev/md2 hinzugefügt, um wieder eine Spiegelung zu bekommen:

mdadm /dev/md2 --add /dev/sda2

Wie schon die Migration der Daten, kann die Synchronisation einige Stunden dauern. Den Fortschritt kann man am besten mit dem folgenden Kommando verfolgen:

watch cat /proc/mdstat

Damit ist alles erreicht, was im laufenden Betrieb möglich ist:

/dev/sda2 \
           --> /dev/md2 --> /dev/mapper/md1_crypt --> vg00
/dev/sdb2 /

Schritt 8: MD-Device umbenennen

Die Umbenennung von MD-Devices wird z.B. hier von Stephen Tweedie beschrieben.

Auf meinen Fall angewendet, heißt das, daß ich auf meinem System alle Filesysteme, die aus der vg00 kommen, in /etc/fstab auskommentiere und das System neu starte. Nach dem Reboot gehe ich wie folgt vor, um alles, was mit LUKS, LVM und MD-RAID zu tun hat, zu stoppen:

vgchange -an vg00
/etc/init.d/cryptdisks stop
mdadm --stop /dev/md2

Anschließend wird /etc/mdadm/mdadm.conf angepaßt:

# definitions of existing MD arrays
ARRAY /dev/md0 level=raid1 num-devices=2 UUID=91440e30:0b2928bf:8686f672:4a39f547
# ARRAY /dev/md2 level=raid1 num-devices=2 metadata=00.90 UUID=3dcd3499:f3e67274:d66856da:8e136666
ARRAY /dev/md1 level=raid1 num-devices=2 metadata=00.90 UUID=3dcd3499:f3e67274:d66856da:8e136666

Und in /etc/crypttab ist jetzt ebenfalls eine Änderung fällig:

# md1_crypt /dev/md2 /etc/luks.key luks
md1_crypt /dev/md1 /etc/luks.key luks

Jetzt kann das RAID1 aus den bestehenden Komponenten neu aufgebaut und die Verschlüsselung neu gestartet werden:

mdadm --assemble /dev/md1 --super-minor=2 --update=super-minor /dev/sda2 /dev/sdb2
/etc/init.d/cryptdisks start
vgchange -ay vg00

Die Optionen --super-minor und --update=super-minor haben folgende Bedeutung: Mit --super-minor=2 wird mdadm mitgeteilt, daß die beiden Komponenten vorher zu /dev/md2 gehört haben, und daß sie ohne weitere Rückfrage für das neue MD-Device verwendet werden sollen. --update sorgt anschließend dafür, daß diese Zuordnung zu einem MD-Device dauerhaft in den Metadaten der Komponenten geändert wird.

Anschließend aktiviere ich meine Filesysteme in /etc/fstab wieder und starte das System neu.

(Wer sich ohne Reboot durch diesen letzten Schritt durchgeboxt hat, ist ein Held, der aber sein System sicherheitshalber doch mal booten sollte, um zu sehen, ob er alles richtig gemacht hat.)

Hier ist die danach vorliegende, wirklich endgültige Konstellation:

/dev/sda2 \
           --> /dev/md1 --> /dev/mapper/md1_crypt --> vg00
/dev/sdb2 /

Nacharbeit: Verschlüsselung auf Handbetrieb umstellen

Da das Kennwort, das ich in /etc/luks.key eingetragen hatte, nicht trivial war, schreibe ich es mir jetzt auf. Anschließend lösche ich /etc/luks.key und ändere den Eintrag in /etc/crypttab ab, so daß ich beim Systemstart nach dem Kennwort gefragt werde:

# md1_crypt /dev/md1 /etc/luks.key luks
md1_crypt /dev/md1 none luks

--Martin 05:57, 9. Jun. 2009 (UTC)