Debian headless installation
Posted on Mo 28 Januar 2019 in Computer & Electronics
TLDR: Eine schön verpackte Version gibt es im github repo: github.com/philpagel/debian-headless
Nachdem mein alter Android Media-Server gestorben war habe ich mich nach einem Ersatz umgesehen. Mit der Android Lösung war ich nicht besonders glücklich, denn eigentlich wollte ich eh nur Kodi verwenden und es im Wesentlichen vom Handy steuern – einen Bildschirm hatte ich nie dauerhaft angeschlossen. Zudem bekommen Android-Geräte ja bekanntermaßen nur sehr begrenzte Zeit Updates, so dass man irgendwann mit einer potentiell unsicheren Uralt-Version dasteht.
Also lieber ein LINUX drauf machen. Debian natürlich. Zunächst mal habe ich mir geeignete Hardware gesucht und bin bei einem Lenovo ThinkCentre m600 tiny gelandet. Ist ein Auslaufmodell und war online günstig zu haben. Sieht sogar ganz hübsch aus und hat alles was der Mensch so braucht: 128GB SSD, 4GB RAM, eine Tastatur mit französischem Layout, die ich schon entsorgt habe und keinen Monitor. Und natürlich auch kein CD-Laufwerk – sowas braucht doch heute kein Mensch mehr.
Also ein Debian-netinst image runterladen, auf einen USB Stick spielen und los geht's. Theoretisch. Denn ich habe ja weder Tastatur, noch Monitor angeschlossen und stur wie ich nunmal bin will ich die Installation diesmal komplett headless über ssh durchziehen. Der Debian installer hat dafür ein nettes Feature namens 'network-console'. Das hat aber einen Pferdefuß: Nach dem Start vom Installationsmedium muss man zunächst interaktiv locale und keymap auswählen, das Netzwerk interface konfigurieren und den hostname festlegen, bevor man die network console aktivieren kann. Das führt die remote installation irgendwie ad absurdum.
Nun hat der Debian installer aber einen sehr praktischen Mechanismus namens preseeding. d.h. man kann ihm die Antworten auf alle oder einige der Konfigurationsfragen in einem File übergeben und diese werden dann nicht mehr gestellt. Im Extremfall kann man so die komplette Installation/Konfiguration automatisieren. Mir geht es aber nur darum, alles bis zum Start der network console zu automatisieren, damit ich dann interaktiv per ssh weitermachen kann.
Soweit so gut. Aber wie präsentiere ich dem installer nun dieses File? Eigentlich ganz einfach: es muss halt aufs Installationsmedium. Das ist aber leider ein ISO File und muss erstmal entpackt werden. Dann kann man das preseed File einfügen, alles wieder zusammenpacken – dabei darauf achten, dass das so erzeugte ISO Image auch bootfähig ist und los geht's.
Im Netz fand ich viele kluge Anleitungen, wie man sowas macht (die beste hier), aber in jeder davon fehlte irgendeinein Aspekt, den ich für mein Vorhaben brauchte – entweder wollte das Ganze dann nicht von USB-Stick booten, oder es blieb in Boot-Menü hängen oder das Preseeding war unvollständig etc. etc. Grumpf! Habe dann lange rumprobiert und Versatzstücke aus den unterschiedlichen Tutorials ausprobiert bis ich schließlich alles am laufen hatte.
Werkzeugkasten
Bevor es los geht stellen wir sicher, dass alle notwendigen tools auch installiert sind:
sudo apt-get install bsdtar syslinux syslinux-utils cpio genisoimage coreutils
Auspacken
Das Entpacken des ISO images geht relativ leicht:
# make a tmp folder
mkdir isofiles
# unpack the iso
bsdtar -C isofiles -xf debian-9.5.0-amd64-netinst.iso
# Set write permissions
chmod -R +w isofiles
Nun liegt alles schön im isofiles/
folder und dort können wir unser
Installationsmedium nun nach Herzenslust modifizieren.
Boot loader config
Als erstes müssen wir das config File für den bootloader erstellen. Im
Originalzustand wartet dieser nämlich bis zum Sanktnimmerleinstag auf die
manuelle Auswahl der gewünschten Boot-Option: Also Install
, Graphical
install
, Advanced options
etc. Zu diesem Zeitpunkt ist aber noch keine
remote-Kontrolle möglich. D.h. wir müssen sicherstellen, dass wir automatisch im
Installer landen und brauchen die übrigen Optionen nicht.
Also erstmal cd isofiles
und dort das File isolinux/isolinux.cfg
löschen
und ein Neues mit diesem Inhalt erzeugen:
DEFAULT install
SAY Now booting the debian installer
LABEL install
kernel /install.amd/vmlinuz
append vga=788 initrd=/install.amd/initrd.gz --- quiet
Preseeding
Als nächstes brauchen wir ein preseeding File (preseed.cfg
). Ein typisches
für eine deutschsprachige Installation sieht so aus:
#### Contents of the preconfiguration file (for stretch)
d-i debian-installer/locale select de_DE
d-i console-keymaps-at/keymap select de
d-i keyboard-configuration/xkb-keymap select de
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string wintermute
d-i netcfg/get_domain string local
d-i netcfg/hostname string wintermute
d-i hw-detect/load_firmware boolean true
d-i network-console/password password install
d-i network-console/password-again password install
d-i network-console/start select continue
Man beachte, dass dieses File nur das Allernötigste enthält, um bis zum Start der remote console zu kommen. Man kann grundsätzlich viel mehr konfigurieren – in der oben verlinkten Debian Seite ist das wunderbar erklärt.
Nun müssen wir das preseeding File noch installieren – und das ist ein bisschen tricky, denn der Installer muss ja sehr früh Zugriff darauf haben. Mit anderen Worten, wir müssen es irgendwie in die init RAM-Disk bekommen. Und das geht so:
# initrd auspacken
gunzip install.amd/initrd.gz
# preseed file rein
echo ../preseed.cfg | cpio -H newc -o -A -F install.amd/initrd
# und wieder einpacken
gzip install.amd/initrd
MD5 sums aktualisieren
Und damit der Installer nicht meckert müssen wir nun die MD5 sums auf den neusten Stand bringen:
find ./ -type f -exec md5sum {} \; > md5sum.txt
Fertig – unser Installationsmedium ist inhaltlich präpariert.
Darf ich Ihnen das einpacken?
Ja gerne, sonst kann ich ja nicht booten. Also nun ein bootfähiges ISO
erstellen. Aber erstmal wieder raus aus dem Folder cd ..
. Im Netz fand ich
viele Vorschläge, wie man das ISO baut, dieser hier funktioniert bei mir
tatsächlich:
# create iso
genisoimage -V Debian-headless \
-r -J -b isolinux/isolinux.bin -c isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-o debian-9.6.0-amd64-netinst-headless.iso isofiles
# fix MBR
isohybrid debian-9.6.0-amd64-netinst-headless.iso
Der letzte Schritt ist wichtig, damit das ISO auch bootfähig ist.
Auf den Stick damit
Nun sollten wir ein bootfähiges ISO Image haben, das nun nur noch auf einen
USB-Stick geschrieben werden muss. Dazu erstmal herausfinden, welches Device
dem USB-Stick entspricht. Meist hilft lsblk
um das herauszufinden, oder ein
Blick in den Output von dmesg
direkt nach dem einstecken des Sticks.
Achtung! Bei mir ist /dev/sdc
das device des USB-Sticks – bei Euch kann es
ganz was anderes sein. Das falsch zu machen ist eine super Gelegenheit sich die
Festplatte komplett zu zerschießen – also Augen auf bei der Device Wahl! Und
so schreiben wir das dann:
sudo dd if=debian-9.6.0-amd64-netinst-headless.iso of=/dev/sdc bs=4k
Und sicherheitshalber noch ein sync
hinterher.
Wenn ihr zu feige seid, das mit dd
zu machen könnt Ihr auch ein Tool wie
etcher nehmen, um Katastrophen zu
verhindern...
Auf geht's
Nun kommt der große Moment: USB Stick in den Server stecken, power on und eine
Weile warten. Nun müsst Ihr noch rausfinden, welche IP-Adresse der neue
Rechner bekommen hat. Das weiß der DHCP-Server, z.B. in eurem Router. Solltet
Ihr kein DHCP verwenden, müsst Ihr das preseed.cfg
file entsprechend anpassen
und eine statische Adresse konfigurieren.
Nehmen wir mal an, der Rechner hat die Adresse 192.168.5.56 bekommen, dann nehmt Ihr so Kontakt auf:
ssh installer@192.168.5.56
In preseed.cfg
hatten wir das Passwort install
konfiguriert – aber Ihr
könnt und solltet dort natürlich auch ein anderes einstellen. Nun kann man die
komplette Installation in Ruhe über ssh durchführen. Zum Server muss man erst
wieder anlässlich des Reboots, denn sonst kann es gut sein, dass er einfach
wieder in den Installer bootet, anstatt das frisch installierte Linux zu
starten.
Fazit
Das waren jetzt viele Schritte und ich kann mir sowas nie merken. Deswegen habe ich mir die Mühe gemacht, den kompletten Vorgang in einem Makefile zusammenzufassen. Wer sich dafür interessiert findet es hier:
github.com/philpagel/debian-headless
Der Vollständigkeit halber sei noch angemerkt, dass das alles nur für den "klassischen" Bootvorgang funktioniert. D.h. im BIOS muss der 'legacy boot' eingestellt sein – mit UEFI boot klappt das so nicht.
Viel Spaß beim Installieren.
Update 2022-03-26
Der Post ist nach wie vor korrekt, aber in der Zwischenzeit habe ich einige Dinge am Prozess verbessert und v.a. Support für UEFI hinzugefügt. All das ist in die schön verpackte Version im Github repository eingeflossen. Also bitte verwendet diese, wenn Ihr das in der echten Welt nutzen möchtet.