Hier beschreibe ich, wie ich einen Hetzner-Server mit …">

Intelligente Lösungen
in neuer Dimension

Hetzner: Ubuntu-20.04 mit verschlüsselter Platte installieren

Hier beschreibe ich, wie ich einen Hetzner-Server mit verschlüsselter Platte installiere. Ich orientiere mich an dieser Beschreibung – disk-encryption-hetzner und an Verschlüsselter Ubuntu 18.04 Server; per SSH entsperrbar.

Hetzner-Server

Ich habe einen Hetzner-Server über die Serverbörse bestellt und meinen SSH-Schlüssel registriert.

Auf dem Rettungssystem kann ich mich damit anmelden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ ssh root@8.145.3.2
The authenticity of host '8.145.3.2 (8.145.3.2)' can't be established.
ECDSA key fingerprint is ee:fd:95:77:cc:f4:9c:5d:3c:22:10:39:8a:8e:80:55.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '8.145.3.2' (ECDSA) to the list of known hosts.

-------------------------------------------------------------------

  Welcome to the Hetzner Rescue System.
...
-------------------------------------------------------------------

Rescue System up since 2020-10-23 14:16 +02:00

Hardware data:

   CPU1: AMD Ryzen 5 3600 6-Core Processor (Cores 12)
   Memory:  64258 MB
   Disk /dev/nvme0n1: 512 GB (=> 476 GiB) doesn't contain a valid partition table
   Disk /dev/nvme1n1: 512 GB (=> 476 GiB) doesn't contain a valid partition table
   Total capacity 953 GiB with 2 Disks

Network data:
   eth0  LINK: yes
         MAC:  a8:XX:...
         IP:   8.145.3.2
         IPv6: 2a01:XXX:...:2/64
         Intel(R) Gigabit Ethernet Network Driver

Installation Minimal-Ubuntu

Zuerst installieren wir ein Minimal-Ubuntu. Das Minimal-Ubuntu läuft ohne Verschlüsselung und wird später in die verschlüsselten Plattenbereiche umkopiert.

Anmelden am Rettungssystem

1
2
3
4
5
6
7
8
desktop:~$ ssh root@8.145.3.2
-------------------------------------------------------------------

  Welcome to the Hetzner Rescue System.
...
-------------------------------------------------------------------
...
rescue:/#

Grundinstallation

Die Grundinstallation sollte diese Anforderungen erfüllen:

  • möglichst kompakt
  • keine komplizierte Plattenaufteilung (nur ein Bereich)

Sie wird später umkopiert in die finale Installation. Dabei kann dann auch eine anspruchsvolle Plattenaufteilung erfolgen, bspw. separater /tmp-Bereich!

Interaktiv

1
rescue:/# installimage

Dann Fragen beantworten! Am Ende gibt es nach der Installation eine Datei “installimage.conf”, die als “vorgefertigte Konfiguration” verwendet werden kann – falls man die Grundinstallation wiederholen möchte!

Vorgefertigte Konfiguration

Datei /autosetup

Inhalt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#
# Hetzner Online GmbH - installimage
#
# This file contains the configuration used to install this
# system via installimage script. Comments have been removed.
#
# More information about the installimage script and
# automatic installations can be found in our wiki:
#
# http://wiki.hetzner.de/index.php/Installimage
#

DRIVE1 /dev/nvme0n1
DRIVE2 /dev/nvme1n1
SWRAID 1
SWRAIDLEVEL 1
HOSTNAME hetzner-de-ryzen
PART /boot  ext3     512M
PART lvm    vg0       all
LV vg0   root   /        ext4         10G
LV vg0   swap   swap     swap          4G
IMAGE /root/.oldroot/nfs/install/../images/Ubuntu-2004-focal-64-minimal.tar.gz

Ablegen auf dem Hetzner-Server:

  1. Obigen Inhalt “kopieren”
  2. Im Rettungssystem: cat >/autosetup (bleibt “hängen”)
  3. Zuvor kopierten Inhalt “einfügen”
  4. Strg-D
  5. Es erscheint wieder die Eingabeaufforderung

Installieren

1
2
3
4
5
6
7
rescue:/# installimage
Found AUTOSETUP file '/autosetup'
Running unattended installimage installation ...

DRIVE1 /dev/nvme0n1
DRIVE2 /dev/nvme1n1
...

Neustart

1
rescue:/# reboot

Anmelden am Minimal-Ubuntu

1
2
3
4
5
6
desktop:~$ ssh-keygen -f "/home/uli/.ssh/known_hosts" -R 8.145.3.2
desktop:~$ ssh root@8.145.3.2
...
39 packages can be updated.
29 updates are security updates.
mini-ubuntu:/#

Sichten Plattenplatz

1
2
3
4
5
6
7
8
9
10
11
mini-ubuntu:/# df -h
Filesystem            Size  Used Avail Use% Mounted on
udev                   32G     0   32G   0% /dev
tmpfs                 6.3G  928K  6.3G   1% /run
/dev/mapper/vg0-root  9.8G  1.2G  8.2G  13% /
tmpfs                  32G     0   32G   0% /dev/shm
tmpfs                 5.0M     0  5.0M   0% /run/lock
tmpfs                  32G     0   32G   0% /sys/fs/cgroup
/dev/mapper/vg0-tmp   4.9G   21M  4.6G   1% /tmp
/dev/md0              487M   82M  380M  18% /boot
tmpfs                 6.3G     0  6.3G   0% /run/user/0

Aktualisierungen einspielen und aufräumen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mini-ubuntu:/# apt update
mini-ubuntu:/# apt upgrade
# Dauert eine ganze Weile, es wird u.a. ein
# neuer Linux-Kernel installiert
#  5.4.0-47-generic
#  5.4.0-52-generic
mini-ubuntu:/# apt clean
mini-ubuntu:/# reboot
desktop:~$ ssh root@8.145.3.2
mini-ubuntu:/# dpkg --get-selections linux*
linux-base                    install
linux-firmware                    install
linux-image-5.4.0-47-generic          install
linux-image-5.4.0-52-generic          install
linux-image-generic               install
linux-modules-5.4.0-47-generic            install
linux-modules-5.4.0-52-generic            install
linux-modules-extra-5.4.0-47-generic      install
linux-modules-extra-5.4.0-52-generic      install
mini-ubuntu:/# apt purge `dpkg --get-selections linux*-47*|cut -f1`
mini-ubuntu:/# df -h
Filesystem            Size  Used Avail Use% Mounted on
udev                   32G     0   32G   0% /dev
tmpfs                 6.3G  932K  6.3G   1% /run
/dev/mapper/vg0-root  9.8G  1.6G  7.8G  17% /
tmpfs                  32G     0   32G   0% /dev/shm
tmpfs                 5.0M     0  5.0M   0% /run/lock
tmpfs                  32G     0   32G   0% /sys/fs/cgroup
/dev/mapper/vg0-tmp   4.9G   21M  4.6G   1% /tmp
/dev/md0              487M   82M  380M  18% /boot
tmpfs                 6.3G     0  6.3G   0% /run/user/0

Entsperren per SSH vorbereiten

Busybox und Dropbear installieren

1
2
mini-ubuntu:/# apt install joe busybox dropbear-initramfs cryptsetup-initramfs
mini-ubuntu:/# apt clean

/etc/initramfs-tools/initramfs.conf anpassen

  • Alt: BUSYBOX=auto
  • Neu: BUSYBOX=y

/etc/dropbear-initramfs/authorized_keys

1
mini-ubuntu:/ # cp ~/.ssh/authorized_keys /etc/dropbear-initramfs/authorized_keys

Rettungssystem erneut starten

  1. In der Web-Oberfläche von Hetzner das Rettungssystem aktivieren
  2. Neustart: ssh root@8.145.3.2 reboot

Verschlüsselung einrichten

Anmelden am Rettungssystem

1
2
3
desktop:~$ ssh-keygen -f "/home/uli/.ssh/known_hosts" -R 8.145.3.2
desktop:~$ ssh root@8.145.3.2
rescue:/#

Mini-Ubuntu einbinden

1
2
3
rescue:/# vgscan -v
rescue:/# vgchange -a y
rescue:/# mount /dev/mapper/vg0-root /mnt

Mini-Ubuntu kopieren

1
2
3
4
5
6
# Resync unterbrechen
rescue:/# echo 0 >/proc/sys/dev/raid/speed_limit_max
rescue:/# mkdir /oldroot
rescue:/# cp -a /mnt/. /oldroot/.
# Resync fortsetzen
rescue:/# echo 200000 >/proc/sys/dev/raid/speed_limit_max

Mini-Ubuntu “ausbinden”

1
rescue:/# umount /mnt

Unverschlüsselte LVM-Volume-Group löschen

1
2
3
4
5
6
7
rescue:/# vgremove vg0
Do you really want to remove volume group "vg0" containing 2 logical volumes? [y/n]: y
Do you really want to remove active logical volume vg0/swap? [y/n]: y
  Logical volume "swap" successfully removed
Do you really want to remove active logical volume vg0/root? [y/n]: y
  Logical volume "root" successfully removed
  Volume group "vg0" successfully removed

Sichtung Plattenstatus

1
2
3
4
5
6
7
8
9
10
11
rescue:/# cat /proc/mdstat
Personalities : [raid1] 
md1 : active raid1 sda2[0] sdb2[1]
      2929608128 blocks super 1.2 [2/2] [UU]
      [====>................]  resync = 23.4% (686186304/2929608128) finish=231.4min speed=161542K/sec
      bitmap: 17/22 pages [68KB], 65536KB chunk

md0 : active raid1 sda1[0] sdb1[1]
      523264 blocks super 1.2 [2/2] [UU]
      
unused devices: <none>

Hierbei ist:

  • md0: /boot
  • md1: Volume für LVM

MD1 verschlüsseln

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
rescue:/# cryptsetup --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time=10000 luksFormat /dev/md1
WARNING: Device /dev/md1 already contains a 'LVM2_member' superblock signature.

WARNING!
========
This will overwrite data on /dev/md1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/md1: {meinKennwort}
Verify passphrase: {meinKennwort}
rescue:/# cryptsetup open /dev/md1 cryptroot
Enter passphrase for /dev/md1: {meinKennwort}
rescue:/# pvcreate /dev/mapper/cryptroot
  Physical volume "/dev/mapper/cryptroot" successfully created.
rescue:/# vgcreate vg0 /dev/mapper/cryptroot
  Volume group "vg0" successfully created
rescue:/# lvcreate -n swap -L4G vg0
  Logical volume "swap" created.
rescue:/# lvcreate -n root -L20G vg0
  Logical volume "root" created.
rescue:/# mkfs.ext4 /dev/vg0/root
mke2fs 1.44.5 (15-Dec-2018)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: 97b9a0f6-ccc5-4b4f-88c7-5de9b6cd83a5
Superblock backups stored on blocks: 
  32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
  4096000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

rescue:/# mkswap /dev/vg0/swap
Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
no label, UUID=c1501715-292b-44f2-addb-c9ab60195b97

Verschlüsselte Plattenbereiche einbinden

1
rescue:/# mount /dev/vg0/root /mnt

Mini-Ubuntu in verschlüsselten Plattenbereich kopieren

1
2
3
4
5
# Resync unterbrechen
rescue:/# echo 0 >/proc/sys/dev/raid/speed_limit_max
rescue:/# cp -a /oldroot/. /mnt/.
# Resync fortsetzen
rescue:/# echo 200000 >/proc/sys/dev/raid/speed_limit_max

Finale Installation einbinden

1
2
3
4
5
6
rescue:/# mount --bind /dev /mnt/dev
rescue:/# mount --bind /sys /mnt/sys
rescue:/# mount --bind /proc /mnt/proc
rescue:/# chroot /mnt
final:/# mount /boot
final:/#

/etc/crypttab

1
2
# <target name> <source device>         <key file>      <options>
cryptroot /dev/md1 none luks,discard

initramfs neu schreiben

1
2
final:/# update-initramfs -u
update-initramfs: Generating /boot/initrd.img-5.4.0-52-generic

GRUB neu schreiben

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final:/# update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/hetzner.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.4.0-52-generic
Found initrd image: /boot/initrd.img-5.4.0-52-generic
done
oot@rescue / # grub-install /dev/nvme0n1
Installing for i386-pc platform.
Installation finished. No error reported.
root@rescue / # grub-install /dev/nvme1n1
Installing for i386-pc platform.
Installation finished. No error reported.

Finale Installation ausbinden

1
2
3
4
5
final:/# umount /boot
final:/# exit
rescue:/# umount /mnt/proc /mnt/sys /mnt/dev
rescue:/# umount /mnt
rescue:/# sync

Neustart

1
rescue:/# reboot

Schlüsseleingabe beim Boot-Vorgang

1
2
3
4
5
6
7
8
9
10
11
12
13
14
desktop:~$ ssh  -o UserKnownHostsFile=/dev/null root@8.145.3.2
The authenticity of host '8.145.3.2 (8.145.3.2)' can't be established.
ECDSA key fingerprint is ee:fd:95:77:cc:f4:9c:5d:3c:22:10:39:8a:8e:80:55.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '8.145.3.2' (ECDSA) to the list of known hosts.
To unlock root partition, and maybe others like swap, run `cryptroot-unlock`

BusyBox v1.27.2 (Ubuntu 1:1.27.2-2ubuntu3.2) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# cryptroot-unlock
Please unlock disk cryptroot (/dev/md1): {meinKennwort}
Error: Timeout reached while waiting for PID 388.
# exit

Anmelden am gestarteten Rechner

1
2
3
4
5
6
7
8
9
desktop:~$ ssh-keygen -f "/home/uli/.ssh/known_hosts" -R 8.145.3.2
desktop:~$ ssh root@8.145.3.2
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-65-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
...
sb35:/#

Entsperren mit zweigeteiltem Schlüssel

Der zweigeteilte Schlüssel sieht so aus:

  • Schlüssel Teil 1: Porsche911
  • Schlüssel Teil 2: {geheimerZweiterTeil}
  • Schlüssel gesamt: Porsche911_{geheimerZweiterTeil}

Zweigeteilten Schlüssel in LUKS hinterlegen

1
2
3
4
5
desktop:~$ ssh root@8.145.3.2
sb35:/# cryptsetup luksAddKey /dev/md1
Enter any existing passphrase: {keinKennwort}
Enter new passphrase for key slot: Porsche911_{geheimerZweiterTeil}
Verify passphrase: Porsche911_{geheimerZweiterTeil}

Entsperrskript hinterlegen

/etc/initramfs-tools/unlock-disks.sh:

1
2
#!/bin/sh
(cat; echo -n "_{geheimerZweiterTeil}")|tr -d "\r\n"|cryptroot-unlock

/etc/initramfs-tools/hooks/unlock-disks-hook:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/sh
#
#
# This is an example hook script.  It will be run by 'mkinitramfs'
# when it creates the image.  It's job is to decide which files to
# install, then install them into the staging area, where the
# initramfs is being created.  This happens when a new 'linux-image'
# package is installed, or when the administrator runs 'mkinitramfs'
# by hand to update an initramfs image.
#
#  CONFDIR -- usually /etc/initramfs-tools, can be set on mkinitramfs
#      command line.
#
#  DESTDIR -- The staging directory where we are building the image.
#
# see initramfs-tools(8)

#
# List the soft prerequisites here.  This is a space separated list of
# names, of scripts that are in the same directory as this one, that
# must be run before this one can be.
#
PREREQ=""

prereqs()
{
  echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
  prereqs
  exit 0
  ;;
esac


# You can do anything you need to from here on.
#

# Source the optional 'hook-functions' scriptlet, if you need the
# functions defined within it.  Read it to see what is available to
# you.  It contains functions for copying dynamically linked program
# binaries, and kernel modules into the DESTDIR.
#
. /usr/share/initramfs-tools/hook-functions

copy_file binary "${CONFDIR}/unlock-disks.sh" "/bin"

exit 0
  • Zugriffsrechte anpassen:
    • chmod 700 /etc/initramfs-tools/unlock-disks.sh
    • chmod +x /etc/initramfs-tools/hooks/unlock-disks-hook
  • Initramfs neu erzeugen: update-initramfs -u

Boot-Vorgang testen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
desktop:~$ ssh root@8.145.3.2
final:/# reboot
Connection to 8.145.3.2 closed by remote host.
Connection to 8.145.3.2 closed.
desktop:~$ echo "Porsche911"|ssh -o UserKnownHostsFile=knownHosts-boot root@8.145.3.2 /bin/unlock-disks.sh
The authenticity of host '8.145.3.2 (8.145.3.2)' can't be established.
ECDSA key fingerprint is 68:...
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '8.145.3.2' (ECDSA) to the list of known hosts.
Please unlock disk cryptroot (/dev/md1)
Error: Timeout reached while waiting for PID 394.
desktop:~$ ssh root@8.145.3.2
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-52-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
...
final:/#

Weitere SSH-Schlüssel für den Boot-Vorgang freischalten

  • Datei “etc/dropbear-initramfs/authorized_keys” erweitern um den PubKey:
1
2
...
    command="/bin/unlock-disks.sh" ssh-rsa AAAAB3NzaC1yc2EAAAA...KjErh Gerd Mueller
  • Initramfs neu erzeugen: update-initramfs -u
  • Ersten Schlüsselteil (“Porsche911”) an den Inhaber des Schlüssels übermitteln
  • Entsperrkommando an den Inhaber des Schlüssels übermitteln: echo "Porsche911"|ssh -o UserKnownHostsFile=knownHosts-boot root@8.145.3.2

Links

Server ist sehr langsam

Während der Installation und eine ganze Weile danach habe ich den Eindruck, dass der Server sehr langsam ist. Insbesondere wenn Datenbereiche kopiert werden, dauert das ewig.

Sichtung von “/proc/mdstat” zeigt, dass der Resync des von mir verwendeten Raid1 noch im Gange ist:

1
2
3
4
5
6
...
md1 : active raid1 sdb2[1] sda2[0]
      2929608128 blocks super 1.2 [2/2] [UU]
      [=======>.............]  resync = 36.0% (1055877824/2929608128) finish=214.0min speed=145870K/sec
      bitmap: 16/22 pages [64KB], 65536KB chunk
...

Man kann die Abläufe beschleunigen, indem man temporär den Resync-Vorgang unterbricht:

  • unterbrechen: echo 0 >/proc/sys/dev/raid/speed_limit_max
  • fortsetzen: echo 200000 >/proc/sys/dev/raid/speed_limit_max

Nachdem der Resync fertig ist, sollte der Rechner dauerhaft mit der üblichen Geschwindigkeit funktionieren!