# Linux - Verschlüsselung

# Linux - LUKS LVM - Dropbear-initramfs

# Verschlüsseltes System per Dropbear-Initramfs über SSH entsperren

Diese Anleitung gilt für Debian/Ubuntu-Systeme mit `<span class="editor-theme-code">initramfs-tools</span>` und einer verschlüsselten Root-Partition. Die erste Variante verwendet ein normales, ungetaggtes Netzwerkinterface. Die zweite Variante verwendet ein getaggtes IEEE-802.1Q-VLAN.

**Vor dem Neustart:** Konsolen- oder KVM/IPMI-Zugriff bereithalten. Eine falsche Interface-, IP-, Gateway- oder VLAN-Konfiguration kann den SSH-Zugriff während des Bootens verhindern. Die normale Passworteingabe an der Konsole bleibt der Rückfallweg.

<details id="bkmrk-anleitung-1%3A-dropbea"><summary>Anleitung 1: Dropbear-Initramfs ohne VLAN einrichten</summary>

## Voraussetzungen

- Die Root-Partition ist verschlüsselt und wird bereits beim Booten nach einer Passphrase fragen.
- Der Client kann das Servernetz während der Initramfs-Phase erreichen.
- Eine statische IP-Adresse, Netzmaske und ein Gateway sind bekannt.
- Die Befehle auf dem Server werden als `<span class="editor-theme-code">root</span>` oder über `<span class="editor-theme-code">sudo</span>` ausgeführt.

## 1. Netzwerkinformationen ermitteln

Interface, IP-Adresse und Default-Gateway anzeigen:

```bash
ip -br address
ip route show default
```

Beispiel:

```text
Interface: enp4s0f0
IP-Adresse: 10.100.0.2
Netzmaske: 255.255.0.0
Gateway: 10.100.0.1
```

## 2. Pakete installieren

```bash
apt update
apt install -y dropbear-initramfs cryptsetup-initramfs
```

## 3. Statische Initramfs-Netzwerkkonfiguration eintragen

Datei öffnen:

```bash
nano /etc/initramfs-tools/initramfs.conf
```

Folgende Werte ergänzen beziehungsweise vorhandene Werte ersetzen:

```ini
DEVICE=enp4s0f0
IP=10.100.0.2::10.100.0.1:255.255.0.0::enp4s0f0:none
```

Aufbau der `<span class="editor-theme-code">IP</span>`-Zeile:

```text
IP=<Client-IP>:<Server-IP>:<Gateway>:<Netzmaske>:<Hostname>:<Interface>:<Autoconf>
```

Bei einer statischen Adresse bleiben Server-IP und Hostname im Beispiel leer. `<span class="editor-theme-code">none</span>` deaktiviert die automatische Konfiguration per DHCP.

## 4. Dropbear absichern und Port festlegen

Datei öffnen:

```bash
nano /etc/dropbear/initramfs/dropbear.conf
```

Empfohlene Basiskonfiguration:

```bash
DROPBEAR_OPTIONS="-I 300 -j -k -s -p 2222"
```

<table><colgroup><col></col><col></col></colgroup><tbody><tr><th>Option

</th><th>Bedeutung

</th></tr><tr><td>`<span class="editor-theme-code">-I 300</span>`

</td><td>Inaktive Verbindung nach 300 Sekunden trennen

</td></tr><tr><td>`<span class="editor-theme-code">-j</span>`

</td><td>Lokales Port-Forwarding deaktivieren

</td></tr><tr><td>`<span class="editor-theme-code">-k</span>`

</td><td>Remote-Port-Forwarding deaktivieren

</td></tr><tr><td>`<span class="editor-theme-code">-s</span>`

</td><td>Passwortanmeldung deaktivieren; nur Schlüssel erlauben

</td></tr><tr><td>`<span class="editor-theme-code">-p 2222</span>`

</td><td>Separaten SSH-Port für das Initramfs verwenden

</td></tr></tbody></table>

## 5. SSH-Schlüssel auf dem Client erzeugen

```bash
ssh-keygen -t ed25519 \
  -f ~/.ssh/id_initramfs_unlock_System_1 \
  -C "Initramfs unlock for System_1"
```

Den öffentlichen Schlüssel anzeigen:

```bash
cat ~/.ssh/id_initramfs_unlock_System_1.pub
```

Der private Schlüssel verbleibt ausschließlich auf dem Client. Nur die Datei mit der Endung `<span class="editor-theme-code">.pub</span>` wird auf den Server übertragen.## 6. Öffentlichen Schlüssel auf dem Server hinterlegen

```bash
install -d -m 0700 /etc/dropbear/initramfs
nano /etc/dropbear/initramfs/authorized_keys
chmod 0600 /etc/dropbear/initramfs/authorized_keys
```

In `<span class="editor-theme-code">authorized_keys</span>` steht der vollständige öffentliche Schlüssel in einer Zeile:

```text
no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3... Initramfs unlock for System_1
```

Ein zugelassener Schlüssel ermöglicht eine Root-Shell im Initramfs. Den privaten Schlüssel deshalb wie ein Administrationspasswort schützen und bei Verlust sofort aus `<span class="editor-theme-code">authorized_keys</span>` entfernen.## 7. Initramfs neu erzeugen und Inhalt prüfen

```bash
update-initramfs -u -k all

lsinitramfs /boot/initrd.img-$(uname -r) | \
  grep -E 'dropbear|authorized_keys|cryptroot-unlock'
```

Die Ausgabe sollte unter anderem Dropbear, `<span class="editor-theme-code">authorized_keys</span>` und `<span class="editor-theme-code">cryptroot-unlock</span>` enthalten.

## 8. Komfortablen SSH-Zugriff auf dem Client einrichten

`<span class="editor-theme-code">~/.ssh/config</span>` ergänzen:

```sshconfig
Host System_1-unlock
    HostName 10.100.0.2
    User root
    Port 2222
    IdentityFile ~/.ssh/id_initramfs_unlock_System_1
    IdentitiesOnly yes
    PasswordAuthentication no
    UserKnownHostsFile ~/.ssh/known_hosts.initramfs
```

Die separate `<span class="editor-theme-code">known_hosts</span>`-Datei verhindert Konflikte zwischen dem Host-Key des Initramfs und dem Host-Key des normal gestarteten SSH-Servers.

## 9. Neustarten und entsperren

```bash
reboot
```

Sobald der Server an der Festplattenabfrage wartet, vom Client verbinden:

```bash
ssh System_1-unlock
```

In der Initramfs-Shell:

```bash
cryptroot-unlock
```

Nach erfolgreicher Passworteingabe wird die SSH-Verbindung normalerweise beendet und der reguläre Bootvorgang fortgesetzt.

## Fehlersuche

- **Keine Verbindung:** Interface-Name, IP, Netzmaske, Gateway, Switchport und Firewall prüfen.
- **Netzwerkkarte fehlt:** Den Treiber aus `<span class="editor-theme-code">basename "$(readlink -f /sys/class/net/enp4s0f0/device/driver/module)"</span>` in `<span class="editor-theme-code">/etc/initramfs-tools/modules</span>` eintragen und das Initramfs erneut bauen.
- **Konfiguration wird ignoriert:** Mit `<span class="editor-theme-code">cat /proc/cmdline</span>` nach einem vorhandenen `<span class="editor-theme-code">ip=</span>`-Bootparameter suchen. Dieser kann die Werte aus `<span class="editor-theme-code">initramfs.conf</span>` überschreiben.
- **SSH-Key wird abgelehnt:** Eine vollständige Schlüsselzeile sowie Rechte `<span class="editor-theme-code">0700</span>` für das Verzeichnis und `<span class="editor-theme-code">0600</span>` für `<span class="editor-theme-code">authorized_keys</span>` prüfen.
- **Host-Key-Warnung:** Den separaten Port und `<span class="editor-theme-code">UserKnownHostsFile ~/.ssh/known_hosts.initramfs</span>` verwenden.

</details><details id="bkmrk-anleitung-2%3A-dropbea"><summary>Anleitung 2: Dropbear-Initramfs über Tagged VLAN einrichten</summary>

## Voraussetzungen

- Der Switchport zum Server transportiert das gewünschte VLAN getaggt.
- Das VLAN ist auf allen beteiligten Trunks erlaubt.
- Die Root-Partition ist verschlüsselt und wird im Initramfs entsperrt.
- Das physische Parent-Interface, die VLAN-ID, IP-Adresse, Netzmaske und das Gateway sind bekannt.

Beispielwerte:

```text
Parent-Interface: enp1s0
VLAN-ID: 40
VLAN-Interface: enp1s0.40
IP-Adresse: 10.15.32.253
Netzmaske: 255.255.248.0
Gateway: 10.15.39.254
```

Die Initramfs-Netzwerkkonfiguration gilt nur während der frühen Bootphase. Das gestartete Betriebssystem muss das VLAN zusätzlich über Netplan, systemd-networkd oder `<span class="editor-theme-code">/etc/network/interfaces</span>` konfigurieren.## 1. Pakete installieren

```bash
apt update
apt install -y dropbear-initramfs cryptsetup-initramfs iproute2
```

## 2. VLAN und statische Adresse konfigurieren

`<span class="editor-theme-code">/etc/initramfs-tools/initramfs.conf</span>` öffnen:

```bash
nano /etc/initramfs-tools/initramfs.conf
```

Folgende Werte eintragen:

```ini
VLAN="enp1s0:40"
DEVICE=enp1s0.40
IP=10.15.32.253::10.15.39.254:255.255.248.0::enp1s0.40:none
```

Die Variable `<span class="editor-theme-code">VLAN</span>` verwendet das Format `<span class="editor-theme-code">Parent-Interface:VLAN-ID</span>`. Das folgende Skript ist nicht auf VLAN 40 festgelegt. Für VLAN 120 würde die Konfiguration beispielsweise so aussehen:

```ini
VLAN="enp1s0:120"
DEVICE=enp1s0.120
```

Mehrere VLAN-Interfaces können ebenfalls vorbereitet werden:

```ini
VLAN="enp1s0:40 enp1s0:120"
```

## 3. Benötigte Kernelmodule aufnehmen

Treiber des physischen Interfaces ermitteln:

```bash
basename "$(readlink -f /sys/class/net/enp1s0/device/driver/module)"
```

In `<span class="editor-theme-code">/etc/initramfs-tools/modules</span>` mindestens das VLAN-Modul ergänzen. Falls der Netzwerkkartentreiber nicht automatisch im Initramfs vorhanden ist, zusätzlich den zuvor ausgegebenen Modulnamen eintragen:

```text
8021q
# Beispiel für einen NIC-Treiber:
# ixgbe
```

## 4. Programm `<span class="editor-theme-code">ip</span>` ins Initramfs kopieren

Datei `<span class="editor-theme-code">/etc/initramfs-tools/hooks/vlan-ip</span>` erstellen:

```bash
nano /etc/initramfs-tools/hooks/vlan-ip
```

Inhalt:

```bash
#!/bin/sh

PREREQ=""

prereqs()
{
    echo "$PREREQ"
}

case "$1" in
    prereqs)
        prereqs
        exit 0
        ;;
esac

. /usr/share/initramfs-tools/hook-functions

IP_BIN="$(command -v ip || true)"

if [ ! -x "$IP_BIN" ]; then
    echo "Fehler: ip aus dem Paket iproute2 wurde nicht gefunden" >&2
    exit 1
fi

manual_add_modules 8021q
copy_exec "$IP_BIN"

exit 0
```

```bash
chmod 0755 /etc/initramfs-tools/hooks/vlan-ip
```

## 5. Generisches VLAN-Bootskript erstellen

Das VLAN muss existieren, bevor Dropbear das Netzwerk konfiguriert. Deshalb wird das Skript als `<span class="editor-theme-code">init-premount/00-vlan</span>` installiert und nicht unter `<span class="editor-theme-code">local-top</span>`.

```bash
install -d -m 0755 /etc/initramfs-tools/scripts/init-premount
nano /etc/initramfs-tools/scripts/init-premount/00-vlan
```

Inhalt:

```bash
#!/bin/sh

PREREQ=""

prereqs()
{
    echo "$PREREQ"
}

case "$1" in
    prereqs)
        prereqs
        exit 0
        ;;
esac

. /scripts/functions
. /conf/initramfs.conf

for config_file in /conf/conf.d/*.conf; do
    [ -f "$config_file" ] && . "$config_file"
done

[ -n "${VLAN:-}" ] || exit 0

modprobe 8021q || {
    log_failure_msg "VLAN-Modul 8021q konnte nicht geladen werden"
    exit 1
}

for vlan_config in $VLAN; do
    parent=${vlan_config%%:*}
    vlan_id=${vlan_config#*:}

    if [ "$parent" = "$vlan_config" ]; then
        log_failure_msg "Ungueltige VLAN-Konfiguration: $vlan_config"
        exit 1
    fi

    case "$vlan_id" in
        ''|*[!0-9]*)
            log_failure_msg "Ungueltige VLAN-ID: $vlan_id"
            exit 1
            ;;
    esac

    if [ "$vlan_id" -lt 1 ] || [ "$vlan_id" -gt 4094 ]; then
        log_failure_msg "VLAN-ID ausserhalb 1 bis 4094: $vlan_id"
        exit 1
    fi

    vlan_device="${parent}.${vlan_id}"

    # Kurz auf das physische Interface warten.
    attempts=0
    while ! ip link show "$parent" >/dev/null 2>&1; do
        attempts=$((attempts + 1))
        if [ "$attempts" -ge 10 ]; then
            log_failure_msg "Interface $parent wurde nicht gefunden"
            exit 1
        fi
        sleep 1
    done

    ip link set "$parent" up || exit 1

    if ! ip link show "$vlan_device" >/dev/null 2>&1; then
        ip link add link "$parent" \
            name "$vlan_device" \
            type vlan id "$vlan_id" || exit 1
    fi

    ip link set "$vlan_device" up || exit 1
    log_success_msg "VLAN-Interface $vlan_device wurde aktiviert"
done

exit 0
```

```bash
chmod 0755 /etc/initramfs-tools/scripts/init-premount/00-vlan
```

## 6. Dropbear konfigurieren

`<span class="editor-theme-code">/etc/dropbear/initramfs/dropbear.conf</span>`:

```bash
DROPBEAR_OPTIONS="-I 300 -j -k -s -p 2222"
```

## 7. SSH-Schlüssel erzeugen und eintragen

Auf dem Client:

```bash
ssh-keygen -t ed25519 \
  -f ~/.ssh/id_initramfs_unlock_System_1 \
  -C "Initramfs unlock for System_1"

cat ~/.ssh/id_initramfs_unlock_System_1.pub
```

Auf dem Server:

```bash
install -d -m 0700 /etc/dropbear/initramfs
nano /etc/dropbear/initramfs/authorized_keys
chmod 0600 /etc/dropbear/initramfs/authorized_keys
```

Beispielzeile:

```text
no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3... Initramfs unlock for System_1
```

## 8. Initramfs bauen und prüfen

```bash
update-initramfs -u -k all

lsinitramfs /boot/initrd.img-$(uname -r) | \
  grep -E '8021q|scripts/init-premount/00-vlan|/ip$|dropbear|authorized_keys|cryptroot-unlock'
```

Optional kann die tatsächlich ins Initramfs übernommene Konfiguration kontrolliert werden:

```bash
lsinitramfs /boot/initrd.img-$(uname -r) conf/initramfs.conf
```

## 9. Switch konfigurieren und prüfen

- VLAN 40 muss auf dem Serverport **tagged** beziehungsweise als erlaubtes Trunk-VLAN konfiguriert sein.
- VLAN 40 muss auf allen Uplinks zwischen Server und Client beziehungsweise Gateway erlaubt sein.
- Das Gateway `<span class="editor-theme-code">10.15.39.254</span>` muss im VLAN 40 liegen und erreichbar sein.
- Die IP `<span class="editor-theme-code">10.15.32.253</span>` darf nicht gleichzeitig von einem anderen Gerät verwendet werden.

## 10. SSH-Zugriff auf dem Client einrichten

`<span class="editor-theme-code">~/.ssh/config</span>`:

```sshconfig
Host System_1-unlock
    HostName 10.15.32.253
    User root
    Port 2222
    IdentityFile ~/.ssh/id_initramfs_unlock_System_1
    IdentitiesOnly yes
    PasswordAuthentication no
    UserKnownHostsFile ~/.ssh/known_hosts.initramfs
```

## 11. Neustarten und entsperren

```bash
reboot
```

Vom Client verbinden:

```bash
ssh System_1-unlock
```

Danach in der Initramfs-Shell:

```bash
cryptroot-unlock
```

## Fehlersuche für Tagged VLAN

- **Keine Pakete:** Switchport auf Tagged/Trunk, erlaubte VLANs und VLAN-ID prüfen.
- **Parent-Interface fehlt:** Den Netzwerkkartentreiber in `<span class="editor-theme-code">/etc/initramfs-tools/modules</span>` aufnehmen.
- **`<strong class="editor-theme-bold editor-theme-code">ip</strong>` fehlt:** Den Hook prüfen und kontrollieren, ob `<span class="editor-theme-code">iproute2</span>` installiert ist.
- **VLAN-Interface fehlt:** Mit `<span class="editor-theme-code">lsinitramfs</span>` prüfen, ob `<span class="editor-theme-code">00-vlan</span>`, `<span class="editor-theme-code">ip</span>` und `<span class="editor-theme-code">8021q</span>` enthalten sind.
- **Falsches Interface wird verwendet:** In `<span class="editor-theme-code">/proc/cmdline</span>` nach einem alten `<span class="editor-theme-code">ip=...:enp1s0:none</span>` suchen. Ein Kernel-Bootparameter kann `<span class="editor-theme-code">initramfs.conf</span>` überschreiben.
- **Nach dem Entsperren kein Netzwerk:** Das VLAN zusätzlich im regulären Betriebssystem konfigurieren; die Initramfs-Konfiguration wird nach dem Mounten des Root-Dateisystems nicht zur dauerhaften Netzwerkkonfiguration.

</details>## Quellen und weiterführende Dokumentation

- [Debian: Dropbear im Initramfs](https://sources.debian.org/src/dropbear/2022.83-1%2Bdeb12u3/debian/README.initramfs/)
- [Debian: initramfs.conf(5)](https://manpages.debian.org/stable/initramfs-tools-core/initramfs.conf.5.en.html)
- [Debian: dropbear(8)](https://manpages.debian.org/stable/dropbear-bin/dropbear.8.en.html)
- [Debian: Cryptsetup-Initramfs-Integration](https://sources.debian.org/src/cryptsetup/2%3A2.6.1-4~deb12u2/debian/README.initramfs/)