Aus Linux-Magazin 03/2006

Einfache Verwaltung von plattenlosen Linux-Clients mit Union-FS

Selbst betagte Rechner kommen als Diskless-Clients unter Linux dank transluzenter Dateisysteme und anderer Zutaten zu neuen Ehren – ersparen sie ihren Admins doch jede Menge Arbeit.

Wo Software auf eine so große Anzahl Clients zu verteilen ist, dass der Rundgang mit der Installations-CD von vornherein ausscheidet, bieten sich einige Alternativen an. Häufig fällt die Wahl auf eine Administrationssoftware, die Betriebssystem, Anwendungen und Updates aus einem zentralen Repository via Netzwerk und gegebenenfalls mittels Wake-on-LAN auf die Clients verbreitet. Dieses an sich recht übersichtliche Verfahren kann in der Praxis jedoch schnell zu einem Alptraum ausarten. Denn gerade dann, wenn sich die Konfiguration der Zielmaschinen sehr rasch ändert, stößt diese Herangehensweise bald an ihre Grenzen.

Doch Abhilfe ist möglich. In der Unix-Welt sind Diskless-Clients weit verbreitet, die ihren Kernel und auch das Wurzeldateisystem übers Netzwerk beziehen. Damit entfällt die Softwareverteilung, weil alle Programme auf einem zentralen Server bleiben. Hat der Client genügend eigene Rechenpower, kann er als so genannter Rich-Client lokal Applikationen ausführen. Bei Thin-Clients findet andernfalls auch die Datenverarbeitung komplett auf dem Server statt.

PXE ist Standard

Die Zeiten, in denen man für den Systemstart via Netzwerk Boot-ROMs für exotische Netzwerkkarten brennen oder zumindest eine Bootdiskette dabei haben musste, sind so gut wie vorbei: Intels PXE-Industriestandard steckt in fast jedem PC, der damit in der Lage ist, ohne ein lokales Bootmedium sein Betriebssystem zu starten.

Wenn die Voraussetzungen erfüllt sind, kann man das Bios so umkonfigurieren, dass der PC immer via Netzwerk bootet. Dazu bedarf es lediglich eines DHCP-Servers für die Vergabe der IP-Adresse und der Bootloader-Definition sowie eines TFTP-Servers, der den Client erst mit dem Bootloader und danach mit dem Linux-Kern versorgt (Abbildung 1). Oftmals ist mit dem DHCP-Server auch noch ein dynamischer DNS-Server (DDNS) verbunden, der den Namen des gerade gestarteten Clients nach einer erfolgreichen DHCP-Adressenvergabe in den DNS-Dienst einträgt [1].

Abbildung 1: So bootet ein zustandsloser Client unter Mithilfe seiner Server.

Abbildung 1: So bootet ein zustandsloser Client unter Mithilfe seiner Server.

Hat der Linux-Kern auf der Clientmaschine seinen Dienst aufgenommen, verlangt er die Wurzel eines Dateisystems, um den Urprozess, meist »init«, starten zu können. Im Fall des Diskless-Clients ist dies natürlich ein Netzwerk-Dateisystem, genauer gesagt NFS, denn etwas anderes wird vom Linux-Kern an dieser Stelle nicht unterstützt. Zusätzlich müssen einige Kerneloptionen korrekt eingestellt sein [2].

Komplexität begrenzen

Beruht das Konzept einer derartigen Systemlandschaft auf plattenlosen Clients, ist eine der Randbedingungen, dass die Komplexität nicht beliebig steigen darf. Stattdessen sollen Standardlösungen den Administratoren das Leben erleichtern. Das hier vorgestellte Beispiel verwendet aus diesem Grund eine unmodifizierte Linux-Distribution, komplizierte Anpassungen entfallen. Ein Update der eingesetzten Software zieht also nicht die Anpassung einer Unzahl von Skripten nach sich. Zusätzlich gestaltet sich auch die Installation von Diskfull- und Diskless- Clients gleich.

Als Distribution für Server und Clients kommt Gentoo zum Einsatz. Die Installation eines Diskfull-Systems geschieht dort über eine »chroot()«-Umgebung, was auch beim Diskless-Client passt. Änderungen an den Start-Stop-Skripten können unterbleiben, damit geht der Admin möglichen Problemen bei einem Upgrade von vornherein aus dem Weg. Anzupassen sind nur Skripte, die zu Applikationen gehören, die der Anwender außerhalb der Gentoo-Paketverwaltung Portage installiert hat.

In einem Gentoo-Server sind die erforderlichen Dienste mit wenigen Kommandos schnell aufgesetzt:

emerge net-misc/dhcp
emerge net-ftp/tftp-hpa
emerge net-fs/nfs-utils

Die Konfiguration des DHCP-Servers ist in [3] nachzulesen. Listing 1 enthält ein entsprechendes Beispiel, die »subnet«-Blöcke sind jeweils den lokalen Gegebenheiten anzupassen. Die entscheidenden Optionen heißen »next-server« und »filename«. Die Option »next-server« bezeichnet den TFTP-Server. Im Beispiel ist dies derselbe Server, was aber nicht so sein muss.

Listing 1:
»/etc/dhcp/dhcpd.conf«

01 allow unknown-clients;
02 default-lease-time 1800;                # 30 minutes
03 max-lease-time 7200;                    # 2 hours
04 
05 subnet 192.168.39.0 netmask 255.255.255.0 {
06     range 192.168.39.128 192.168.39.254;
07     option broadcast-address 192.168.39.255;
08     option domain-name-servers 192.168.39.1;
09     option domain-name "localdomain";
10     next-server 192.168.39.10;
11     filename "gentoo_A/boot/pxelinux.0";
12 }

Netzwerk-Boot vorbereiten

Als Wert für die Option »filename« trägt der Admin den Pfad des Bootloaders relativ zur Wurzel des TFTP-Servers ein. Ob er hierfür die Grub-Variante »pxegrub« [4] oder aber »pxelinux« aus dem Projekt Syslinux [5] einsetzt, ist Geschmackssache. Doch ist die Unterstützung für neuere Netzwerkkarten bei »pxelinux« besser, dafür entfällt im Vergleich mit »pxegrub« das grafische Bootmenü.

Die Konfiguration des TFTP-Servers beschränkt sich im Wesentlichen auf die Wahl der Wurzel des bereitgestellten Dateisystembaums. Die folgenden Zeilen in »/etc/conf.d/in.tftpd« wählen hierfür »/tftproot«:

INTFTPD_PATH="/tftproot"
INTFTPD_OPTS="-u nobody -l -s -v ${INTFTPD_PATH}"

Auch die Konfiguration des NFS-Servers birgt keine Geheimnisse. Die folgenden Zeilen in »/etc/exports«

/tftproot/gentoo_A 192.168.39.*(ro,sync,no_root_squash)
/sync 192.168.39.*(ro,sync,no_root_squash)
/home 192.168.39.*(rw,sync,root_squash)

exportieren die Verzeichnisse »/tftproot/gento_A« und »/sync« lesend und außerdem das Verzeichnis »/home« lesend und schreibend für die Clients. Die Verwendung des Verzeichnisses »/sync« wird später klar.

Installation des Clients

Bevor ein Client erfolgreich starten kann, muss das zukünftige Wurzeldateisystem des Clients unterhalb von »/tftproot/gentoo_A« gefüllt sein. Dies gelingt bei Gentoo ohne Besonderheiten, da hier ja die Installation ab einer bestimmten Stufe immer in einer »chroot()«-Umgebung stattfindet. Und genau an dieser Stelle kreuzt der Weg die ganz normale Installation [7]:

chroot /tftproot/gentoo_A /bin/bash
mount -t proc none /proc
env-update
. /etc/profile

Die folgenden Schritte beziehen sich – wie bei Gentoo üblich – auf diese »chroot()«-Umgebung. Für den Client ist ein Kernel erforderlich, der die Option »Networking | Networking Options | IP: Kernel Level Autoconfiguration« gesetzt hat, damit er in der Lage ist, die erste IP-Konfiguration selbst via DHCP vorzunehmen. Zusätzlich sollten die benötigten Netzwerk-Kartentreiber einkompiliert und die Option »NFS-Root« gesetzt sein (Listing 2).

Listing 2:
Kerneloptionen

01 <*> NFS file system support
02 [*]   Provide NFSv3 client support
03 [ ]     Provide client support for the NFSv3 ACL protocol extension
04 [ ]   Provide NFSv4 client support (EXPERIMENTAL)
05 [ ]   Allow direct I/O on NFS files (EXPERIMENTAL)
06 < > NFS server support
07 [*] Root file system on NFS

Dies und die Kompilation des Kernels erledigt effektiv »genkernel« mit »emerge genkernel; genkernel –menuconfig all«. Am Ende finden sich dann unter »/boot« wie gewohnt der Kern und die initiale RAM-Disk, die man verwenden kann, aber nicht muss.

Der Admin sollte auch an »/etc/conf.d/keymaps« denken und in »/etc/fstab« das via NFS zu montierende Wurzeldateisystem mit folgender Zeile eintragen: »192.168.39.10:/tftproot/gentoo_A / nfs defaults,ro 0 0«. Die sonstigen Systemtools kann er wie üblich und nach Geschmack installieren.

Hat der Kern dann im späteren Betrieb das primäre Netzwerk-Interface konfiguriert, so dürfen die Bootskripte nicht noch einmal eine IP-Adresse anfordern. Andernfalls würde der Client plötzlich ohne sein Wurzeldateisystem dastehen. Diesen Fehler verhindert der folgende Eintrag in »/etc/conf.d/net«: »config_eth0 = ( “noop” )«.

Booten übers Netz

Die Konfiguration von »pxelinux« aus Listing 3 erlaubt es, den Client immer noch über eine eventuell vorhandene Festplatte oder eben weiterhin über das Netzwerk zu starten. Daher sind hier unterschiedliche Einträge vorgesehen. Die Netzwerk-Bootvorgänge unterscheiden sich nur durch die Parameter für den Kernel, die später den Bootvorgang dynamisch steuern. Damit kann der Admin alle Clients generell auf PXE-Boot umstellen. Sie bieten ein einheitliches Bootmenü an.

Listing 3:
»/tftproot/gentoo_A/boot/pxelinux.cfg/default«

01 default L
02 timeout 100
03 prompt 1
04 display msg.txt
05 
06 label L
07         LOCALBOOT 0
08 
09 label l
10         LOCALBOOT 0
11 
12 label R
13         kernel /gentoo_A/boot/EbzImage
14         append ip=dhcp root=/dev/nfsnfsroot=192.168.39.10:/tftproot/gentoo_A,hard,intr,ro udev init=/stateless.sh stateless=unionfs xauto=auto
15 
16 label r
17         kernel /gentoo_A/boot/EbzImage
18         append ip=dhcp root=/dev/nfsnfsroot=192.168.39.10:/tftproot/gentoo_A,hard,intr,ro udev init=/stateless.sh stateless=unionfs xauto=auto

Da »syslinux« auf dem Client noch nicht vorhanden ist, installiert der Admin es kurzerhand nach: »emerge sys-boot/syslinux«. Die grundsätzliche Einrichtung eines Diskless-Clients ist damit abgeschlossen. Ein Test verliefe aber noch nicht erfolgreich, weil ja das Wurzeldateisystem nur read-only exportiert ist. Daher könnte der Client weder unter »/var« seine Logfiles schreiben noch eine »/etc/mtab« anlegen.

Durchscheinende Dateien

Abhilfe schafft ein transluzentes Dateisystem. Es erreicht außerdem, dass gegebenüber einer einfachen Installation [7] nicht für jeden Diskless-Client ein eigenes Wurzelverzeichnis bereitgestellt werden muss. Obwohl das transluzente Dateisystem Union-FS [8] in Gentoo noch maskiert, also nicht ohne weiteres installierbar ist, reicht seine Stabilität für den vorliegenden Zweck bereits aus. Der Administrator kann deshalb die Maskierung unbesorgt aufheben und die aktuelle Version mit »ACCEPT_KEYWORDS=”~x86″ emerge unionfs« aufspielen.

Union-FS erlaubt es, das vom Server exportierte Wurzelverzeichnis zunächst unverändert und schreibgeschützt zu übernehmen. Es wird dann zusammen mit einem beschreibbaren Dateisystem zu einem Union-Mount vereinigt. Änderungen landen in dem beschreibbaren Zweig der Vereinigung.

Damit Gentoos Portage-System bei späteren Upgrades des Clients reibungslos funktioniert, weist der Admin den Kernel über seine Parameter (Listing 3) dazu an, statt »init« das Shellskript »stateless.sh« (Listing 4) zu starten. Es sorgt für die notwendigen Overlay-Mounts für »/etc« und »/var« (Abbildung 2). Das darunter liegende Read-Write-Dateisystem benutzt das RAM-Disk-Dateisystem Temp-FS. Das passiert vor dem Gentoo-Startvorgang und wird auch außerhalb des Systems, im Bootloader konfiguriert.

Listing 4:
»stateless.sh«

01 #!/bin/bash
02 
03 MODPROBE=/sbin/modprobe
04 IFCONFIG=/sbin/ifconfig
05 
06 ahostname(){
07     MYHOST="$1_`$IFCONFIG eth0 | awk '/HWaddr/ {print $5}' | tr -d ':'`"
08     echo "STATELESS: Setting Hostname to $MYHOST"
09     echo "HOSTNAME="$MYHOST"" > /etc/conf.d/hostname
10     /bin/hostname "$MYHOST"
11 }
12 
13 getparams() {
14         local cmdline=$(dmesg | grep '^Kernel command line' | sed 's/^Kernel command
15         line://g')
16         for pp in $cmdline; do
17                 echo $pp | grep '^stateless=' >/dev/null 2>&1
18                 if [ $? -eq 0 ]; then
19                         echo $pp | sed 's/stateless=//g'
20                         return 0
21                 fi
22         done
23         echo ""
24         return 1
25 }
26 
27 isset() {
28         for p in $(getparams | tr ',' ' '); do
29                 if [ "$p" == "$1" ]; then
30                         return 0
31                 fi
32         done
33         return 1
34 }
35 
36 aunionfs() {
37     isset unionfs
38     if [ $? -eq 0 ]; then
39         echo "STATELESS: Loading module unionfs ..."
40         $MODPROBE unionfs
41         while [ "$1" != "" ]; do
42             echo "STATELESS: Mounting tmpfs $1 ..."
43             mount -n -t tmpfs -o defaults none /mnt/unionfs/$1
44             echo "STATELESS: Mounting $1 unionfs ..."
45             mount -n -t unionfs -o dirs=/mnt/unionfs/$1=rw:/$1=ro none /$1
46             shift
47         done
48     else
49         echo "STATELESS: Not using unionfs as requested ..."
50     fi
51 }
52 
53 aunionfs etc var
54 ahostname stateless
55 exec /sbin/init
Abbildung 2: Dieser Ausschnitt aus dem Dateisystem des Clients zeigt die Overlay-Mounts für die Verzeichnisse »/etc« und »/var«.

Abbildung 2: Dieser Ausschnitt aus dem Dateisystem des Clients zeigt die Overlay-Mounts für die Verzeichnisse »/etc« und »/var«.

Eigenes Init

Das Skript sorgt auch für die Vergabe eines unverwechselbaren Hostnamens auf Basis der MAC-Adresse. Danach überlagert es sich mit »init« – und alles geht normal weiter, der Client bootet wie üblich. Die Änderungen in »/etc« und »/var« gelangen in die RAM-Disk und sind nach dem Herunterfahren verloren. Aus diesem Grunde spricht man auch von einem Stateless-Rich-Client.

Für das Skript »stateless.sh« steht unter [10] auch ein Portage-Ebuild bereit. Da dies eine Abweichung vom offiziellen Portage-Tree ist, sollte der Admin für diese Zwecke unter »/usr/local/portage« einen lokalen Portage-Zweig einrichten. Dies geschieht durch die Option »PORTDIR_OVERLAY=”/usr/local/portage”« in der Datei »/etc/make.conf«. Anschließend kopiert er einfach »sys-apps/stateless-0.1_pre.ebuild« nach »/usr/local/portage/sys-apps/stateless« und installiert mit »emerge stateless«.

Zu guter Letzt ist noch die Konfigurationsdatei des Bootloaders anzupassen. Die Kerneloption »stateless=unionfs« schaltet den zustandslosen Rich-Client für das nächste Booten scharf. An dieser Stelle sollte auch gleich ein »depmod -a« ausgeführt werden, denn bei einem späteren Start des Clients ist dies durch das Read-only-Wurzeldateisystem nicht mehr möglich.

Das grundsätzliche Konzept lässt sich in einigen Punkten noch weiter verfeinern. Da alle Logging-Informationen bei einem Neustart verloren gehen, schickt der Client diese Daten besser über Syslog-NG [16] an einen zentralen Logging-Server. Je nach Bedarf und Vorliebe kann der Administrator auf dem Logging-Server für jeden Client wieder getrennte Logdateien vorsehen. Listing 5 zeigt die Syslog-Konfiguration für den Client und Listing 6 die für den Server.

Listing 5:
»syslog-ng.conf« des Clients

01 options {
02         long_hostnames(off);
03         sync(0);
04         stats(43200);
05 };
06 source src { unix-stream("/dev/log"); internal(); pipe("/proc/kmsg"); };
07 destination server { udp("192.168.39.10",port(514)); };
08 log { source(src); destination(server); };

Listing 6:
»syslog-ng.conf« des Servers

01 options {
02         chain_hostnames(off);
03         keep_hostname(yes);
04         sync(0);
05         stats(43200);
06 };
07 source src { unix-stream("/dev/log"); internal(); pipe("/proc/kmsg"); };
08 source remote {
09         udp (
10                 ip("0.0.0.0")
11                 port(514)
12         );
13 };
14 destination messages { file("/var/log/messages"); };
15 destination hosts {
16         file("/var/log/hosts/$FULLHOST"
17         create_dirs(yes));
18 };
19 log {source(src); destination(messages); };
20 log {source(remote); destination(hosts); };

LDAP einbinden

Die Benutzerdatenbank »/etc/passwd« und »/etc/shadow« stehen zwar allen Clients zum Lesen zur Verfügung, doch ist es in einer größeren Umgebung selbstverständlich, eine zentrale Benutzerdatenbank zu verwenden. In einer reinen Unix/Linux-Welt kommt dafür wohl in den meisten Fällen ein OpenLDAP-Server zum Einsatz, in Mischumgebungen zusammen mit Windows ist die bessere Wahl allerdings ein Microsoft Active Directory Server (ADS). Hierfür benötigt der Client sowohl »nss_ldap« als auch »pam_ldap«. Mit dem Portage-System ist das schnell erledigt: »emerge nss_ldap pam_ldap«.

Für den Active Directory Server ist noch die Schema-Erweiterung Microsoft Services for Unix (MSSFU) notwendig. Auch braucht »/etc/ldap.conf« (Listing 7) noch ein Attribute-Mapping, um der anderen Namensgebung dieses Schemas Rechnung zu tragen. Damit sowohl die Authentifizierung als auch die Attributezuordnung zu den Benutzern über LDAP laufen, sind sowohl der Nameservice-Switch (NSS) als auch der PAM-Stack anzupassen. Der Artikel in [11] beschreibt diesen Vorgang ausführlich.

Listing 7:
»/etc/ldap.conf«

01 base dc=ds,dc=fh-kl,dc=de
02 uri ldaps://dc1.ds.fh-kl.de ldaps://dc2.ds.fh-kl.de
03 ldap_version 3
04 
05 binddn cn=buser,cn=users,dc=ds,dc=fh-kl,dc=de
06 bindpw buserpw
07 
08 # Services for UNIX 3.5 mappings
09 nss_map_objectclass posixAccount User
10 nss_map_objectclass shadowAccount User
11 nss_map_attribute uid sAMAccountName
12 nss_map_attribute uidNumber msSFU30UidNumber
13 nss_map_attribute gidNumber msSFU30GidNumber
14 nss_map_attribute uniqueMember member
15 nss_map_attribute homeDirectory msSFU30HomeDirectory
16 nss_map_attribute loginShell msSFU30LoginShell
17 nss_map_objectclass posixGroup Group
18 pam_filter objectclass=User
19 pam_password ad
20 pam_login_attribute sAMAccountName
21 
22 ssl on
23 tls_checkpeer no
24 referrals no

Zentrale Ablage

Die Benutzer benötigen ein zentrales Dateisystem für ihre Daten. In einer reinen Unix/Linux-Umgebung eignet sich dafür wohl wieder NFS am besten. In einer Linux/Windows-Mischumgebung reicht NFS nicht aus. Für die Windows-Welt ist ein CIFS-Fileserver notwendig. Bei der Entscheidung zugunsten eines Windows-Fileservers gibt es allerdings Probleme mit anderen Dateitypen jenseits von regulären Dateien und Verzeichnissen. Damit scheidet ein Windows-Fileserver eigentlich aus.

Mit Samba und den CIFS-Unix-Extensions lassen sich diese Probleme vermeiden. Allen CIFS-Servern bleibt jedoch gemeinsam, dass sie eine benutzer- und sitzungsbezogene Authentifizierung erfordern. Die wiederum ist ein typischer Anwendungsfall für das Sitzungsmanagement im PAM-Stack des Clients.

Der zugehörige Mount-Helper »mount.cifs« stammt aus der Samba-Suite, die Kernelunterstützung für CIFS ist dank »genkernel« schon im Kernel enthalten. Die User-Level-Tools sind wie gewohnt zu installieren: »emerge nfs-utils samba«. Das bereits betagte und in manchen Situationen instabile PAM-Modul Pam_mount [12] wurde bei dieser Gelegenheit durch eine neue, eigene Variante ersetzt: Pam_cifs [13].

Dieses Modul steht auch als Portage-Ebuild zur Verfügung. Es klinkt sich sowohl im Authentisierungs-Stack als auch im Session-Stack von PAM ein. Ein Daemon sorgt für ein zuverlässiges Abmontieren der CIFS-Shares, falls der betreffende Benutzer auf dem System nicht mehr aktiv ist.

In Kombination mit einem Windows-Fileserver verwendet das vorgestellte Beispiel Homeverzeichnisse via NFS und lässt »pam_cifs« den CIFS-Share nach »/var/cifs/User/cifs« montieren und im Homeverzeichnis einen Link von »cifs« auf »/var/cifs/User/cifs« anlegen.

In diesem Konzept findet jeder Nutzer seine zentrale Datenablage unter »/cifs« wieder. Unter Windows wird dies beispielsweise als Netzwerk-Laufwerk »U:« durch das Anmeldeskript verbunden. So sind auch Windowmanager zufrieden, die Sockets und Pipes im Homeverzeichnis des Benutzers anlegen möchten.

Pam_cifs gibt es ebenfalls als Portage-Ebuild, das wie oben unter »/usr/local/portage« zu platzieren ist. Anschließend muss der Admin noch die PAM-Konfiguration entsprechend Listing 8 anpassen und mit Hilfe von »rc-update add cifsumountd default« dafür sorgen, dass der Daemon »cifsumountd« beim Booten automatisch startet. Er ist zuständig für das Abmontieren nicht mehr benötigter CIFS-Shares.

Listing 8:
»/etc/pam.d/system-auth«

01 auth       required     /lib/security/pam_env.so
02 auth       required     /lib/security/pam_cups.so debug # stored auth-token
03 auth       sufficient   /lib/security/pam_unix.so likeauth nullok # get auth-token, local users
04                                                                   # don't use pam_cifs
05 auth       required     /lib/security/pam_cifs.so debug # stored auth-token
06 auth       sufficient   /lib/security/pam_ldap.so use_first_pass debug
07 auth       required     /lib/security/pam_deny.so
08 
09 account    sufficient   /lib/security/pam_ldap.so debug
10 account    required     /lib/security/pam_unix.so
11 
12 password   required     /lib/security/pam_cracklib.so retry=3
13 password   sufficient   /lib/security/pam_ldap.so debug
14 password   sufficient   /lib/security/pam_unix.so nullok md5 shadow use_authtok
15 password   required     /lib/security/pam_deny.so
16 
17 session    required     /lib/security/pam_limits.so
18 session    required     /lib/security/pam_mkhomedir.so umask=077 skel=/etc/skel
19 session    sufficient   /lib/security/pam_ldap.so debug
20 session    required     /lib/security/pam_unix.so
21 session    optional     /lib/security/pam_cups.so use_first_pass debug min_uid=1000
22 session    optional     /lib/security/pam_cifs.so use_first_pass debug min_uid=1100 make_mount_point linkname=cifs prefix=/var suffix=/cif

Drucken

Drucken in einer reinen Linux-Umgebung über Cups ist ebenfalls problemlos möglich – sowohl über die LDP/IPP-Protokolle als auch über das Smbspool-Backend auf Windows-Drucker. Verlangen die Windows-Drucker jedoch nach einer Authentifizierung, weil beispielsweise eine Druckkostenabrechnung durchgeführt wird, beginnt die Suche nach anderen Lösungen. Eine Möglichkeit besteht in einem Client-seitigen Password-Cache (siehe Pam-cups [12], [13]).

Diese nicht besonders elegante Lösung lässt sich zwar durch Umstellung des Gesamtkonzepts auf Kerberos umgehen. Doch steht eine Anpassung von »smbspool« für die Verwendung des Kerberos-Credential-Cache des druckenden Benutzers noch aus.

Virtuelle Clients

Natürlich kann man auch VMware-Workstation oder VMware-Player [15] in den Clientsystemen installieren. Liegen die virtuellen Festplatten-Images jedoch auf einem NFS-Server, kommt bei der Arbeit mit VMware keine Freude auf. Dann ist es besser, von dem strengen Konzept eines zustandslosen Clients abzuweichen und ein Caching der VMware-Images auf der lokalen Festplatte einzurichten. Dies lässt sich durch ein einfaches »rsync«-Skript bewerkstelligen – [10] stellt dazu ein Portage-Ebuild zur Verfügung.

Voraussetzung dafür ist, dass es auf der lokalen Platte eine Partition mit dem Label »DISKLESS« gibt. Achtung: Die Partition wird gegebenenfalls formatiert und »rsync« mit dem exportierten »/sync«-Verzeichnis des Servers angestoßen. Das Verzeichnis »/sync« des Servers wird zunächst nach »/remote« des Clients montiert. Das »rsync«-Skript synchronisiert »/sync/local« des Servers nach »/cache« des Clients. Auf dem Client ist »/remote/local« ein symbolischer Link auf »/cache« und »/remote/remote« wird mit einem Tmp-FS wieder zu einem Union-Mount zusammengefasst.

Damit besteht die Möglichkeit, die VMware-Clones unter »/remote/local« zu halten, während die zugehörigen Master unter »/remote/remote« zu finden sind (siehe Abbildung 3). Wenn außerdem das VMware-Gastsystem zustandslos sein soll, kennzeichnet der Admin die Festplatten in VMware als »independent«.

Abbildung 3: Mit Hilfe von Union-Mounts lassen sich auf dem Server sehr effektiv unterschiedliche, aber ähnliche Client-Dateisysteme abbilden.

Abbildung 3: Mit Hilfe von Union-Mounts lassen sich auf dem Server sehr effektiv unterschiedliche, aber ähnliche Client-Dateisysteme abbilden.

Die hier vorgestellte Lösung eignet sich ebenfalls für getrennte Subnetze oder verteilte Standorte, die unterschiedliche Netzwerk-Konfigurationen erforderlich machen. In diesen Fällen differieren die Konfigurationen der Rich-Clients nur minimal.

Server-Varianten

Der TFTP- und NFS-Server benötigt Netzwerk-Interfaces in jedem Subnetz. Notwendige Änderungen bei den Clients betreffen die Bootloader-Konfiguration, gegebenenfalls die DNS-Serverangaben in »/etc/resolv.conf« oder die Lage der Homeverzeichnisse. Dann bietet es sich an, ein Dateisystem aus dem ursprünglichen Wurzeldateisystem »/tftproot/gentoo_A« der Clients und den Änderungen für ein weiteres Subnetz mit Hilfe von »unionfs« zu erzeugen.

Unter [10] liegt ein Patch, das ein Nachschlagen so genannter Whiteouts vermeidet, also jener Verzeichniseinträge, die versehentlich gleichnamige in tiefer liegenden Layern verdecken. Damit wird der Read-only-Zweig »/tftproot/gentoo _A« mit einem Read-Write-Zweig »/tftproot/gentoo_Bdiff« zu »/tftproot/gentoo_B« vereinigt (Abbildung 4):

mount -t unionfs -o dirs=/tftproot/gentoo_Bdiff=rw:/tftproot/gentoo_A=ro none /tftproot/gentoo_B
Abbildung 4: Um möglichst performant mit VMware arbeiten zu können, kopiert »rsync« die Clones der virtuellen Maschinen auf den Client.

Abbildung 4: Um möglichst performant mit VMware arbeiten zu können, kopiert »rsync« die Clones der virtuellen Maschinen auf den Client.

Allerdings liefert das Union-FS keine Filesystem-ID. Die muss daher manuell über die Option »fsid« in »/etc/exports« eingetragen werden, wenn der NFS-Server das Subnetz B des Bereichs 192.168.48.0/24 beliefern soll: »/tftproot/gentoo_B 192.168.48.*(fsid=0x1234,ro,sync,no_root_squash)«.

Dann können in »/tftproot/gentoo_B« die erforderlichen Änderungen vorgenommen werden. Damit der Bootloader im Subnetz B auch die richtigen Parameter weitergibt, ist die Konfiguration anzupassen (Listing 9). Zudem muss auch der DHCP-Server den richtigen Pfad auf den Bootloader des Clients mitgeben. Für das Subnetz B des Bereichs 192.168.48.0/24 müsste ein passendes File »/etc/dhcp/dhcpd.conf« beispielsweise enthalten:

next-server 192.168.48.10;
filename "gentoo_B/boot/pxelinux.0";

Listing 9:
»/tftproot/gentoo_B/boot/pxelinux.cfg/default«

01 default L
02 timeout 100
03 prompt 1
04 display msg.txt
05 
06 label L
07         LOCALBOOT 0
08 
09 label l
10         LOCALBOOT 0
11 
12 label R
13         kernel /gentoo_B/boot/EbzImage
14         append ip=dhcp root=/dev/nfs
nfsroot=192.168.48.10:/tftproot/gentoo_B,
hard,intr,ro udev init=/stateless.sh stateless=unionfs xauto=auto
15 
16 label r
17         kernel /gentoo_B/boot/EbzImage
18         append ip=dhcp root=/dev/nfsnfsroot=192.168.48.10:/tftproot/gentoo_B,hard,intr,ro udev init=/stateless.sh stateless=unionfs xauto=auto

Für die Clients ist dann noch die Datei »/tftproot/gentoo_B/etc/fstab« anzupassen: »192.168.48.10:/tftproot/gentoo_B / nfs defaults,ro 0 0«.

In einem Szenario mit mehreren Standorten und Bootservern ist es unter Umständen sinnvoller, die Wurzeldateisysteme über »rsync« zu replizieren. Der oben erzeugte Dateisystembaum unter »/tftproot/gentoo_B« dient als Quelle für eine Replikation auf einen anderen Server. Die Clients booten von diesem alternativen Server. Die Konfiguration befindet sich aber nach wie vor nur an einer einzigen zentralen Stelle.

Client-Varianten

Das in diesem Beitrag beschriebene Konzept lässt sich den unterschiedlichsten Anforderungen anpassen. Beispielsweise kann man die Konfiguration von KDE so ändern, dass der Benutzer standardmäßig auf einem entfernten Server angemeldet wird. Auf diese Weise ist mit demselben Konzept ein waschechter Thin-Client entstanden. Soll der Thin-Client außerdem noch bezüglich der Serverplattform neutral bleiben, ist es zum Beispiel möglich, NX-Client und -Server von Nomachine [14] einzusetzen oder auch auf RDesktop zurückzugreifen. Ebenso kann der Admin eine Bootoption für einen Kiosk-Modus mit Webbrowser anbieten.

Zum Abschluss sein noch erwähnt, dass sich die zustandslosen Rich- oder Thin-Clients jederzeit und bedenkenlos während des Betriebs ausschalten lassen. Das planmäßige Herunterfahren beschleunigt ein Powerdown-Skript in »/etc/conf.d/local.stop«. (jcb)

Infos

[1] Konstantin Agouros, “Zahlen Meister!”: Linux-Magazin 02/02, S. 54

[2] Diskless-Client-Howto: [http://www.tldp.org/HOWTO/Diskless-root-NFS-HOWTO.html]

[3] DHCP-Server-Konfiguration: [http://www.tldp.org/HOWTO/DHCP/index.html]

[4] Grub: [http://www.gnu.org/software/grub/]

[5] Syslinux: [http://syslinux.zytor.com/]

[6] Gentoo: [http://www.gentoo.org]

[7] Gentoo-Installation: [http://www.gentoo.org/doc/de/handbook/2005.1/handbook-x86.xml]

[8] Gentoo, diskless: [http://www.gentoo.org/doc/en/diskless-howto.xml]

[9] Union-FS: [http://www.fsl.cs.sunysb.edu/project-unionfs.html]

[10] Gentoo-Rich-Clients:[http://mozart.informatik.fh-kl.de/download/Software/GentooDiskless]

[11] Markus Klimke, “Fensterplatz”: Linux-Magazin-Sonderheft 03/05, S. 32

[12] PAM-mount: [http://www.flyn.org/projects/pam_mount/index.html]

[13] PAM-cifs und PAM-cups: [http://mozart.informatik.fh-kl.de/download/Software/pam_cifs/pam_cifs.html] und [http://mozart.informatik.fh-kl.de/download/Software/pam_cups/pam_cups.html]

[14] Gentoo 3rd-Party Ebuilds:[http://gentoo-wiki.com/HOWTO_Installing_3rd_Party_Ebuilds]

[15] Nomachine: [http://www.nomachine.com]

[16] Christian Schmitz, “Computertagebuch”: Linux-Magazin 11/03, S. 61

Die Autoren

Dipl.-Inf. Jan Dworschak hat an der FH Kaiserslautern Angewandte Informatik studiert und arbeitet derzeit als Software-Entwickler.

Markus Müller studiert an der FH Kaiserslautern Angewandte Informatik und beschäftigt sich seit fünf Jahren mit Linux und anderen freien Betriebssystemen.

Prof. Dr.-Ing. Wilhelm Meier ist an der FH Kaiserslautern in Zweibrücken als Dozent im Fachbereich Informatik/Mikrosystemtechnik für das Lehrgebiet “Betriebssysteme” tätig.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben