Das Ziel der Entwicklung dieses Systems ist ein Diskless-Client1), der über das Netzwerk startet und alle
Programme lokal ausführt, sodass vorhandene Rechenleistung weiter verwendet wird und keine neue Hardware angeschafft werden muss.
Weiterhin soll dieses System bequem verwalt- und konfigurierbar sein und sich leicht in eine Paed-/OpenML-Lösung integrieren lassen. Hierbei
ist auch eine gewisse Distributions-Unabhängigkeit wünschenswert.
Besonders wichtig soll die Sicherheit des Systems sein, dass die Endbenutzer keine Veränderungen an kritischen Eigenschaften des Systems
vornehmen können (Vandalismus2)-Vorbeugung).
Wünschenswert ist eine gewisse Geschwindigkeit3).
Die Grundlage des Systems ist ein debootstrap
4)
-tes Debian-System.
Dieses wird auf dem Server erzeugt und konfiguriert.
Danach wird das System nur lese-berechtigt in das Netzwerk mit
NFS5)
freigegeben6)
und mit PXE
7) gebootet.
Es sind also Eingriffe am DHCP-Server nötig.
Ebenso muss ein TFTP-Dämon auf einem Host installiert werden und
eine NFS-Freigabe des Systems erstellt werden.
Irgendwann im August anno 2011 begann thoto ein debootstraptes Debian zu erstellen 8) mit:
debootstrap stable ./ http://ftp.de.debian.org/debian
Nach der Installation konnte die grundlegende Konfiguration
9)
des Systems vorgenommen werden.
Das Netzwerk sollte so eingerichtet werden,
dass das normale Interface, über das gebootet wird und
das die Verbindung zum NFS-Server aufrecht erhält,
keine Konfiguration bekommt, sondern nur das
Loopback-Interface konfiguriert
10)
wird. Dies wird für einige Anwendungen benötigt.
Das System bootete schliesslich in einer virtuellen Maschine11).
Zur Arbeit mit dem System wird jedoch KEINE virtuelle Maschine verwendet, sondern eine chroot-ed-Umgebung:
chroot ./ /bin/sh
Hierbei ist zu beachten, dass man sich dabei an der Dateisystem-Wurzel12) des debootstrap-Systems befinden muss.
Hier kann das System den eigenen Wünschen angepasst werden unter anderem muss das Paket aufs-tools installiert werden.
apt-get install aufs-tools
Um das System NFS-Rootfähig zu machen verwendet man das in eigener Produktion entstandene Skript nfsroot.sh in
Anhang A.
Dieses installiert man über:
cp nfsroot.sh /etc/init.d/nfsroot.sh insserv /etc/init.d/nfsroot.sh /etc/init.d/nfsroot.sh install
Danach modifiziert man die Datei /etc/fstab, sodass dort auch folgende Zeilen stehen:
none /aufs-tmp/home tmpfs auto,defaults 0 0 none /home aufs auto,defaults,br:/aufs-tmp/home=rw:/home=ro,rw 00
Diese Zeilen erzeugen eine schreibbare Home-Parition, die in einem RAM-Dateisystem13) liegen.
Das Dateisystem AUFS
14)
ermöglicht
hier „ein Schreiben“ auf ein Dateisystem ohne Schreibmöglichkeit,
indem es ein Dateisystem zum Lesen der Daten verwendet und ein weiteres zum Schreiben der Daten.
AUFS ermöglicht auch mehrere andere interessante Aktionen, z.B. ein gleichmäßiges Verteilen von Daten über mehrere
Dateisysteme und einiges mehr
15).
Nachdem wir nun das System zu einem festplattenlosen Bootvorgang vorbereitet haben, können wir uns dem Kernel zuwenden. Hierbei
muss die Initrd
16), modifiziert werden,
damit z.B. der NFS-Kernel-Client integriert wird. Bei einem Debian-System ändert/editiert man einfach die Datei
/etc/initramfs-tools/initramfs.conf folgendermaßen
17):
MODULES=netboot BOOT=nfs NFSROOT=auto
Damit wäre18) der Client Netzwerk-bootfähig.
Die Einrichtung des Servers verläuft ähnlich unkompliziert:
Bei dem Testsystem handelt es sich entweder um ein Arch-Linux-System (Testsystem) oder
OpenML-Debian.
Dadurch variieren die Paketnamen etwas:
| Komponente | Arch-Linux | Debian | OpenML | Anmerkung |
|---|---|---|---|---|
| NFS-Server | nfs-utils | nfs-kernel-server | Empfehlenswert ist der Kernel-Server | |
| NFS-Client | nfs-utils | nfs-common | — | |
| DHCP-Server | dhcpd | isc-dhcpd | — | Empfehlenswert ist der ISC-DHCPd |
| TFTP-Server | tftp-hpa | tftpd-hpa | — | HPA |
| Test-VM | kvm / qemu | kvm / qemu | Nur zum Test! Bitte keine Verwendung in Produktivsystem! | |
Paket-Installation mittels pacman -S oder apt-get.
Konfiguration:
Der NFS-Server muss so konfiguriert werden, dass er das Verzeichnis (im Beispiel /srv/nfsroot) an
den Client (im Beispiel mit der IP 10.16.1.106) exportiert.
Der Client darf jedoch nicht auf den Server Schreiben (Flag ro) und
alle Berechtigungen sollen einfach übertragen werden, ohne bestimmte User-Berechtigungen des Users root (auf dem Client)
auf den User nobody zu übertragen (Flags no_root_squash und no_all_squash).
Das Flag no_subtree_check wird eigentlich nur bei Debian benötigt.
Es ist empfehlenswert die Freigaben fest vorzunehmen, sodass diese bei jedem Booten auch wieder erscheinen. Dazu
dient folgender Eintrag in /etc/exports, :
/srv/nfsroot 10.16.1.106(ro,no_root_squash,no_all_squash,no_subtree_check)
Nach wie vor kann auch ohne Veränderung der /etc/exports das NFS-Wurzel-Dateisystem exportiert werden durch:
exportfs -o ro,no_root_squash,no_all_squash 10.16.1.106:/srv/nfsroot
Anmerkung: Bitte ERST lesen, DANN ausprobieren.
Der ISC-DHCPd sollte folgende Zeilen in ähnlicher Form in der Konfigurationsdatei19) enthalten:
subnet 10.16.1.0 netmask 255.255.255.000 {
range 10.16.1.10 10.16.1.20;
option broadcast-address 10.16.1.255;
option routers 10.16.1.1;
}
group netterms{
filename "pxelinux.0";
next-server 10.16.1.1;
host netterm1{
hardware ethernet 00:50:56:12:00:60;
fixed-address 10.16.1.101;
}
}
Die Umgebung subnet sorgt hier für eine allgemeine Adressverteilung und
das Setzen einiger Parameter, sowie dafür, dass DHCPd überhaupt
auf dem Interface
20)
lauscht, das eine IP im angegebenen Subnetz hat.
„group netterms“ gruppiert alle Netzwerk-Bootrechner in einer Gruppe. Diese werden in einer Host-Umgebung angegeben und sollten eindeutig
über ihre MAC-Adresse identifiziert und ihnen eine eindeutige IP-Adresse zugewiesen werden.
Ebenso werden gruppenweit die Parameter filename und next-server übergeben,
die die Lage des TFTP-Servers und den Dateinamen des Boot-Loaders auf diesem definieren.
In OpenML ist hier die Konfiguration einfacher:
Einfach über die Schulkonsole (https:/ /<openml-server>:242/) eine neue LINBO-Gruppe
anlegen und unter Hosts
dem entsprechenden Rechner diese Gruppe zuweisen. Die pxelinux-Konfigurationsdatei lautet dann dementsprechend nicht mehr default,
sondern liegt unter anderem Dateinamen (Arno meint nach Blick in /etc/dhcp3/dhcpd.conf-linuxmuster: clientnet)in diesem Verzeichnis. Also /var/linbo/pxelinux.cfg/clientnet
Die Einrichtung des TFTPd ist trivial: TFTPd-HPA hat ein beim Starten des Dämon als Argument übergebenes Verzeichnis, aus dem er seine Dateien freigibt.
Die automatischen Startskripts unter Arch-Linux ermöglichen
einen einfachen Start. Die Konfiguration des Dämon liegt hierbei in
/etc/conf.d/tftpd. In dieser Datei wird die Variable TFTPD_ARGS
gesetzt, der alle Parameter enthält, die der TFTPd auf der Kommandozeile übergeben bekommt. Beispiel:
TFTPD_ARGS="-l -s /usr/local/tftpboot"
Debian's TFTP-Konfiguration liegt in /etc/default/tftpd-hpa
Bei OpenML sollte man nichts umkonfigurieren, da LINBO sonst nicht startet. Hier verwendet man den vorgegebenen Pfad /var/tftproot. 
PXELINUX ist ein auf SYSLINUX
21)
aufbauender Bootloader für PXE. Er wird vom Boot-ROM
der Netzwerkkarte aus dem Netzwerk via TFTP in den RAM geladen und ausgeführt.
PXELINUX holt sich dann via TFTP seine eigene Konfiguration
aus dem Netz, die im Verzeichnis pxelinux.cfg im selben TFTP-Verzeichnis liegt, soweit nicht anders via DHCP angegeben.
PXELINUX sucht hier zunächst nach Dateien, die seine MAC- oder IP22)-Adresse im Dateinamen haben, oder, wenn diese Option23) vom DHCP-Server übergeben wurde nach
einer bestimmten Datei. Als letzte Möglichkeit nimmt er die Datei default in diesem Verzeichnis. Danach lädt er den ersten Fund herunter
und parst diese Konfiguration.
Aufgrund seiner Herkunft sieht die PXELINUX-Konfiguration eine SYSLINUX-Konfiguration sehr ähnlich:
Datei: pxelinux.cfg/default
default foo
label foo
kernel term/vmlinuz
append vga=normal initrd=term/initrd.img root=/dev/nfs nfsroot=10.16.1.1:/srv/nfsroot/ ip=dhcp noprompt ro -- quit
Diese Konfiguration ist natürlich noch anzupassen:
Zunächst einmal sollte man einen eigenen Ordner im TFTP-Root erschaffen, soweit nicht bereits24) geschehen.
Dort kopiert man den Kernel und das Initrd aus dem debootstrap-ten System hinein. Danach passt man die Pfade in oberer Konfiguration an
(term/vmlinuz ist der Kernel, term/initrd.img ist die Init-RAM-Disk) und verändert auch die Parameter für den NFS-Server.
Natürlich muss auch pxelinux.0 im TFTP-Verzeichnis vorhanden sein. Einstellbar ist der Ort der Datei über die DHCP-Konfiguration(s.o.) mit
dem Parameter filename. Der DHCP-Konfigurationsparameter next-server sollte die IP des TFTP-Servers enthalten.
Nun sollten alle Dämonen gestartet werden (DHCP, TFTP und NFS) und ein erster Test gestartet werden. Dazu ist es sehr empfehlenswert KVM zu verwenden. Hierbei sollte aber noch der TUN-/TAP-Support für Netzwerkinterfaces nachinstalliert werden:
pacman -S uml_utilities
bzw.
apt-get install uml-utilities
Danach kann man25) ein TAP-Interface mit Berechtigungen für unseren testenden Benutzer26) erstellen und eine IP an dieses vergeben,
das später eine direkte Verbindung zur VM herstellt:
tunctl -u user -g kvm -t tap0 ifconfig tap0 10.16.1.1 up
Erst danach sollte man den DHCPd27) starten, damit er auch garantiert auf dieses
Interface lauscht. Dazu ist natürlich auch nötig, dass der DHCPd auf dem Host installiert ist, auf dem die Tests stattfinden.
Der TFTP-Server und NFS-Server können auch auf einem anderen Host liegen, jedoch muss dann IP-Forwarding im Linux-Kernel
aktiviert28) werden.
Danach kann die KVM gestartet durch folgendes gestartet werden:
kvm -net nic,vlan=0,macaddr=00:50:56:12:00:60 -net tap,vlan=0,ifname=tap0 -monitor stdio -boot n
Wichtig: Bitte nicht in einem Produktivsystem Tests durchführen!
Noch ein kleines Skript, das alle wichtigen Komponenten auf dem Testsystem startet:
tunctl -u <username!> -g kvm -t tap0 ifconfig tap0 10.16.1.1 up /etc/rc.d/dhcp4 start /etc/rc.d/tftpd start /etc/rc.d/nfs-server start exportfs -o no_root_squash,no_all_squash,ro 10.16.1.\*:/srv/nfsroot/
Die erste Einbettung des oben beschriebenen Systems in OpenLML lief relativ flüssig. Zwar musste der NFS-Server noch installiert werden
und die Schulkonsole ein wenig ausgetrickst werden jedoch lief es unerwartet schnell, sehr gut. Das Austricksen bezieht sich auf
folgendes:
Es kann leider nur LINBO als Netzwerkboot-Image verwendet werden. So musste eine neue LINBO-Umgebung erstellt werden29) und die PXE-Konfiguration umgebogen werden30).
Um ein hübsches Vorzeige-System zu erstellen sollten X11 und ein billiger, für nicht-Linuxer leicht zu bedienender Window-Manager
installiert werden, also wurde IceWM ausgewählt. Somit installierten wir also bequem über die change-root-Umgebung icewm, mussten aber
noch /proc in die Umgebung31) einbinden. Wir installierten um das Image klein zu halten nur den radeon-
Treiber32).
Die X-Konfiguratin war etwas umständlicher, da wir erst das Verzeichnis /root33) schreibbar machen mussten,
was wir durch das temporäre Mounten eines auf dem Server via NFS schreibbar freigegebenen Ordners erreichten, der via AUFS über das
Verzeichnis /root übermountet wurde. So konnten wir eine Konfiguration erzeugen34), testen35) und einsetzen36).
Danach stellten wir fest, dass wir mit unserem Test-Benutzer anmelden konnten und X via xinit starten konnten, jedoch uns slim, den wir
zur Steigerung der Benutzerfreundlichkeit als Display-Manager einsetzten37), nach einem Login direkt wieder
hinauswarf. Nach Betrachtung der Log-Dateien wurde schnell klar, dass das Problem bei xauth lag, das gerne ~/.Xauthority angelegt hätte.
Theoretisch hätte man xauth mit -file oder der Umgebungsvariable $XAUTHORITY eine andere Position der Datei mitgeben können, jedoch
verhindete dies slim, der auf irgendeine Weise hart-kodiert den Pfad zu dieser Datei festgeschrieben hatte und der auch nicht xauth mit
User-Berechtigung38) lief.
Somit mounteten wir erneut ein AUFS über /home und schrieben in ein TMPFS hinein. Damit dies persistent bleibt, modifizierten wir die Datei
/etc/fstab (s.o.) und änderten das Installationsskript (s.u.).
Danach installierten wir noch chromium (Die Basis von Chrome) als schnellen Browser.
Das OpenLML-System hat leider einen Schutz durch einen IP-Filter 39) realisiert. Dadurch wird es von Außen erschwert auf unbekannte Dienste des Schulservers zuzugreifen.
Da NFS nachgerüstet wurde, ist dies auch hier der Fall: Man muss die Firewall wegnehmen40) um den Client mit NFS-Root starten zu können.
Da dies natürlich unpraktisch und unsicher ist, müssen neue Firewallregeln geschrieben werden. Hierzu könnte man ein Skript erstellen, was dies selber vornimmt oder die bestehenden Skripte modifizieren. Die Linux-Musterlösung verfügt hierbei über eine Methode, bei der man einfach UDP- und TCP-Ports in eine Art Liste schreiben braucht, und das Init-Skript linuxmuster-base erzeugt daraus automatisch Firewall-Regeln.
Leider erzeugt jedoch NFS bei jedem Start mithilfe von Portmap neue Ports für seine Dienste. Aus diesem Grund müssen diese festgeschrieben werden. Einige kann man in den entsprechenden Dateien /etc/default/nfs-* anpassen. Hierbei müssen den Dämonen mountd und statd der Parameter –port übergeben werden, was sich über diese Dateien definieren lässt.
Hierzu verwendet man den in der Default-Konfiguration bereits existierenden aber leeren Parameter STATDOPTS, für statd, der auch zusätzlich den Parameter –outgoing-port benötigt um außerhalb des Rechners kommunizieren zu können. Hierbei muss es sich scheinbar (
) um einen anderen Port als über –port handeln.
Der NFS-Server wird in der Datei /etc/default/nfs-kernel-server über die Variable RPCMOUNTDOPTS mit dem Parameter –port angepasst.
nfs callback und lockd, die für die Sperrung von Dateien sowie für eine Rückverbindung verantwortlich sind, sind jedoch (scheinbar
) kernelseitig und müssen daher direkt in der Initram-Disk des Schulservers angepasst werden. Dazu erstellt man eine beliebige Datei in /etc/modprobe.d/, die man mit den entsprechenden Konfigurationsdaten füllt:
options lockd nlm_udpport=32768 nlm_tcpport=32768 options nfs callback_tcpport=32764
Andere Dämonen werden nicht benötigt.
Die Ports müssen nachher in der Firewall hinzugefügt werden, indem man die Open-LML-Firewall-Konfiguration in /etc/linuxmuster-base/allowed_ports bearbeitet.
Quelle: Debian Wiki
Die aktuellen Firewallregeln kann man sich über iptables -L -v anzeigen lassen.
— WORK IN PROGRESS — WIRD FORD-GESETZT — TO BE CONTINUED —
Ort: /etc/init.d/
Installation:
insserv /etc/init.d/nfsroot.sh # insserv aktiviert installierte Init-Skripte, in dem es die passenden Links # in den Runlevel-Verzeichnissen (/etc/init.d/rcn.d) setzt. )) /etc/init.d/nfsroot.sh install
Skript:
#! /bin/sh ### BEGIN INIT INFO # Provides: nfsroot # Required-Start: checkroot # Required-Stop: # Default-Start: S # Default-Stop: # X-Start-Before: mtab ifupdown # Short-Description: Provides mechanisms for running from ro-rootfs # Description: Provides mechanisms for running from ro-rootfs ### END INIT INFO # nfsboot.sh, init-script supplied by MODUL NFSBOOT, PROJEKT SCHULSYSTEM # (Autor: thoto) # Installation: insserver nfsroot.sh # !!! Unvollständige Version. !!! PATH=/sbin:/bin #. /lib/init/vars.sh . /lib/init/mount-functions.sh . /lib/lsb/init-functions makelink(){ # $1:file $2:linked file $3:DIR? if [ ! -e $1 -o ! -L $1 -o "$(readlink $1)" != "$2" ] ; then echo "Creating link $1 to $2" # remove file if it exists [ -e $1 ] && rm $1 # create linked file/directory if it is not there yet if $3 ; then [ -d $2 ] || mkdir $2 else [ -f $2 ] || touch $2 fi # finally create the link [ ! -L $1 -o "$(readlink $1)" != "$2" ] && ln -s $2 $1 fi } case "$1" in install) [ -d /var-rw ] || mkdir /var-rw [ -d /aufs-tmp ] || mkdir /aufs-tmp [ -d /aufs-tmp/home ] || mkdir /aufs-tmp/home #makelink "/etc/mtab" "/var/run/mtab" false makelink "/etc/mtab" "/proc/mounts" false makelink "/etc/network/run" "/var/run/ifstate" true ;; start|"") log_daemon_msg "Making readonly NFS-root usable" "nfsboot" modprobe aufs domount tmpfs "" /var-rw none "-n -odefaults" domount aufs "" /var none \ "-orw,br:/var-rw=rw:/var=ro,nodev" log_end_msg 0 ;; restart|reload|force-reload) # nop ;; stop) # nop ;; *) echo "Usage: nfsroot.sh [start|stop]" >&2 exit 3 ;; esac
auto lo iface lo inet loopback
tap0/etc/rc.d/dhcp4echo -n "1">/proc/sys/net/ipv4/ip_forward
X -configure
X -config /root/xorg.conf.new
cp /root/xorg.conf.new /etc/X11/xorg.conf
iptables