Kurzanleitungen/Howtos

Raspberry-Pi-SD-Karten-Images vor dem Schreiben anpassen

03.07.2020

Dodger-Tools

Abbilddateien, die zum Schreiben von Raspberry-Pi-SD-Karten verwendet werden, sind letztendlich 1:1-Kopien aller Sektoren einer vorhandenen SD-Karte. Darin sind zwei Partitionen vorhanden, wobei die erste Bootinformationen und die zweite das eigentliche Betriebssystem enthält. Beim ersten Booten wird die Betriebssystempartition auf die tatsächliche Größe der SD-Karte erweitert. Die SD-Karte muß also mindestens so groß wie das Abbild sein. Ein neues von einer größeren Karte erstelltes Image läßt sich nicht mehr einfach auf die urprüngliche Größe des alten Abbildes reduzieren, da alle (auch leere) Sektoren kopiert werden.
Möchte man nur kleinere Modifikationen, wie das Aktivieren des SSH-Servers oder das Setzen von Paßwörtern und einer statischen IP-Adresse, durchführen, so können diese direkt in der Abbilddatei vorgenommen werden. Das kommentierte Skript in dieser Kurzanleitung zeigt, wie das Abändern eines Images vonstatten gehen kann.

Modifikationsskript

Speichern Sie das folgende Skript in einer Datei und führen Sie es anschließend als "root" aus. Als einzigen Parameter übergeben Sie den Namen des (unkompromierten) Images, welches Raspbian/RaspberryPi OS als Distribution verwendet. Als Ergebnis erhalten Sie ein modifiziertes mit gzip kompromiertes neues Abbild.

#!/bin/bash

img="$1"

mntP="/tmp/RasPi-Image-setStaticIPenable-SSH$$"

# Überprüfen, ob die Abbilddatei zwei Partitionen enthält
if [ $(file "$img" | sed 's/;/\n/g' | grep partition -c) -ne 2 ]
then
  echo "Not an image from a Raspberry Pi Raspbian with 2 partitions"
  exit 1
fi

# Gerätedateien für die beiden Partitionen erstellen
loops=$(kpartx -a -v "$img" | cut -d' ' -f3)

# Warten, bis die Gerätedateien verfügbar sind
while [ ! -e "/dev/mapper/$(echo $loops | sed 's/ /\n/g' | head -1)" ]
do
  sleep 1
  echo "Wait for loop device to become ready..."
done

# Temporären Mountpunkt anlegen
mkdir "$mntP"

# Die Gerätedateien auflisten
echo $loops

# Die Partitionen nacheinander durchlaufen
for loop in $loops
do
  dev="/dev/mapper/$loop"

  # Die aktuelle Partitionen einhängen
  mount "$dev" "$mntP"

  # Modifikationen für die Bootpartition finden hier statt
  # (Erkennung durch Vorhandensein der Datei cmdline.txt)
  if [ -f "$mntP/cmdline.txt" ]
  then
    # SSH-Server aktivieren
    echo "Touching $mntP/ssh"
    touch "$mntP/ssh"
  fi

  # Modifikationen für die Systempartition finden hier statt
  # (Erkennung durch Vorhandensein des Verzeichnisses /etc/network)
  if [ -d "$mntP/etc/network" ]
  then
    # Statische Netzwerkeinstellungen vornehmen
    echo "Setting static IP"
    echo 'source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet static
  address 192.168.5.12
  netmask 255.255.255.0
  network 192.168.5.0
  broadcast 192.168.5.255
  gateway 192.168.5.1
  dns-nameservers 192.168.5.1' > "$mntP/etc/network/interfaces"

    # Server für die Namensauflösung festlegen
    echo "Setting nameserver"
    echo 'nameserver 192.168.5.1' > "$mntP/etc/resolv.conf"

    # Paßwort für die Benutzer "pi" und "root" auf "test" setzen
    echo 'Setting password "test" for "pi" and "root"'
    sed -i 's/\(^pi\):[^:]*\(.*\)/\1:$6$wfBigHblaCoTwSMC$LDw1BlBeqs7TDnbm4PHSIqb.RLQGvGfR06g5OfBEaET.6RW\/↵
    x7wwqj3iNurRSw4QSGFu6nzDEqZ1pWjsWlk\/R\/\2/' "$mntP/etc/shadow"
    sed -i 's/\(^root\):[^:]*\(.*\)/\1:$6$wfBigHblaCoTwSMC$LDw1BlBeqs7TDnbm4PHSIqb.RLQGvGfR06g5OfBEaET.6RW↵
    \/x7wwqj3iNurRSw4QSGFu6nzDEqZ1pWjsWlk\/R\/\2/' "$mntP/etc/shadow"

    # SSH-root-Anmeldung mittels Paßwort freischalten
    echo 'Enabling SSH login as root'
    grep -v PermitRootLogin "$mntP/etc/ssh/sshd_config" > /tmp/sshd_config
    echo 'PermitRootLogin yes' >> /tmp/sshd_config
    cat /tmp/sshd_config > "$mntP/etc/ssh/sshd_config"
  fi

  # Die aktuelle Partitionen aushängen
  umount "$mntP"
done

# Gerätedateien löschen
kpartx -d "$img"

# Modifizierte Abbilddatei komprimieren
pigz -9 "$img"

chmod 777 "$img"*

Achtung! Achtung! Die folgenden Anweisungen richten sich ausschließlich an fachkundige Personen. Bei jedem Schritt kann es zum kompletten Datenverlust kommen. Alle Angaben ohne Gewähr! Die Anweisungen, Skripte, etc. sind ausschließlich für Lernzwecke auf Lernsystemen und nicht für Produktivumgebungen bestimmt!