Archinstall

Mo, 17. April 2023, Eichehome

Ich möchte heute ein kleines Projekt von mir vorstellen, welches möglicherweise einige Personen interessieren könnte. Was es macht? Es installiert Arch Linux! Doch darüber muss Mensch doch nicht schreiben. Ich habe dabei aber einiges über BASH-Scripting gelernt, und möchte dies mit der Community teilen.

Geschichte

Nun etwas zur Entstehungsgeschichte: Eines Abends informierte ich mich auf Youtube über systemd-boot und merkte dabei, dass ich Arch Linux nutzen sollte, wenn ich damit spielen möchte. Doch auf richtiger Hardware ging nicht, da nicht vorhanden. Auf Youtube stolperte ich über den Kanal eflinux, welcher Beispiele für Arch-Setups in VMs gibt und dabei viel erklärt und mir so eine sehr gute Anleitung gab. Da er dort ein Script aus Git benutzte, versuchte ich dieses und merkte, dass dieses Script nicht ganz das macht, was ich wollte. Also begann ich mit meinem eigenen Script. Als ich verstanden hatte, was mit diesem Ansatz möglich war, habe ich mir überlegt, wie mein Traum-System aussehen sollte. Durch den Blog Pid 1 von Lennart Poettering habe ich das Konzept von Systemd relativ gut verstanden und wollte die einzelnen Teile wie Systemd-Networkd, Systemd-resolved etc. ausprobieren. Durch den Do-It-Yourself-Ansatz von arch kann man sich bei der Erstellung und Konfiguration “seines” Systems aus den Repositories wie aus einem Baukasten Teile nehmen und diese zusammenbauen.

Bevor ich mit der Geschichte und den Herausforderungen weitermache, sollte ich vielleicht kurz das Ziel ansprechen. Mein Ziel für das Projekt ist, ein sicheres System mit vielen modernen Programmen zu erstellen. Stichwörter hierfür sind Secure Boot, TPM, systemd-boot, Btrfs, LUKS (cryptenroll), systemd-resolved und iwd als Alternative zu wpa_supplicant.

Weiter in der Geschichte. Durch Fedora (mein Hauptsystem) wurde ich auf BTRFS aufmerksam und wollte damit spielen. Fedora zeigte mir auch Pipewire als Audio-Backend. Da Fedora den Switch zu BTRFS nur bei einer Neuinstallation macht, wollte ich dann halt unter Arch damit Erfahrungen sammeln. Da ich mich auch für IT-Sicherheit interessiere, wollte ich auch mit Verschlüsselung unter Linux vertraut werden. Bei dem Projekt merkte ich, dass man möglicherweise nicht immer verschlüsseln möchte. Auch gibt es bei der Hardware auch Unterschiede (Stichwort: Microcode). Dadurch bekam das Script erste User-Abfragen und ich dachte: Mensch könnte ja einen kleinen Installer bauen, welcher diese Optionen. Doch da das Script auf dem Arch-Iso laufen sollte und dort leider kein Tool wie dialog (ein Programm um grafische Abfragen im Terminal zu machen) installiert ist, wurde ich “gezwungen” mich mit der Bash und ihrer Syntax auseinanderzusetzen. Dabei entdeckte ich einige Dinge, die mir neue Ideen wie ein Default-Wert für Abfragen, sodass danach nur noch bestätigt werden muss.

Beispiele:

read -r -p "Name for the cryptrootdevice (defaults to cryptroot): " cryptrootname
: "${cryptrootname:=cryptroot}"
echo "The cryptrootdevice will be named: ${cryptrootname}"

Dieser Code fragt nach einer Eingabe und wenn diese nicht gegeben und einfach Return gedrückt wird, wird durch die 2. Zeile standardmässig “cryptroot” in die Variable geschrieben. Der Doppelpunkt und das Leerzeichen am Anfang der Zeile sagen der Bash, dass sie das folgende nicht als Kommando interpretieren soll.

echo "Select Kernel (Defaults to Linux):"
echo "1) Linux 2) Linux LTS 3) Linux Zen"
read -r kernel
: "${kernel:=1}"

tempString="";
for range in ${kernel//,/ }; do
    tempString="$tempString{${range//-/..}}";
done;
tempString=${tempString//\}{/\} {};
tempString=$(echo $tempString | tr [:blank:] '\n' | sed 's/{\([0-9]\{1,2\}\)}/\1/' | tr '\n' ',');
tempString=${tempString/%,/};
result="";
for range2 in ${tempString//,/ }; do
    result+=$(eval echo $range2);
    result+=";";
done;
result=${result/%;};
result=${result//;/ };
echo $result

for index in ${result}; do
  echo -n "Ausgewählt: "
    case $index in
        *1*)
      echo "Linux"
      selectedKernel+="linux "
      header+="linux-headers "
      ;;
        *2*)
      echo "Linux LTS"
      selectedKernel+="linux-lts "
      header+="linux-lts-headers "
      ;;
        *3*)
      echo "Linux Zen"
      selectedKernel+="linux-zen "
      header+="linux-zen-headers "
      ;;
        *) echo "Error, aborting" ;;
    esac
done

Dieser Code ermöglicht es, verschiedene Kernel auszuwählen. Dabei sind alle Kernel-Kombinationen möglich. Bei 3 zur Auswahl stehenden Einträgen ist dies noch nicht wirklich nötig, aber dieses Pattern kann man bei einer beliebigen Anzahl von Einträgen nutzen. Wenn z.B. 10 Einträge hätte, Mensch alle bis auf den 5. Eintrag auswählen möchte, kann man das wie folgt angeben: 1-4,6-10 Dies wird dann zu den einzelnen Werten umgewandelt. In diesem Fall 1 2 3 4 6 7 8 9 10 daran sieht man, wie mächtig diese Syntax sein kann. Die Idee für die Syntax kam mir, nachdem ich bei der Installation des base-Meta-Packages auswählen durfte, welche Bestandteile installiert werden sollen.

Zwischen der Zeile tempString=""; und echo $result passiert die ganze Magie. Als Erstes wird in der Eingabe 1-3,5,6-8 das Komma durch ein Leerzeichen ersetzt und mit den Elementen 1-3 5 und 6-8 eine For-Schleife durchlaufen. Dort wird ein gegebenenfalls vorhandenes Minus - durch 2 Punkte .. ersetzt. Nach der Schleife steht in der Variable $tempString {1..3}{5}{6..8} In den folgenden Zeilen wird zwischen }{ ein Leerzeichen eingefügt } {, die geschweiften Klammern wieder entfernt und ein durch das Zusammensetzen entstandenes Komma am Ende wieder entfernt. In einer weiteren Schleife wird aus dem String 1..3 5 6..8 durch Bash-Magie (Expansion) und ein Semikolon der String 1 2 3;5;6 7 8;. Zuletzt werden noch das Semikolon am Ende entfernt und die restlichen Semikolons durch Leerzeichen ersetzt. Jetzt haben wir einen String, der alle gewünschten Einträge enthält.

Quellen

Bash-Manual
Mein Projekt
Arch Wiki

und einige Posts auf Stackoverflow und Unix.Stackexchange

Bildquelle: https://archlinux.org/

Tags

Arch-Linux, Bash-Skripte, bash