Einen bestehenden Debian Wheezy-Server auf Verschlüsselung umstellen

Einleitung

Ein vor langer Zeit eingerichteter Server bereitet Probleme beim Einspielen von Updates, da ein Dateisystem zu klein geworden ist. Da das Partitionierungsschema zu inflexibel geworden ist und die Maschine noch ganz ohne Verschlüsselung arbeitet, müssen einige Änderungen vorgenommen werden:

Vorher: Ein Debian-Server läuft mit mehreren RAID1 für die verschiedenen Dateisysteme ohne Verschlüsselung zu nutzen.

Nachher: Der Server läuft mit zwei RAID1, eins für /boot und eins für die Verschlüsselung mit LUKS. Über die Verschlüsselung ist ein LVM gelegt, das für die weiteren Dateisysteme sorgt.

Überblick:


Die Ausgangssituation

Ein bestehendes Debian-Wheezy-System bereitet Probleme, da es damals mit einer sehr kleinen /boot-Partition aufgesetzt wurde. Beim Einspielen von Updates geht dem System so jedes Mal der Speicherplatz aus. Außerdem sind alle vier möglichen primären Partitionen belegt, so daß kaum Erweiterungen oder Umbauten durchzuführen sind. Da die Partitionen zu dicht aufeinander folgen ist nicht einmal mit fixparts ein Umwandeln in logische Partitionen möglich.

Da zur Problembehebung ohnehin die Partitionierung angefaßt werden muß, soll die Gelegenheit gleich genutzt werden, um auch für eine Verschlüsselung aller Partitionen (bis auf /boot selbst) zu sorgen. Als erstes wird natürlich ein Backup vom Ist-Stand angefertigt.

Das System läuft auf drei Festplatten, welche identisch partitioniert sind. Diese Anleitung sollte mit wenigen Anpassungen aber auch für Systeme mit nur zwei Festplatten im RAID1 funktionieren. fdisk -l /dev/sda zeigt:

Disk /dev/sda: 250.1 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders, total 488397168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0006b466

   Device Boot      Start         End      Blocks   Id  System
   /dev/sda1   *          63       96389       48163+  fd  Linux raid autodetect
   /dev/sda2           96390     4980149     2441880   82  Linux swap / Solaris
   /dev/sda3         4980150    44050229    19535040   fd  Linux raid autodetect
   /dev/sda4        44050230   488392064   222170917+  fd  Linux raid autodetect
Und ein df -h offenbart:
Dateisystem                                            Größe Benutzt Verf. Verw% Eingehängt auf
udev                                                     10M       0   10M    0% /dev
tmpfs                                                   304M    380K  304M    1% /run
/dev/disk/by-uuid/329d6229-355c-4d19-bf3f-4b2de1326ef3   19G    2.0G   16G   12% /
tmpfs                                                   5.0M       0  5.0M    0% /run/lock
tmpfs                                                   1.1G       0  1.1G    0% /run/shm
/dev/md1                                                209G     49G  161G   24% /vol/data
/dev/md2                                                 46M     43M  238K  100% /boot
Die RAID-Verbünde sind alle synchron, wie cat /proc/mdstat zeigt:
Personalities : [raid1] 
md2 : active raid1 sdb1[0] sdc1[2] sda1[1]
      48064 blocks [3/3] [UUU]
      
md1 : active raid1 sdb4[0] sdc4[2] sda4[1]
      222170816 blocks [3/3] [UUU]
      
md0 : active raid1 sdb3[0] sdc3[2] sda3[1]
      19534976 blocks [3/3] [UUU]
      
unused devices: <none>

Das Vorgehen

Da alles auf RAID1 läuft, kann die Umstellung zu größeren Teilen im laufenden Betrieb geschehen. Zunächst wird /dev/sda aus dem laufenden System heraus auf den neuen Stand gebracht. Falls bei den kritischen Prozessen etwas schief gehen sollte, kann so immer noch von der zweiten oder dritten Platte auf das alte System zurückgewechselt werden, indem die Bootplatte getauscht wird. Für den Ausfall einer Festplatte ist das bestehende RAID-System ja ohnehin ausgelegt.

Die Schritte im Einzelnen:

Erst wenn das frisch gestartete neue System wie gewünscht funktioniert, werden also auch /dev/sdb und /dev/sdc nacheinander umgestellt und in die neuen RAID-Verbünde aufgenommen und synchronisiert.


Die Details

Software nachinstallieren
Da auf dem System bisher weder LVM noch Verschlüsselung lief und es demnächst aus der Ferne freigeschaltet werden soll, werden folgende Pakete installiert:
apt-get install lvm2 cryptsetup dropbear busybox initramfs-tools

/dev/sda freistellen
Damit die erste Festplatte gefahrlos umpartitioniert werden kann, müssen zunächst alle verwendeten Partitionen aus den RAID-Verbünden abgemeldet werden. Der Vorgang läßt sich bequem parallel in einer weiteren Sitzung mit watch cat /proc/mdstat beobachten. Außerdem muß der aktive Swap-Bereich abgemeldet werden.
mdadm --manage /dev/md0 --fail /dev/sda3
mdadm /dev/md0 -r /dev/sda3
mdadm --manage /dev/md1 --fail /dev/sda4
mdadm /dev/md1 -r /dev/sda4
mdadm --manage /dev/md2 --fail /dev/sda1
mdadm /dev/md2 -r /dev/sda1
swapoff /dev/sda2

Neupartitionieren von /dev/sda
Mit fdisk /dev/sda wird die Partitionierung angepaßt: Bestehende Partitionen werden gelöscht und es wird eine primäre Partition für das /boot-RAID1 und eine logische Partition für das Verschlüsselungs-RAID1 angelegt:
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      377047      187500   fd  Linux raid autodetect
/dev/sda2          377048   488397167   244010060    5  Extended
/dev/sda5          379096   488397167   244009036   fd  Linux raid autodetect

Neue RAID-Verbünde für /boot und Verschlüsselung einrichten
Für /boot wird ein neuer RAID1-Verbund mit zunächst nur einer eingebundenen Partition erstellt:
mdadm --create /dev/md/boot --name=boot --level 1 --raid-devices 3 /dev/sda1 missing missing
Für die Verschlüsselung geschieht dies analog:
mdadm --create /dev/md/crypt --name=crypt --level 1 --raid-devices 3 /dev/sda5 missing missing
Da mdadm intern offenbar zunächst noch selbst durchnummeriert, wurden hierbei tatsächlich /dev/md127 und /dev/md126 erzeugt, wobei ein ls -l /dev/md/ die Zuordnung offenbart:
insgesamt 0
lrwxrwxrwx 1 root root 8 Apr 12 16:01 boot -> ../md127
lrwxrwxrwx 1 root root 8 Apr 12 16:02 crypt -> ../md126

Einrichten der Verschlüsselung
Die gerade bekannt gewordene Zuordnung der md-Geräte wird für das Erzeugen des Eintrags in der /etc/crypttab benötigt. Die Verschlüsselung wird eingerichtet:
cryptsetup luksFormat /dev/md/crypt
echo -en "md.sys\t/dev/disk/by-uuid/`ls -l /dev/disk/by-uuid/ | grep md126 | cut -d ' ' -f 9`\tnone\tluks\n" >> /etc/crypttab
cryptdisks_start md.sys

Einrichten von LVM
Für LVM wird zunächst die Markierung eines „Physical Volume“ gesetzt. Dann wird erst eine neue „Volume Group“ und anschließend werden darin mehrere „Logical Volumes“ für die gewünschten Dateisysteme und Swap erstellt:
pvcreate /dev/mapper/md.sys
vgcreate sys /dev/mapper/md.sys
lvcreate -L2GB --name swap sys
lvcreate -L12GB --name root sys
lvcreate -L218GB --name data sys

Neue Dateisysteme erzeugen
Die neuen Dateisysteme werden erzeugt:
mkswap -L"SWAP"/dev/sys/swap
mkfs.ext2 -m 5 -L"BOOT" /dev/md/boot
mkfs.ext4 -m 5 -L"ROOT" /dev/sys/root
mkfs.ext4 -m .1 -L"DATA" /dev/sys/data

Laufende Dienste stillegen
Nun müssen diejenigen Dienste abgeschaltet werden, die Änderungen im Dateisystem auslösen, um im nächsten Schritt die Daten aus den alten auf die neuen Dateisysteme gefahrlos übertragen zu können.

Auf dem Beispielserver laufen mehrere OpenVZ-VMs, die jeweils mit vzctl stop CTID beendet werden. Damit diese beim nächsten Start nicht automatisch wieder starten (vorher möchte ich das System genau prüfen), wird in den jeweiligen Konfigurationsdateien der VMs zudem ONBOOT=no gesetzt.

Ebenso interessant könnten Web-, FTP- und Maildienste sein, bei denen es sonst vorkommen könnte, daß ein Benutzer in der Zwischenzeit neue Daten empfängt oder hochlädt und diese dann im neuen System vermißt, weil das Übertragen bereits das Dienstverzeichnis bearbeitet hatte, als die neuen Daten eintrafen.


Übertragen der Daten auf die neuen Dateisysteme
Die neuen Dateisysteme werden in einem neuen Mountpunkt /target eingehängt und die Daten aus dem laufenden System dorthin kopiert, außerdem werden für das chroot im nächsten Schritt weitere Verzeichnisse mittels bind-mount zur Verfügung gestellt:
mkdir /target
mount /dev/sys/root /target
rsync -aHxv / /target/

mount /dev/md/boot /target/boot
rsync -aHxv /boot/ /target/boot

mount /dev/sys/data /target/vol/data
rsync -aHxv /vol/data/ /target/vol/data/

mount --bind /sys /target/sys
mount --bind /proc /target/proc
mount --bind /dev /target/dev

Anpassen des Systems an die neuen Gegebenheiten
In das neue System wechseln:
chroot /target
Nun müssen noch ein paar Anpassungen an den Konfigurationsdateien durchgeführt werden. Die Datei /etc/fstab wird geändert:
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults                        0 0
/dev/sys/root   /               ext4    defaults,errors=remount-ro      0 1
/dev/md/boot    /boot           ext2    defaults,errors=remount-ro      0 2
/dev/sys/data   /vol/data       ext4    defaults,errors=remount-ro      0 3
/dev/sys/swap   none            swap    sw                              0 0
Die Datei /etc/mdadm/mdadm.conf wird ebenfalls angepaßt. Die neu hinzugekommenen RAID-Verbünde werden mit mdadm -Db /dev/md/* ausgelesen und die alten RAID-Verbünde umbenannt:
DEVICE partitions
CREATE owner=root group=disk mode=0660 auto=yes
HOMEHOST <system>
ARRAY /dev/md6 metadata=0.90 UUID=9aab5666:2a6ef367:5706f916:0d9490d7
ARRAY /dev/md7 metadata=0.90 UUID=a22ef756:5db20b39:bfeba281:cd12092d
ARRAY /dev/md8 metadata=0.90 UUID=19d030c1:137f3413:f464e451:9a3b8e54
ARRAY /dev/md/boot metadata=1.2 name=servername:boot UUID=c51388e4:0a8a857e:e2d7cf39:65e54b69
ARRAY /dev/md/crypt metadata=1.2 name=servername:crypt UUID=65c2915f:1b1dc7b0:f1bb02d1:154d0002
Darüberhinaus werden die für die Freischaltung der Verschlüsselung über SSH nötigen Vorkehrungen analog zum Vorgehen in der Anleitung „Debian Wheezy mit verschlüsselter Rootpartition und Freischaltung via ssh“ getroffen:
  1. Anpassen der Datei /etc/initramfs-tools/root/.ssh/authorized_keys
  2. Eintragen des Netzwerkkartenmoduls in die Datei /etc/initramfs-tools/modules
  3. Eintragen der IP-Adressdaten in die Datei /etc/initramfs-tools/conf.d/network_config
  4. Erweitern der Datei /etc/rc.local
  5. Einspielen des Skripts /etc/initramfs-tools/hooks/mount_cryptroot (ausführbarmachen nicht vergessen)
Abschließend werden noch die Initrds aktualisiert:
update-initramfs -k all -u
Um sicherzugehen, daß der Bootloader auch wirklich eingerichtet ist, wird noch ausgeführt:
grub-install /dev/sda
update-grub

Neustart ins neue System
Bevor der Neustart durchgeführt wird, werden die neuen Dateisysteme noch sauber ausgehängt:
exit   # aus dem chroot wieder aussteigen
umount /target/dev/
umount /target/sys/
umount /target/proc/
umount /target/vol/data/
umount /target/boot
umount /target
reboot
Beim Hochfahren des Systems wird die neue Passphrase für die LUKS-Verschlüsselung abgefragt. Danach erst fährt das System komplett hoch.

Starten der Dienste
Nach dem genauen Prüfen, ob alles richtig läuft, können die oben gestoppten Dienste wieder einzeln gestartet werden. Hier sind das die verschiedenen OpenVZ-VMs, in deren Konfiguration wieder das ursprüngliche ONBOOT=yes eingestellt wird.

Ausschalten der alten RAID-Verbünde
Jetzt ist noch einmal Gelegenheit auf die alten RAID-Verbünde zuzugreifen und evtl. in der Zwischenzeit angefallene Daten, wie z.B. Logdateien zu sichern. Danach werden die alten RAID-Verbünde abgeschaltet:
mdadm --stop /dev/md6
mdadm --stop /dev/md7
mdadm --stop /dev/md8
Es werden noch die nun überflüssigen Einträge aus der Datei /etc/mdadm/mdadm.conf entfernt und die Initrds werden noch einmal mit update-initramfs -k all -u aktualisiert.

Neupartionieren von /dev/sdb und /dev/sdc und Aufnehmen in die neuen RAID-Verbünde
Nachdem die Festplatten /dev/sdb und /dev/sdc nun freigestellt sind, wird die Partitionnierung von /dev/sda übertragen und die neuen Partitionen werden den jeweiligen neuen RAID-Verbünden zugewiesen.
swapoff /dev/sdb2
sfdisk -d /dev/sda | sfdisk /dev/sdb
mdadm /dev/md/boot -a /dev/sdb1
mdadm /dev/md/crypt -a /dev/sdb5
grub-install /dev/sdb

swapoff /dev/sdc2
sfdisk -d /dev/sda | sfdisk /dev/sdc
mdadm /dev/md/boot -a /dev/sdc1
mdadm /dev/md/crypt -a /dev/sdc5
grub-install /dev/sdc
Nachdem nun noch der Resync durchgelaufen ist, ist das System fertig eingerichtet.

Verweise

Weitere Webseiten rund um das Thema: