Die Ausgangslage
Die Ausgangslage ist mein Notebook mit installiertem System, sowie den aktuellen Sourcen fuer Welt und Kernel. Man bekommt es hoechstwahrscheinlich auch mit Binaerpaketen hin, aber da ich den Quellcode kompiliert vorliegen hatte, bot es sich geradezu an, ihn zu benutzen...
Also, ab in die Details, das ist mein System:
[ad001@glas ~]$ uname -a FreeBSD glas 8.0-BETA2 FreeBSD 8.0-BETA2 #2: Sun Jul 26 17:49:43 CEST 2009 root@salz:/usr/obj/usr/src/sys/GENERIC i386 [ad001@glas ~]$ ifconfig em0 em0: flags=8843Die Boot-Informationen fuer die netzwerkgebooteten Maschinen sollen auf dem Serversystem untermetric 0 mtu 1500 options=19b ether 00:16:41:e3:20:4b inet 192.158.0.191 netmask 0xffffff00 broadcast 192.158.0.255 media: Ethernet autoselect (100baseTX ) status: active
/tftpboot liegen.Daneben wird natuerlich noch eine andere Maschine benoetigt, die per PXE booten kann -- das duerfte heute so gut wie jede sein.
Im folgenden werde ich in der Reihenfolge vorgehen, wie das ueber Netzwerk gebootete System mit den einzelnen Komponenten interagiert. Und um Mut zu machen: Es sind nur drei essenzielle Schritte notwendig. Bei mir waren Sie begleitet von viel htttp://frag-onkel-google.de und RTFM und dem garstigstem von allem, dem Lesen irgendwelcher Mailinglisten. Ich verstehe einfach nicht, wieso es Menschen gibt, die Mailinglistdumps im Netz fuer eine tolle Informationsquelle halten... aber nun zur Sache.
Schritt 1: DHCP und Booten
Wenn der Rechner Strom bekommt, dann beginnt das BIOS, das Chaos im Speicher zu ordnen. Nachdem die ungefaehre Konfiguration (Bildschirm - vorhanden. Tastatur - USB, Legacy mode, Festplatten - keine) bekannt ist, werden die BIOS' der einzelnen Komponenten gefragt, ob sie noch etwas Beitragen wollen. Das kann dann die Enumeration der SCSI-Platten oder der SATA-Platten sein oder eben eine Netzwerkkarte, die ankuendigt, dass sie Booten kann. Wenn man sie fragt.
Schliesslich wird gebootet. Dabei wird in der im BIOS vorgegebenen Reihenfolge vorgegangen: Meist angefangen bei Festplatten, dann CD-Rom und schliesslich Netzwerk. Wenn der Rechner alt ist, noch Diskette. Wenn hier nun die Wahl auf Netzwerk faellt, wird das PXE-BIOS wieder aktiviert. Und hier gehts nun los:
Das PXE versucht, sich eine IP-Adresse per DHCP zu holen. Hierzu werden die ueblichen Broadcasts ausgesandt und die Antworten ausgewertet. Hier wird nun auf spezielle Antwortpakete gewartet: Solche, die Boot-Informationen enthalten. Anderweitige DHCP-Antworten werden ignoriert.
Daraus erwaechst die erste Aufgabe fuer das Serversystem: Geeignete DHCP-Antworten geben koennen. Ich habe hierzu den ISC-DHCPD in der Version 3.0 genutzt. Um diesen auf ein System zu bekommen tut es ein cd /usr/ports/net/isc-dhcp30-server/ && make install clean als Nutzer mit ausreichenden Rechten. Danach muss eine entsprechende Konfiguration geschaffen werden, die die erforderlichen Zusatzinformationen enthaelt. Das ganze laesst sich mit folgender dhcpd.conf, die normalerweise in /usr/local/etc/ residiert, erreichen.
Hinweis: Diese Konfiguration liefert ein Boot-Image an jeden Rechner aus. Entsprechend befindet sich hier ein gewisses Sicherheitsrisiko!
[ad001@glas /usr/home/ad001]$ cat /usr/local/etc/dhcpd.conf
ddns-update-style none;
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.30 192.168.0.39;
option subnet-mask 255.255.0.0;
option broadcast-address 192.168.0.255;
# option routers 192.168.0.1;
# option domain-name-servers 192.168.0.2;
option domain-name "pxec";
default-lease-time 3600;
max-lease-time 3600;
server-name "192.168.0.191";
server-identifier 192.168.0.191;
next-server 192.168.0.191;
option root-path "192.168.0.191:/tftpboot/clientroot";
filename "/pxeboot";
}
Eine kurze Erklaerung, was da nun was tut:- subnet-Definition Definiert, fuer welchen IP-Bereich wir uns hier befassen wollen.
- range Legt den Vergebenen IP-Adressbereich fest: Hier von 192.168.0.30-192.168.0.39.
- broadcast-address, routers, domain-name-servers, domain-name Diverse Informationen zur Netzwerkeinrichtung der angeschlossenen Rechner.
- default-lease-time, max-lease-time Gibt an, wie lange das erhaltene DHCP-Lease gueltig ist und wie lange dies maximal sein darf.
- server-name Hier beginnt nun der fuer PXE-Booten relevante Teil: Diese Direktive gibt einen Namen an, von wo das Image kommt. Dieser kann von der PXE-Hardware dem Nutzer gezeigt werden.
- server-identifyer Enthaelt die Adresse des Servers, von dem das Boot-Image per TFTP geholt werden kann.
- next-server Bietet die Moeglichkeit, fuer weitere Dateien an einen weiteren Server zu verweisen.
- option root-path Hier steht der NFS-Pfad, der vom Kernel einmal als Root-Pfad gemoutet werden soll.
- filename Zum Schluss das wichtigste: Unter welchem Dateinamen kann das PXE-Boot-Image vom TFTP-Server angefordert werden? Gut zu wissen ist, dass diese Angabe reltiv zur Wurzel des vom TFTPd angebotenen Verzeichnis ist...
[ad001@glas /usr/home/ad001]$ sudo /usr/local/etc/rc.d/isc-dhcpd onestart Starting dhcpd. Internet Systems Consortium DHCP Server V3.0.7 Copyright 2004-2008 Internet Systems Consortium. All rights reserved. For info, please visit http://www.isc.org/sw/dhcp/ Wrote 1 leases to leases file. Listening on BPF/em0/00:16:41:e3:20:4b/192.168.0/24 Sending on BPF/em0/00:16:41:e3:20:4b/192.168.0/24 Sending on Socket/fallback/fallback-netWird nun versucht, per PXE zu booten, sollte der Client ein DHCP-Paket mit Zusatzinfos bekommen und versuchen, die Datei
pxeboot zu laden -- was im Moment noch scheitern sollte, da weder ein TFTPd laeuft noch er die richtige Datei ausliefern kann.
Schritt 2: TFTP und Bootloader
TFTP ist ein selten zum Dateitransfer eingesetztes Protokoll. Dies hat einige einfache Ursachen: Es besitzt keine Sicherheitsmechanismen, baut auf UDP auf (was weitere Schwaechen wie z.B. eine Anfaelligkeit gegen Injections impliziert) und ist, wie der Name "Trivial File Transfer Protocol" schon ankuendigt, eine abgespeckte Variante von FTP.
Um die Sache einfach zu halten, werde ich den von FreeBSD im Grundsystem mitgebrachten tftpd nutzen. Hierzu muss er nur in der /etc/inetd.conf aktiviert und der inetd gestartet werden.
# # ntalk is required for the 'talk' utility to work correctly #ntalk dgram udp wait tty:tty /usr/libexec/ntalkd ntalkd tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /tftpboot #tftp dgram udp6 wait root /usr/libexec/tftpd tftpd -l -s /tftpboot #bootps dgram udp wait root /usr/libexec/bootpd bootpd #So sieht das bei mir aus. Ich habe die Beispielzeile auskommentiert und dafuer gesorgt, dass das hintenstehende Verzeichnis (hier eben
/tftpboot) auch existiert. Sodann kann der inetd mit einem kurzen
[ad001@glas /usr/home/ad001]$ sudo /etc/rc.d/inetd onestart Starting inetd.aktiviert werden. Nun muss als naechstes dafuer gesorgt werden, dass auch ein Bootimage, welches PXE beherrscht vorliegt -- so wie es ja in der DHCP-Antwort dem client versprochen wurde. Wenn man (wie ich) regelmaessig seinen Kernel selbst kompiliert und installiert, dann findet sich ein geeignetes Image in
/boot. Dieses muss dann nur noch nach /tftpboot kopiert werden.Bootet man nun den Client, so sollte sich der FreeBSD-Bootloader sehen lassen. Und feststellen, dass er nicht an den Kernel herankommen kann. Es wird Zeit fuer NFS, denn mit dem Eintrag
option root-path "192.168.0.191:/tftpboot/clientroot" wird dem Bootloader angekuendigt, dass es auf diesem Wege weitere Daten gibt.
Schritt 3: NFS, Kernel und Userland
Als erstes einmal muss das Verzeichnis /tftpboot/clientroot erzeugt und freigegeben werden. Hierzu ist ein Eintrag in der Datei /etc/exports mit beispielsweise dem folgenden Inhalt notwendig:
/tftpboot/clientroot -alldirs -maproot=0 -network 192.168.0.0 -mask 255.255.0.0hiermit wird der entsprechende Pfad mit allen Unterverzeichnissen fuer das angegebene Netzwerk freigegeben und root-Zugriffe auf die UID 0 gemappt (was wiederum Root ist). Anschliessend muss der NFS-Daemon noch zum Laufen gebracht werden:
[ad001@glas ~]$ sudo /etc/rc.d/nfsd onestart Starting mountd. Starting nfsd. [ad001@glas ~]$ sudo /etc/rc.d/rpcbind onestart Starting rpcbind.Nun sollte NFS funktionieren. Testen kann man das, wenn eine zweite unixoide Maschine vorhanden ist einfach, indem man versucht, das freigegebene Verzeichnis zu mounten. Hierzu reicht ein
mount 192.168.0.191:/tftpboot/clientroot /mnt aus.Nun muss noch Inhalt fuer die Remote-Maschine hinterlegt werden. Im einfachsten Fall kopiert man
/boot einfach in das Verzeichnis, also nach /tftpboot/clientroot/boot. Damit liegt schonmal ein Kernel vor. Jetzt sollte eine per PXE bootende Maschine bereits den Kernel (mit FreeBSD-Bootscreen) laden koennen. Der Spass wird damit enden, dass der Kernel eine Panic mit der Meldung
panic: going nowhere without my init.von sich gibt. Was der Kernel uns damit sagen moechte? Schlicht und ergreifend, dass der Sprung ins Userland furios gescheitert ist. Dies ist allerdings im Moment auch nicht verwunderlich, denn so etwas wie ein Userland findet sich noch nicht im NFS-Share. Das kann man aber auf drei Wegen aendern: Durch haendisches kopieren des Userlandes von
/ in das Zielverzeichnis (nicht sehr komfortabel), durch eine Installation aus Binaerpaketen (z.B. von einer FreeBSD-CD), dort waere dann das Paket base relevant, oder aber direkt aus dem kompilierten Quellcode. Das geht dann ebenfalls recht einfach, es reicht ein
[ad001@glas /usr/src]$ sudo make DESTDIR=/tftpboot/clientroot/ installworld mkdir -p /tmp/install.AhUs44jS progs=$(for prog in [ awk cap_mkdb cat chf......der Prozess dauert ein wenig laenger. Bei einer Installation von Binaerpaketen muss die Umgebungsvariable
DESTDIR ebenfalls gesetzt sein -- ansnsten ersetzt man Teile des gerade laufenden Systems (was nur dann ein Problem ist, wenn es eine andere Version ist -- dann aber ein grosses) durch moeglicherweise inkompatible Versionen (schlimmer noch: Dateien mit sinnvollem Inhalt durch leere). Nun liegt auch eine Welt vor. Wenn nun PXE-gebootet wird, dann wird es dennoch eine Fehlermeldung nach der anderen geben: Der Kernel mountet / schreibgeschuetzt, entsprechend wird alles zu Fehlern fuehren. Dies beginnt beim schreiben des DHCP-Leases, setzt sich mit dem DNS-Eintrag fort und... naja, es ist recht unkomfortabel, nicht mal eine temporaere Datei schreiben zu koennen. Also muss eine /etc/fstab eingerichtet werden, die entsprechend auch schreibbare Systeme enthaelt. Zum Beispiel kann / problemlos auch schreibbar sein -- dafuer haben wir es ja nach /tftpboot/clientroot gemountet und nicht nach / auf dem Serversystem. Was man allerdings problemlos tun kann, ist Teile des Originalsystems ueber das Grundsystem zu mounten. So sieht meine /etc/fstab dann schliesslich aus:
[ad001@glas /tftpboot/clientroot]$ cat etc/fstab # Device Mountpoint FStype Options Dump Pass# 192.168.0.191:/tftpboot/clientroot / nfs rw 0 0 192.168.0.191:/libexec /libexec nfs ro 0 0 192.168.0.191:/lib /lib nfs ro 0 0 192.168.0.191:/usr /usr nfs ro 0 0 192.168.0.191:/home /home nfs rw 0 0Natuerlich muss die
/etc/exports die analogen Eintraege besitzen (oder einfach eine Freigabe von / -- aber das ist auch nicht unbedingt sicher). Nichtsdestoweniger, nun sollte alles im wesentlichen Funktionieren. Und dank des mountens von /usr/ stehen auch mit /usr/local/bin saemtliche installierte Programme zur Verfuegung.Was noch fehlt, sind natuerlich die Nutzerlogins. Wenn man das ganze jetzt vorbildlich loesen wollen wuerde (der geneigte Leser erahnt, in welche Richtung es geht...), koennte man Login per LDAP, NIS oder NIS+ aufsetzen. Man kann aber auch einfach die entsprechenden Dateien aus
/etc *raeusper* rueberkopieren.... um ganz ehrlich zu sein, ich habe einfach /etc nach /tftpboot/clientroot/etc kopiert und dann dort die abweichenden Anpassungen vorgenommen.Zu diesem Zeitpunkt soll schliesslich ein funktionierendes, durch das Netzwerk gebootetes FreeBSD zur Verfuegung stehen.
Weiteres
Ein paar Fragen bleiben natuerlich offen...
- Kann Windows das auch? :)
Die Antwort ist eines Juristen wuerdig: "Kommt drauf an.". Installationen von Windows Vista per PXE sind moeglich, wobei der Server die Remote-Installation-Services besitzen muss -- das klappt ab spaetestens Windows 2008 Server. Der Betrieb plattenloser Workstations wird aber wohl noch ein wenig auf sich warten lassen.
- Und wenn ich doch eine Installation per PXE machen will?
...dann wird alles eigentlich nur noch einfacher. Per NFS-Share muss der Inhalt der Installations-CD erreichbar sein und im boot-Verzeichnis (das immer noch per NFS-erreichbar sein muss), muss sich die Datei
mfsroot.gzaus dem Wurzelverzeichnis der CD befinden. Ferner sollte dieloader.confdie folgenden Zeilen umfassen:mfsroot_load="YES" mfsroot_type="mfs_root" mfsroot_name="/boot/mfsroot"
Die angegebene Datei (hier/boot/mfsroot) wird dann vom Bootloader auf den zu bootenden Rechner nachgeholt und vom Kernel als virtuelles Dateisystem gemountet. Diemfsroot.gzvon der Installations-CD enthaelt ein Userland, welches direkt in den FreeBSD-Installer springt. In diesem muss spaeter bei der Frage nach der Installationsquelle dann natuerlich per NFS das Share mit den Daten der CD angegeben werden.
Resourcen
Hier nun eine laengere Liste von Quellen, die ich abgegrast habe,
- Die FreeBSD-Manpage zu
diskless. - http://mirrors.yocum.org/cvsup/src/sys/nfsclient/nfs_diskless.c,v hier habe ich endlich gelesen, dass der Kernelfehler
nfs_ diskless: no NFS handleeine einfache Loesung hat: Der Bootloader hat kein NFS-Handle uebergeben. Keine Magie, nur der entsprechende Eintrag in derdhcpd.conf - http://www.locolomo.org/pub/pxeboot/index.html "Der FreeBSD PXEBoot Guide". Sehr interessant, geht aber eher in Richtung Installation per Netz.
- http://www.the-labs.com/FreeBSD/Diskless/
- http://www.freebsd.org/doc/en/books/handbook/network-diskless.html "The FreeBSD-Handbook: Advanced Networking"
- http://jdc.parodius.com/freebsd/pxeboot_serial_install.html "Installing FreeBSD 7.1 via serial Console and PXE"
- http://www.freebsd.org/doc/en_US.ISO8859-1/articles/pxe/article.html "FreeBSD Jumpstart Guide" -- auch wieder mehr Installation als Diskless Workstation
- http://people.freebsd.org/~dwhite/pxeboot.html "Quick and Dirty PXE Boot Setup for FreeBSD 4.x and later"
- http://netboot.sourceforge.net/english/introduction.html Netboot bietet Disketten an, die PXE auf Hardware ohne PXE ermoeglichen, indem ein Minimal-Linux auf der Diskette genutzt wird.
- http://blogs.interdose.com/sebastian/2008/03/19/software-deployment-per-pxenetboot/ Generelle PXE-Anleitung, auf Debian gestuetzt.
* Keine unerwuenschte Werbung, kein Spam, kein... naja, die Nachricht duerfte klar sein.