Raspberry Pi 4 (8 GB) als Proxmox VE Test-Node
Installation von Debian 13 (Trixie) ARM64 auf einem Raspberry Pi 4 mit 8 GB RAM. Das Root-Dateisystem wird mit LUKS2 verschlüsselt und beim Booten über Dropbear-SSH entsperrt.
Die Einrichtung erfolgt von einem Linux-PC mit debootstrap und einer ARM64-chroot-Umgebung. Das System erhält eine feste IP-Adresse, automatische Zeitsynchronisierung und eine deutsche UTF-8-Locale.
1. Voraussetzungen
- Raspberry Pi 4 mit 8 GB RAM
- USB-SSD mit mindestens 64 GB
- Debian-13-Linux-PC
- Ethernet-Verbindung
- USB-Boot-fähige Raspberry-Pi-Firmware
- SSH-Schlüssel für Administration und LUKS-Entsperrung
Netzwerkkonfiguration
Hostname | darkside |
IP-Adresse | 10.100.0.61 |
Netzmaske | 255.255.0.0 (/16) |
Gateway | 10.100.0.1 |
DNS | 1.1.1.1 |
Interface | eth0 |
Zeitzone | Europe/Berlin |
Locale | de_DE.UTF-8 |
2. Datenträger vorbereiten
Die SSD besteht aus einer unverschlüsselten Boot-Partition und einer mit LUKS2 verschlüsselten Root-Partition.
Partition | Format | Verwendung |
|---|---|---|
Partition 1 | FAT32 | /boot/firmware |
Partition 2 | LUKS2 | Verschlüsseltes Root-Dateisystem |
cryptroot | ext4 | Debian und virtuelle Maschinen |
Alle folgenden administrativen Befehle werden als root ausgeführt.
Benötigte Pakete auf dem Linux-PC installieren:
apt update
apt install -y \
debootstrap \
debian-archive-keyring \
qemu-user \
qemu-user-binfmt \
binfmt-support \
cryptsetup \
parted \
dosfstools \
e2fsprogs \
ca-certificates
Datenträger identifizieren:
lsblk -o NAME,SIZE,MODEL,TYPE,MOUNTPOINTS
Im folgenden Beispiel wird /dev/sdb als Zielgerät verwendet. Die Gerätebezeichnung unbedingt prüfen. Alle Partitionen der SSD müssen ausgehängt sein.
Achtung: Die folgenden Befehle löschen sämtliche Daten auf dem ausgewählten Datenträger. Bei einem bereits installierten System diesen Abschnitt überspringen.
DISK=/dev/sdb
parted -s "$DISK" mklabel msdos
parted -s "$DISK" mkpart primary fat32 1MiB 1025MiB
parted -s "$DISK" mkpart primary 1025MiB 100%
parted -s "$DISK" set 1 boot on
partprobe "$DISK"
udevadm settle
Partitionen festlegen:
BOOT=/dev/sdb1
ROOT=/dev/sdb2
3. LUKS2-Verschlüsselung
Boot-Partition formatieren:
mkfs.vfat -F32 -n PVEBOOT "$BOOT"
Root-Partition mit AES-256-XTS und Argon2id verschlüsseln:
cryptsetup luksFormat \
--type luks2 \
--cipher aes-xts-plain64 \
--key-size 512 \
--pbkdf argon2id \
--pbkdf-memory 524288 \
--pbkdf-parallel 2 \
--iter-time 2000 \
--verify-passphrase \
"$ROOT"
Eine lange, zufällig erzeugte Passphrase verwenden. Die tatsächlichen Argon2-Parameter werden auf dem einrichtenden Rechner kalibriert und müssen später auf dem Raspberry Pi getestet werden.
LUKS-Partition öffnen:
cryptsetup open "$ROOT" cryptroot
Dateisystem erstellen:
mkfs.ext4 -L pve-root /dev/mapper/cryptroot
UUIDs ermitteln und notieren:
cryptsetup luksUUID "$ROOT"
blkid -s UUID -o value "$BOOT"
4. Debian installieren
Dateisysteme einhängen:
mkdir -p /mnt/Temp/1
mount /dev/mapper/cryptroot /mnt/Temp/1
mkdir -p /mnt/Temp/1/boot/firmware
mount "$BOOT" /mnt/Temp/1/boot/firmware
Debian 13 installieren:
debootstrap \
--arch=arm64 \
--keyring=/usr/share/keyrings/debian-archive-keyring.gpg \
trixie \
/mnt/Temp/1 \
https://deb.debian.org/debian
Crypttab konfigurieren
nano /mnt/Temp/1/etc/crypttab
Eintrag:
cryptroot UUID=LUKS-UUID none luks,initramfs
LUKS-UUID durch die zuvor ermittelte UUID ersetzen.
Fstab konfigurieren
nano /mnt/Temp/1/etc/fstab
Inhalt:
/dev/mapper/cryptroot / ext4 defaults,noatime 0 1
UUID=BOOT-UUID /boot/firmware vfat defaults,umask=0077 0 2
BOOT-UUID durch die UUID der FAT32-Partition ersetzen.
5. ARM64-chroot betreten
Systemdateisysteme einbinden:
for DIR in dev proc sys run; do
mount --rbind "/$DIR" "/mnt/Temp/1/$DIR"
mount --make-rslave "/mnt/Temp/1/$DIR"
done
DNS-Konfiguration für die Installation:
cp -L /etc/resolv.conf /mnt/Temp/1/etc/resolv.conf
ARM64-chroot betreten:
chroot /mnt/Temp/1 /bin/bash
Architektur prüfen:
dpkg --print-architecture
Die Ausgabe muss arm64 sein. Die folgenden Befehle werden innerhalb der chroot-Umgebung ausgeführt.
6. Debian-Basissystem
APT-Paketquellen prüfen:
nano /etc/apt/sources.list
Die folgenden Debian-Quellen verwenden. Gleichwertige vorhandene Einträge unter /etc/apt/sources.list.d nicht duplizieren.
deb https://deb.debian.org/debian trixie main non-free-firmware
deb https://deb.debian.org/debian trixie-updates main non-free-firmware
deb https://security.debian.org/debian-security trixie-security main non-free-firmware
Pakete installieren:
apt update
apt install -y \
linux-image-arm64 \
raspi-firmware \
initramfs-tools \
cryptsetup-initramfs \
dropbear-initramfs \
openssh-server \
ifupdown2 \
systemd-sysv \
systemd-timesyncd \
locales \
tzdata \
ca-certificates \
curl \
git \
nano \
less \
busybox
7. Locale konfigurieren
Das System erhält die deutsche UTF-8-Locale. Die Locale muss erzeugt werden, bevor sie von Shell, SSH und Programmen verwendet werden kann.
Locale-Konfiguration öffnen:
nano /etc/locale.gen
Folgende Zeile aktivieren:
de_DE.UTF-8 UTF-8
Falls ein Kommentarzeichen vor der Zeile steht, dieses entfernen.
Locale erzeugen:
locale-gen
Systemsprüngliche Locale setzen:
update-locale LANG=de_DE.UTF-8
Verfügbare Locales prüfen:
locale -a
Erwartete Ausgabe enthält:
de_DE.utf8
LC_ALL wird nicht dauerhaft gesetzt. Programme erhalten die gewünschten Kategorieeinstellungen über LANG oder spezifische LC_-Variablen.
Zeitzone einstellen
Zeitzone konfigurieren:
ln -sfn /usr/share/zoneinfo/Europe/Berlin /etc/localtime
echo Europe/Berlin > /etc/timezone
Zeitzone prüfen:
date
In einer chroot-Umgebung stammt die aktuelle Uhrzeit vom Linux-Host. Die eigentliche Netzwerkzeitsynchronisierung erfolgt später auf dem Raspberry Pi.
8. NTP-Zeitsynchronisierung konfigurieren
Der Raspberry Pi besitzt normalerweise keine batteriegepufferte Echtzeituhr. Nach einem Neustart kann die Systemzeit deshalb falsch sein.
Eine falsche Uhrzeit kann HTTPS-Verbindungen und die Zertifikatsüberprüfung von APT verhindern.
Als Zeitdienst wird systemd-timesyncd verwendet.
Konfigurationsverzeichnis erstellen:
mkdir -p /etc/systemd/timesyncd.conf.d
Konfiguration bearbeiten:
nano /etc/systemd/timesyncd.conf.d/10-ntp.conf
Folgenden Inhalt eintragen:
[Time]
NTP=162.159.200.1 162.159.200.123 time.cloudflare.com 0.de.pool.ntp.org 1.de.pool.ntp.org
PollIntervalMinSec=32
PollIntervalMaxSec=2048
SaveIntervalSec=60
Die ersten beiden Adressen sind NTP-Server von Cloudflare. Sie sind auch ohne DNS-Auflösung erreichbar.
Für NTP muss ausgehender UDP-Verkehr auf Port 123 erlaubt sein.
Zeitdienst für den Systemstart aktivieren:
systemctl enable systemd-timesyncd.service
systemd-timesyncd wird beim regulären Systemstart aktiviert. Innerhalb von chroot wird kein laufender Zeitdienst benötigt.
Der Dienst speichert regelmäßig einen Zeitstempel, damit die Systemzeit bei späteren Neustarts nicht immer auf einen sehr alten Wert zurückfällt.
9. Netzwerk dauerhaft konfigurieren
Die Netzwerkverbindung im Initramfs ist unabhängig von der normalen Debian- Netzwerkkonfiguration.
Deshalb muss eth0 auch im installierten Debian-System eingerichtet werden.
Netzwerkdatei öffnen:
nano /etc/network/interfaces
Folgende Konfiguration verwenden:
# Loopback
auto lo
iface lo inet loopback
# Ethernet
auto eth0
iface eth0 inet static
address 10.100.0.61/16
gateway 10.100.0.1
# Weitere Interfaces
source /etc/network/interfaces.d/*
Die Management-IP liegt zunächst direkt auf eth0. Eine Linux-Bridge für virtuelle Maschinen wird erst nach erfolgreicher Einrichtung des Basissystems konfiguriert.
Die gleiche Management-IP darf später nicht gleichzeitig auf eth0 und vmbr0 liegen.
Netzwerkdienst aktivieren:
systemctl enable networking.service
DNS konfigurieren
DNS-Konfiguration öffnen:
nano /etc/resolv.conf
Inhalt:
nameserver 1.1.1.1
Diese Konfiguration setzt voraus, dass /etc/resolv.conf als reguläre Datei verwaltet wird und kein anderer Netzwerkdienst ihren Inhalt automatisch ersetzt.
Für die Namensauflösung muss DNS über UDP beziehungsweise TCP Port 53 erreichbar sein.
10. Hostname konfigurieren
Hostname bearbeiten:
nano /etc/hostname
Inhalt:
darkside
Hosts-Datei bearbeiten:
nano /etc/hosts
Folgende Einträge verwenden:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
10.100.0.61 darkside.home.arpa darkside
Der Hostname muss auf die tatsächliche Management-IP des Servers auflösbar sein.
11. SSH-Zugang einrichten
Root-Passwort setzen:
passwd
Für den SSH-Zugang wird ein eigener Ed25519-Administrationsschlüssel verwendet.
Den öffentlichen Schlüssel auf dem administrierenden Linux-Client erzeugen:
ssh-keygen -t ed25519 -a 100 \
-f ~/.ssh/id_pi4_admin \
-C "Pi4 Administration"
Den privaten Schlüssel ausschließlich auf dem Linux-Client speichern.
Auf dem Raspberry-Pi-Dateisystem:
install -d -m 0700 /root/.ssh
nano /root/.ssh/authorized_keys
Den vollständigen öffentlichen Schlüssel aus id_pi4_admin.pub eintragen.
Dateirechte setzen:
chmod 0600 /root/.ssh/authorized_keys
SSH-Konfiguration erstellen:
nano /etc/ssh/sshd_config.d/10-security.conf
Inhalt:
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
X11Forwarding no
MaxAuthTries 3
SSH-Hostkeys erzeugen, falls sie fehlen:
ssh-keygen -A
SSH-Konfiguration prüfen:
sshd -t
SSH-Dienst aktivieren:
systemctl enable ssh.service
12. Initramfs-Netzwerk
Für die LUKS-Entsperrung wird eth0 bereits innerhalb des Initramfs aktiviert.
Datei öffnen:
nano /etc/initramfs-tools/initramfs.conf
Folgende Werte setzen:
MODULES=most
DEVICE=eth0
Die statische IP-Adresse wird über einen Kernelparameter konfiguriert.
Datei öffnen:
nano /etc/default/raspi-extra-cmdline
Folgende Zeile eintragen:
ip=10.100.0.61::10.100.0.1:255.255.0.0:darkside:eth0:none
Die Zeile darf keine zusätzlichen Zeilenumbrüche enthalten.
13. Raspberry-Pi-Firmware
Firmware-Konfiguration öffnen:
nano /etc/default/raspi-firmware
Folgende Werte setzen:
ROOTPART="/dev/mapper/cryptroot"
KERNEL="auto"
INITRAMFS="auto"
Die bestehende Konfiguration des Firmwarepakets ansonsten beibehalten.
Auf einem Raspberry Pi 4 mit USB-SSD können zusätzliche USB-Treiber im Initramfs benötigt werden, insbesondere reset_raspberrypi.
Datei öffnen:
nano /etc/initramfs-tools/modules
Das benötigte Modul ergänzen, sofern es beim installierten Kernel als Modul vorliegt:
reset_raspberrypi
14. Dropbear für LUKS konfigurieren
Ein separater SSH-Schlüssel wird für die Entsperrung der LUKS-Partition verwendet.
Schlüssel auf dem Linux-Client erzeugen:
ssh-keygen -t ed25519 -a 100 \
-f ~/.ssh/id_pi4_unlock \
-C "Pi4 LUKS Unlock"
Dropbear-Verzeichnis erstellen:
install -d -m 0700 /etc/dropbear/initramfs
nano /etc/dropbear/initramfs/authorized_keys
Den öffentlichen Entsperrschlüssel mit folgenden Optionen eintragen:
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/cryptroot-unlock" ssh-ed25519 SSH-PUBLIC-KEY
SSH-PUBLIC-KEY durch den vollständigen öffentlichen Ed25519-Schlüssel ersetzen.
Dateirechte setzen:
chmod 0600 /etc/dropbear/initramfs/authorized_keys
Dropbear konfigurieren:
nano /etc/dropbear/initramfs/dropbear.conf
Inhalt:
DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 120"
Dropbear akzeptiert damit nur Schlüsselauthentifizierung auf Port 2222.
Die Hostkeys von Dropbear müssen vor dem ersten Verbindungsaufbau sicher dokumentiert und auf dem SSH-Client verifiziert werden.
15. Initramfs erstellen
Installierte Kernel-Version ermitteln:
ls /lib/modules
Die gewünschte Kernel-Version auswählen und das passende Initramfs erstellen.
Beispiel:
KVER=$(ls /lib/modules | sort -V | tail -n 1)
if [ -f "/boot/initrd.img-$KVER" ]; then
update-initramfs -u -k "$KVER"
else
update-initramfs -c -k "$KVER"
fi
Boot-Konfiguration prüfen:
cat /boot/firmware/config.txt
cat /boot/firmware/cmdline.txt
cmdline.txt muss auf /dev/mapper/cryptroot verweisen und den statischen ip-Parameter enthalten.
Initramfs-Inhalt überprüfen:
lsinitramfs "/boot/initrd.img-$KVER" | less
Besonders die Cryptsetup-Komponenten, Dropbear, authorized_keys, cryptroot-unlock, USB- und Ethernet-Treiber kontrollieren.
16. Installation abschließen
chroot verlassen:
exit
Dateisysteme kontrollieren:
findmnt -R /mnt/Temp/1
Alle Ziel-Mountpoints aushängen:
umount -R /mnt/Temp/1
LUKS schließen:
cryptsetup close cryptroot
Schreibvorgänge abschließen:
sync
Die USB-SSD ist jetzt für den ersten Boot vorbereitet.
17. LUKS über SSH entsperren
Nach dem Start sollte Dropbear im Initramfs auf Port 2222 erreichbar sein.
SSH-Verbindung herstellen:
ssh -t \
-p 2222 \
-i ~/.ssh/id_pi4_unlock \
root@10.100.0.61
Den SSH-Hostkey mit dem zuvor dokumentierten Fingerprint vergleichen.
Anschließend die LUKS-Passphrase eingeben.
Nach erfolgreicher Entsperrung startet das normale Debian-System.
Reguläre SSH-Verbindung:
ssh -i ~/.ssh/id_pi4_admin root@10.100.0.61
18. Ersten Systemstart überprüfen
Netzwerk kontrollieren:
ip -br address
ip route show default
Erwartete Netzwerkkonfiguration:
eth0 UP 10.100.0.61/16
Namensauflösung prüfen:
getent ahostsv4 deb.debian.org
Zeitsynchronisierung kontrollieren
Systemzeit anzeigen:
date
timedatectl status
Zeitdienst aktivieren:
systemctl enable --now systemd-timesyncd
Synchronisierungsstatus anzeigen:
timedatectl timesync-status
timedatectl show -p NTPSynchronized
Erwarteter Status nach erfolgreicher Synchronisierung:
NTPSynchronized=yes
Erst nach erfolgreicher Zeitsynchronisierung Paketdownloads und größere Systemupdates durchführen.
19. Fehlerbehebung: HTTPS-Zertifikate
Folgende Fehlermeldung kann auftreten, wenn die Systemzeit falsch ist:
SSL connection failed:
certificate verify failed
Aktuelle Zeit überprüfen:
date -u
NTP-Dienst kontrollieren:
systemctl status systemd-timesyncd --no-pager
timedatectl timesync-status
Falls NTP noch nicht zur Verfügung steht und die Uhr stark falsch geht, kann die Uhrzeit vorübergehend manuell auf einen vertrauenswürdigen aktuellen UTC-Wert gesetzt werden.
Beispiel mit dem aktuellen UTC-Zeitwert des Linux-Clients:
date -u -s "JAHR-MONAT-TAG STUNDE:MINUTE:SEKUNDE"
Die Platzhalter müssen durch eine tatsächlich aktuelle UTC-Zeit ersetzt werden.
Nach Korrektur der Uhrzeit kann APT erneut verwendet werden:
apt update
Falls der TLS-Fehler weiterhin besteht, anschließend CA-Zertifikate, Paketquellen und mögliche TLS-Interception prüfen.
Die HTTPS-Zertifikatsprüfung darf nicht deaktiviert werden.
20. Fehlerbehebung: Locale
Bei folgender Meldung fehlt die gewünschte Locale oder die SSH-Umgebung verwendet nicht unterstützte Locale-Werte:
setlocale: LC_CTYPE:
cannot change locale (de_DE.UTF-8)
Verfügbare Locales überprüfen:
locale -a
Locale-Konfiguration öffnen:
nano /etc/locale.gen
Folgende Zeile aktivieren:
de_DE.UTF-8 UTF-8
Locale neu erzeugen:
locale-gen
Standardeinstellung aktualisieren:
update-locale LANG=de_DE.UTF-8
Anschließend eine neue SSH-Sitzung öffnen. Die setlocale-Warnungen sollten verschwinden.
21. Fehlerbehebung: Netzwerk
Falls das Netzwerk im Initramfs funktioniert, aber nach der LUKS-Entsperrung ausfällt, die reguläre Netzwerkkonfiguration prüfen.
cat /etc/network/interfaces
ip -br address
ip route
/etc/network/interfaces muss die statische Konfiguration von eth0 enthalten.
Bei einem beschädigten oder unvollständigen System kann die verschlüsselte SSD auf einem anderen Linux-PC entschlüsselt und die Konfigurationsdatei repariert werden.
22. Proxmox VE vorbereiten
Erst wenn Debian, LUKS, SSH, Netzwerk und Zeitsynchronisierung zuverlässig funktionieren, wird die Virtualisierungsplattform eingerichtet.
Proxmox VE 9 stellt ARM64-Pakete bereit. Der Raspberry Pi 4 ist als Plattform jedoch nicht Teil der unterstützten Proxmox-Hardware.
Vor einer Installation müssen insbesondere die Paketabhängigkeiten und die Auswirkungen auf den Raspberry-Pi-Kernel geprüft werden.
Den funktionierenden Bootkernel, raspi-firmware, cryptsetup-initramfs und dropbear-initramfs nicht unkontrolliert ersetzen oder entfernen.
Vor dem Einrichten einer Proxmox-Bridge muss die bisherige Management-IP von eth0 auf vmbr0 umgestellt werden. Dabei darf die IP nicht doppelt vergeben werden.
Eine Aufnahme in einen bestehenden Proxmox-Cluster erfolgt erst nach vollständiger Funktionsprüfung.
No comments to display
No comments to display