This page (revision-8) was last changed on 21-Jan-2008 18:14 by PeterHormanns 

This page was created on 11-Jul-2007 23:12 by ThomasBayen

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
8 21-Jan-2008 18:14 13 KB PeterHormanns to previous Tagging
7 21-Jul-2007 16:40 13 KB ThomasBayen to previous | to last Fehler behoben, Jens hat gut aufgepasst
6 20-Jul-2007 18:10 13 KB JensKapitza to previous | to last löschen von doc und man ?
5 14-Jul-2007 20:43 13 KB ThomasBayen to previous | to last Jetzt ist X auch verschlüsselt
4 14-Jul-2007 17:50 12 KB ThomasBayen to previous | to last Mein ThinClient läuft wireless! Und so hab ichs gemacht
3 13-Jul-2007 18:03 9 KB ThomasBayen to previous | to last kleinere Verbesserungen
2 13-Jul-2007 11:27 9 KB ThomasBayen to previous | to last Korrekturgelesen und ein weiterer Schritt zum WLAN-ThinClient
1 11-Jul-2007 23:12 6 KB ThomasBayen to last ThinClient von lokaler Platte booten

Page References

Incoming links Outgoing links

Version management

Difference between version and

= ThinClient lokal booten =

Normalerweise ist es am besten, einen ThinClient - wie auf der Seite LinuxTerminalServer beschrieben - über das Netzwerk von einem zentralen LTSP-Server aus zu booten. Auf diese Art und Weise kann man alle Clients im Netzwerk am besten zentral einrichten und verwalten.

Dennoch kann es sinnvoll sein, einen ThinClient von einem lokalen Medium zu booten. Dies kann z.B. sein, wenn das Netzwerk entweder sehr langsam ist oder erst noch richtig eingerichtet werden muss. Auch bei grundsätzlichen Problemen mit dem Netboot kann eine lokale Installation helfen.



== komplette lokale Installation ==

Generell muss man sich überlegen, wie viel man lokal installieren will. Im Grunde kann man einen vollwertigen Linux-Rechner installieren und dann dort einen X-Server mit der "-query ..."-Option starten. Oft reicht es aber auch, viel weniger zu installieren.



== lokale Installation von Kernel und Initramdisk ==

Eine andere Sache ist es, nur den Kernel und die initrd lokal zu installieren. In dieser kann man dann ggf. lokale Einstellungen vornehmen und dann mit Hilfe des bereits funktionierenden Linux-Systems das Netzwerk initialisieren und den Rest des Systems immer noch per NFS vom Server beziehen (um so ein zentrales, identisches System zu erhalten).

Ich habe hier einen ThinClient, der einen internen Flash-Speicher von 32MB hat. Diesen würde ich gerne per WLAN anbinden. In diesen Speicher passt kein komplettes Linux-System - allerdings reicht es, um mit Hilfe einer initrd das WLAN einzurichten und dann dort weiterzumachen.

Tips zum Thema habe ich mir aus dem [LTSP-Wiki|http://wiki.ltsp.org/twiki/bin/view/Ltsp/BootingFromLocalDevice] geholt (ist leider viel zu kompliziert, weil der Autor mehrere Dinge gleichzeitig gemacht hat).

Als erstes habe ich den Client an einem normalen Netzwerk normal gebootet, um mich auf ihm einloggen zu können. Der Flash-Speicher ist wie eine gewöhnliche Festplatte angebunden, also habe ich ihn mit '''cfdisk''' eingerichtet und mit '''mke2fs''' formatiert. Ich habe die Partition danach gemountet und dann den '''grub-Bootloader''' installiert. Zum Abschluss habe ich alle boot-Dateien des Clients kopiert:

 mke2fs /dev/hda1
 mount /dev/hda1 /mnt
 grub-install --root-directory=/mnt /dev/hda
 cp -a /boot/* /mnt/boot/

Dabei ist zu beachten, daß ich in meinem LTSP-Client die ganz normalen Debian-Kernel-Pakete installiert habe. Beim Booten per LTSP werden nämlich der Kernel sowie die initrd per tftp vom LTSP-Server geholt. Ich habe in meinem System aber dennoch (quasi unbenutzte) Dateien mit gleichem Inhalt in ''/boot/''. (Bei Kernel-Updates kopiere ich diese dann jeweils in das tftp-Verzeichnis.)

Nun legen wir eine grub-typische Datei ''/mnt/boot/grub/menu.lst'' an. Diese sieht z.B. so aus:

 default=0
 timeout=0
 title ThinClient
       root (hd0,0)
       kernel /boot/vmlinuz ro root=/dev/hda1
       initrd /boot/initrd.img

Als nächstes habe ich den Client rebootet, im BIOS-Menü die Bootreihenfolge umgeschaltet und siehe da: Der Client hat ruck-zuck gebootet. Er hat ohne Probleme den Anschluss ans NFS gefunden, als wäre nichts gewesen.

Eventuell sollte man anhand seiner bisherigen Enistellung noch die Kernel-Aufrufzeile anpassen. Oben steht z.B. hda1, obwohl das offensichtlich nicht als root-Device genommen wird. Dennoch lief es erstmal so. :-)



== Manipulation der initramdisk ==

Bisher ist ja eigentlich noch nichts spannendes passiert. Nun will ich jedoch, daß die Initramdisk meinen WLAN-Adapter initialisiert, sich in ein WLAN einhängt, eine OpenVPN-Verbindung aufbaut (weil wir ja wohl einem WLAN nicht über den Weg trauen) und dann darüber das NFS-Laufwerk einbindet.

Grundsätzlich empfehle ich das Studium folgender manpage:

 man initramfs-tools

Wichtig zu wissen ist, daß man mit dem Parameter '''break''' in der Kernel-Startzeile den Startvorgang an verschiedenen Stellen unterbrechen kann. Das hilft beim Debuggen ungemein!



=== Installation zusätzlicher Treiber in der Initramdisk ===

Ich habe einen WLAN-Adapter von "hama" in Form eines USB-Sticks. Das ist insoweit ganz praktisch, als im Grunde alle [ThinClient]s einen USB-Port besitzen. Er läuft mit dem '''rt73'''-Treiber. Dieser ist leider in Debian Etch nicht standardmäßig vorhanden. Ich musste auf ein Paket '''rt73-source''' aus "experimental" zurückgreifen, das (am besten auf einem anderen System) mit

 module-assistant build rt73 -l 2.6.18-4-486

in ein Modul-Paket übersetzt wurde. Die Angabe der Kernelversion ist nötig, weil der Kompilierungsrechner in der Regel einen anderen Kernel benutzt als die Thin Clients.

Ansonsten sei hier generell gesagt, daß für irgendwelche andere Hardware natürlich im LTSP-Client-System alle benötigten Treiber installiert sein sollten. Damit sollte man ggf. auch erstmal testen können, ob man den Adapter überhaupt "von Hand" in Betrieb nehmen kann.

Ich habe dann (im LTSP-chroot) das folgende Hook-Skript ''/etc/initramfs-tools/hooks/wirelessboot'' (mit gesetzten x-Bit) angelegt:
{{{
 #!/bin/sh
 . /usr/share/initramfs-tools/hook-functions

 PREREQ="lvm"
 prereqs()
 {
       echo "$PREREQ"
 }

 case $1 in
       prereqs)
               prereqs
               exit 0
       ;;
 esac

 echo "Wireless-Module einbinden..."
 force_load rt73
 force_load ide-disk
 force_load generic
 force_load tun
 cp -a /root/wireless/* "${DESTDIR}/"
}}}

Wie man sieht, kopiere ich ein Verzeichnis ''/root/wireless'', das ich folgendermassen gefüllt habe (auch im LTSP-chroot):

 mkdir -p /root/wireless/etc/Wireless/RT73STA/
 mkdir /root/wireless/mnt/
 cp /etc/Wireless/RT73STA/rt73.bin /root/wireless/etc/Wireless/RT73STA/
 mkdir /tmp/wireless
 cd /tmp/wireless
 aptitude download wireless-tools libiw28 openvpn libssl0.9.8 libc6 liblzo1 zlib1g
 for package in *.deb ; do dpkg -x $package /root/wireless/ ; done
 cd /root/wireless
 rm -r usr/share/doc
 rm -r usr/share/man

Man kann nun noch nach eigenem Ermessen wieder Dateien löschen (die manpages brauchen wir wirklich nicht in der ramdisk), aber das sollte selbsterklärend sein. Da der Speicher wieder freigegeben wird, ist es letztlich auch nicht soooo wichtig.

Obiges Hook-Skript wird nun während der Installation ausgeführt und bindet sowohl das Kernel-Modul als auch mein wireless-Verzeichnis in die ramdisk ein. Die eigentliche Erzeugung starte ich (wieder auf dem chroot-System) mit

 cd /root/
 mkinitramfs -o initrd.img-2.6.18-4-486 2.6.18-4-486

Der letzte Parameter ist übrigens wieder dem Umstand geschuldet, daß ich diesen Befehl ja in einem chroot-Jail auf meinem LTSP-Server gebe, der einen ganz anderen Kernel haben kann als mein Client-System benutzt. Die neue initramdisk wird so im aktuellen Verzeichnis erzeugt und kann ggf. an Ihren Platz kopiert werden (''/mnt/boot/'', wenn man obige Vorbereitungen getroffen hat).

Zum Debuggen ist evtl. der Parameter "-k" interessant, der den Inhalt der ramdisk als Verzeichnis erhält, so daß man diesen nochmals kontrollieren kann.



=== automatischer Aufbau einer WLAN-Verbindung ===

Grundsätzlich liegen die boot-Skripte in ''/etc/initramfs-tools/scripts/''. Hier gibt es Unterverzeichnisse für verschiedene Stadien des Bootvorgangs. In ''/usr/share/initramfs-tools/init'' kann man im Sourcecode sehen, in welchem Stadium des Bootvorganges welche Skripten aufgerufen werden müssen (''maybe_break ...-Zeilen''). Im konkreten Fall des wireless Adapters ist das '''init-premount'''-Stadium das richtige. In den anderen premount-Skripten wird z.B. udev geladen, das die USB-Module bereits lädt und die Devices einrichtet (Das ist ein Fall für "prereqs"). Nach den mount-Skripten wird dann im nfs-Skript das Interface per DHCP eingerichtet und benutzt. Da müssen wir uns zwischen setzen. Dazu erzeugen wir die Datei ''/etc/initramfs-tools/scripts/init-premount/wireless'':

{{{
 #!/bin/sh
 PREREQ="udev"
 prereqs()
 {
       echo "$PREREQ"
 }

 case $1 in
       prereqs)
               prereqs
               exit 0
       ;;
 esac

 for x in $(cat /proc/cmdline); do
       case $x in
               device=*)
                       device=${x#device=}
               ;;
               essid=*)
                       essid=${x#essid=}
               ;;
               wirelesskey=*)
                       wirelesskey=${x#wirelesskey=}
               ;;
               openvpn=*)
                       openvpn=${x#openvpn=}
               ;;
               hostname=*)
                       hostname=${x#hostname=}
               ;;
       esac
 done

 if [ -n "${device}" ]; then
       DEVICE=$device
       # den Wert fuer nachfolgende Skripte speichern
       echo "DEVICE=${device}" >>/conf/param.conf
 fi

 if [ -n "${essid}" ]; then
       # dem USB-System Zeit lassen, den WLAN-Treiber zu installieren
       sleep 5
       # Besonderheit fuer rt73-Treiber, schadet anderen aber wohl nicht:
       ifconfig $DEVICE up
       if [ -n "${wirelesskey}" ]; then
               iwconfig $DEVICE key $wirelesskey
       fi
       iwconfig $DEVICE essid $essid
 fi

 if [ -n "${openvpn}" ]; then
       # Als Parameter muss ein lokales Device angegeben werden, in dem die Schluessel liegen
       echo -n "OpenVPN startet..."
       mount $openvpn /mnt/
       # zuerst sollte die Basisverbindung konfiguriert werden
       ipconfig $DEVICE
       # source relevant ipconfig output
       . /tmp/net-${DEVICE}.conf
       # OpenVPN benoetigt seinerseits evtl. auch den Nameserver
       echo "nameserver $IPV4DNS0" >/etc/resolv.conf
       # Jetzt sollte das Ding starten:
       /usr/sbin/openvpn --daemon --cd /mnt/openvpn --config /mnt/openvpn/${hostname}.conf
       # Ich setze die MAC-Adresse des tun-Devices auf die meiner Ethernet-Schnittstelle
       # So ist es dem DHCP-Server egal, ueber welches Netz ich komme
       ifconfig eth0 down
       until ifconfig tap1; do sleep 1; done
       ifconfig tap1 down
       mac=`ifconfig eth0|grep eth0`
       ifconfig tap1 hw ether ${mac#*HWaddr}
       ifconfig tap1 up
       # Die weiteren Skripte sollen jetzt vom tun-Device als Hauptdevice ausgehen
       echo "DEVICE=tap1" >>/conf/param.conf
       echo "Fertig."
 fi
}}}

Wie man sieht, wird das WLAN auf der Kernel-Kommandozeile initialisiert und dann noch ein OpenVPN-Tunnel geöffnet. Beide Konfigurationen liegen letztlich auf dem lokalen Medium. Die Kernel-Bootzeile erscheint übrigens beim Hochfahren mitsamt dem WLAN-Schlüssel kurz auf dem Bildschirm und kann von jemandem, der es schafft, sich auf dem Client direkt einzuloggen mit "cat /proc/cmdline" jederzeit angezeigt werden. Wen das stört, der kann auch diese Konfiguration noch in ein Skript auslagern. Mich stört das nicht, weil ich WLAN per Definition für unsicher halte und deshalb OpenVPN benutze.

die Datei ''/mnt/boot/grub/menu.lst'' sieht nun so aus:

{{{
 default=1
 timeout=5
 title ThinClient cable
       root (hd0,0)
       kernel /boot/vmlinuz
       initrd /boot/initrd.img

 title ThinClient wireless
       root (hd0,0)
       kernel /boot/vmlinuz device=rausb0 essid=lugkr wirelesskey=<meinkey> openvpn=/dev/hda1 hostname=meinclient
       initrd /boot/initrd.img
}}}

Das OpenVPN habe ich serverseitig als Bridge in das LAN eingerichtet, das auf den Terminalserver zugreifen darf. Was nun konkret in das ''/mnt/openvpn''-Verzeichnis gehört, liest man am besten auf der zugehörigen Seite.



=== Sonstiges ===

Nun hat man in dem Client ein ungesichertes (d.h. WEP-gesichertes) und ein gesichertes (VPN-) Interface. Darum sollte man kurz nochmal checken, welche Dienste wo laufen. Bei einem normalen LTSP-Client (siehe LinuxTerminalServer) ist der Haupt-Dienst der X-Server. Hat man sich eingeloggt, kann man mit '''echo $DISPLAY''' erfahren, auf welchem Interface er läuft. Damit dieser sich auch wirklich an das richtige Interface bindet, kann man folgendes in die ''/etc/lts.conf'' schreiben:

 SCREEN_07 = startx -from meinclient.localdomain -query terminalserver

''(Der Name des Clients muss übrigens voll qualifiziert sein oder man trägt die IP-Adresse ein, da der einfache Name auf 127.0.0.2 eingestellt wird.)''



=== Auf welchem System erzeugt man das alles? ===

Eigentlich ist es nicht so sinnvoll, das reguläre LTSP-System mit all diesem Installations-Kram vollzumüllen. Die Erzeugung des KErnel-Modul-Paketes mit Hilfe von module-assistant ging auch gut auf einem anderen System. Für die übrigen Sachen habe ich mir einfach eine Kopie des chroot-Verzeichnisses angelegt, mit der ich dann experimentiert habe.

Im Grunde reicht es dann, wenn man später die entstandene initrd in den TFTP-Server kopert und fertig. Man muss also das Client-System gar nicht verändern. Darüberhinaus halte ich es ggf. für sinnvoll, die verwendeten Treiber und Tools (z.B. das rt73-Kernelmodul sowie die wireless-tools in obigem Beispielfall) auf dem echten LTSP Client-System zu installieren, um ggf. im laufenden Betrieb Konfigurationen ändern zu können.

Ein Problem hierbei entsteht bei einem Kernel-Update. Dann wird nämlich in der Regel auch die initrd automatisch neu gebaut. Hier ist zu überlegen, ob man diese jeweils komplett neu erzeugt oder doch obige Skripten und Verzeichnisse auf dem Produktivsystem belässt (womit die erzeugte initrd dann natürlich nur noch für wireless Terminals taugt und nicht mehr für normale...).

[{Tag ThinClient}]