Blog

Unterricht mit Joplin organisieren

Joplin

Unser „GBG-Linux“ wird in der Version für die Lehrkräfte eine Software namens Joplin enthalten, mit der man Unterricht in Notizbüchern organisieren und vorbereiten kann, ähnlich wie in der Software Microsoft OneNote.

In Joplin kann man sehr einfach Dateien einfügen, die dann auch in den Notizbüchern gespeichert und synchronisiert werden. Ein großer Vorzug von Joplin ist, dass es möglich ist, die Notizbücher samt der enthaltenen Arbeitsblätter auf dem IServ über das Webdav-Protokoll zu speichern. Auf diese Weise kann man unterschiedliche Installationen von Joplin beispielsweise auf einem Privatrechner und auf einem Smartphone (Joplin gibt es als App für iOS und Android) synchron halten. Zugleich tut man der DSGVO genüge, da Daten nur auf dem schulischen Server gespeichert werden und zu keinem Zeitpunkt an Dritte gelangen. Außerdem kann man mit Joplin auch eine Ende-zu-Ende-Verschlüsselung nutzen.

Digitale Mitschriften lassen sich dann auf den GBG-Linux-Geräten mit der Software xournal++ anfertigen und in die in Joplin organisierten Notizbücher integrieren. Das folgende Video zeigt, wie ein solcher Arbeitsfluss auf einem GBG-Linux-Gerät aussehen könnte.

Arbeitsfluss mit Joplin

Joplin unterscheidet sich von Microsoft OneNote in der Hinsicht, dass Joplin standardmäßig in einer geteilten Ansicht startet, die aus einem Markdown– und einem Vorschaufenster besteht. Man kann aber auch durch einen Mausklick in die gängige WYSIWYG-Ansicht (Akronym für den Grundgedanken „What You See Is What You Get“) umschalten, in der man dann den Inhalt so sieht, wie er formatiert ist. So sieht man dann Beispielsweise eine Formel als solche und nicht deren TeX-Code. Mehr zur Formatierung und Ausgabe von Formeln findet man hier.

Markdown vs. WYSIWYG

Synchronisation mit IServ

Um die Synchronisation von Joplin mit dem IServ-Server zu aktivieren, muss man als Erstes in den IServ-Dateien einen Ordner mit dem Namen „joplin“ anlegen. Dieser wird dann später genutzt, um in ihm die Notizbücher zu speichern. Dafür muss man im Menü auf der schulischen IServ-Seite auf der linken Seite auf „Dateien“ klicken und dann im Reiter oben nochmals auf „Dateien“ klicken (Wichtig: Nicht auf „Eigene“ oder „Gruppen“ klicken [siehe Bild unten]):

Im nächsten Schritt geht man auf „+Hinzufügen“ und legt einen neuen Ordner an:

Dieser neue Ordner soll dann „joplin“ heißen:

Damit sind die Vorbereitungen bei IServ abgeschlossen und Joplin kann gestartet und eingerichtet werden. In Joplin geht man dann im Menü auf „Werkzeuge“ -> „Optionen“:

In den Optionen muss man dann auf den Reiter „Optionen“ gehen und dort die Synchronisationseinstellungen wie folgt vornehmen:

Das sind die einzustellenden Punkte:

Synchronisationsziel: „WebDAV“

WebDAV-URL: https://webdav.gbg-seelze.eu/joplin (bei einem anderen IServ die Domain entsprechend ersetzen)

WebDAV-Benutzername: vorname.nachname

WebDAV-Passwort: IServ-Passwort

Diese Einstellungen sind dann auch entsprechend in der Android, bzw. iOS-App vorzunehmen. Hat man dieses gemacht, kann man seine Unterrichtsplanungen komfortabel auf unterschiedlichen Endgeräten betrachten und bearbeiten.

IServ-Linux-Client per LTSP an festplattenlose Rechner ausliefern: Arbeit mit Active Directory

In meinem Blogpost mit dem Titel „IServ-Linux-Client per LTSP an festplattenlose Rechner ausliefern“ habe ich beschrieben, wie man einen solchen Linux Terminal Server installiert. Die Anleitung basiert noch auf der Arbeit mit einer Windows-NT-Domäne. Nun wurde unser IServ-Server auf Active Directory umgestellt. Aus diesem Grund sind zwei Anpassungen nötig geworden, damit die LTSP-Clients beim Hochfahren automatisch zur Domäne hinzugefügt werden. Zum Verständnis dieses Blogposts sollte zunächst die ursprüngliche Anleitung gelesen werden.

Zum einen muss sichergestellt werden, dass in der Samba-Konfiguration in /etc/samba/smb.conf als realm der korrekte Domänenname eingetragen wird (bei uns: realm=ad.gbg-seelze.eu) und zum anderen muss dann das Skript zum Domänenbeitritt entsprechend für Active Directory angepasst werden.

An dieser Stelle sei nochmals erwähnt, dass die von mir beschriebene Lösung eher ein Workaround ist, der langfristig besser gelöst werden muss, da in dem Skript join-domain.sh das Domänenadministratorpasswort im Klartext enthalten ist. Zwar sind die Zugriffsrechte mit 700 gesetzt, sodass die Datei von einem unterprivilegierten Benutzer nicht gelesen oder ausgeführt werden kann, aber dennoch bietet das Skript eine gewisse Angriffsfläche. Alternativ kann man den Befehl zum Domänenbeitritt auch in der ltsp.conf in dem Abschnitt zur Client-Konfiguration hinterlegen. Damit hätte man das Domänenadministratorpassword immerhin nicht mehr im Client-Image. Das Grundproblem bleibt aber bestehen.

Nach dieser Vorrede hier nun der veränderte Befehl zum Domänenbeitritt:

echo -n 'password' | net ads join -U domainadmin ad.gbg-seelze.eu --no-dns-updates

Bei diesem Befehl ist domainadmin entsprechend durch den Benutzernamen des verwendeten Domänenadministrators, password durch das Passwort sowie ad.gbg-seelze.eu durch den Namen der AD-Domäne zu ersetzen. Damit kann man dann den LTSP-Client automatisch zur AD-Domäne hinzufügen.

Fernwartung von Laptops bei Schülerinnen und Schülern zuhause: Verteilung von Shell-Skripten und Konfigurationsdateien mit einem deb-Paket über ein launchpad ppa

In diesem Blog-Eintrag werde ich kurz dokumentieren, wie ich die Skripte und Konfigurationsdateien, die unser „GBG-Linux“ konfigurieren, in ein deb-Paket verpackt und dann mithilfe eines launchpad ppa verteilt habe.

Durch die Corona-Krise wurden bei uns in der Schule knapp über sechzig Ubuntu-Laptops an Schülerinnen und Schüler verliehen, die diese Geräte zuhause benutzten. Diese Tatsache machte es erforderlich, dass ich auch in der Lage sein muss, diese Geräte aus der Ferne zu konfigurieren und zu aktualisieren. Ich habe dieses mit dem folgenden kleinen Update-Skript gelöst:

#!/bin/bash
sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
sudo apt-get autoremove -y

Damit der Standardbenutzer dieses Skript ausführen kann, muss ihm erlaubt werden, das Skript mit sudo ohne Passworteingabe auszuführen. Dieses kann man mit einer Regel in der sudoers-Datei lösen. Statt die Regel direkt in die sudoers hineinzuschreiben, habe ich die Regel im Ordner /etc/sudoers.d/ abgelegt, damit die sudoers nicht angetastet wird:

gbg ALL = NOPASSWD: /usr/bin/updater.sh

Damit der Benutzer gbg die Aktualisierungen dann auch bequem starten kann, muss man noch einen Programmstarter im Startmenü anlegen, auf den der Nutzer dann nur noch klicken muss:

[Desktop Entry]
Type=Application
Name=Updates installieren
GenericName=Updates installieren
Exec=sudo /usr/bin/updater.sh
Icon=/usr/share/icons/updater.svg
Terminal=true
Categories=System;

Wie man dem Code entnehmen kann, habe ich auch noch ein kleines instruktives Icon erstellt. Auf diese Weise kann der Benutzer nun mit einem einfachen Mauskick auf das Icon im Startmenü Updates installieren, ohne dass er dafür ein Passwort eingeben muss.

Konfigurationsänderungen auf den Geräten

Um in der Lage zu sein, auch Konfigurationsänderungen an den Geräten bei den Schülerinnen und Schülern zuhause durchzuführen, habe ich die Skripte, mit denen ich das „GBG-Linux“ verwalte, in ein deb-Paket gepackt und dieses dann in einem launchpad ppa zur Verfügung gestellt. Dieses ppa wird auf den Laptops zu den Paketquellen hinzugefügt und wenn ich dann den „GBG-Client“ aktualisiere und die Schülerin oder der Schüler zuhause den Update-Knopf drückt, dann aktualisiert sich auch automatisch der „GBG-Client“, sodass etwaige Konfigurationsänderungen wirksam werden.

Verpacken von Shell-Skripten in ein deb-Paket

Als Erstes muss man folgende Pakete auf dem Entwicklungsgerät installieren.

sudo apt install dh-make devscripts

Hat man dieses gemacht, so muss man sich einen Ordner erstellen, in dem man die Skripte entwickelt.

mkdir gbgclient-0.1

Dabei ist wichtig, dass man dem Namen die Versionsnummer beifügt. In diesem Ordner erstellt man nun die Shell-Skripte und Konfigurationsdateien, die man mit dem deb-Paket verteilen möchte.

Für die Erstellung unseres deb-Pakets müssen in der .bashrc zunächst zwei Umgebungsvariablen gesetzt werden:

$ cat >>~/.bashrc <<EOF
DEBEMAIL="person@company.tld"
DEBFULLNAME="Vorname Nachname"
export DEBEMAIL DEBFULLNAME
EOF
$ . ~/.bashrc

Diese Variablen werden beim Erstellen des Pakets übernommen. Jetzt müssen wir in unserem Entwicklungsordner das Grundgerüst für das Debian-Paket erzeugen.

dh_make --indep --createorig

dh_make erzeugt im Entwicklungsordner einen Unterordner debian mit vielen für den Paketbau erforderlichen Dateien. Wir müssen aber zusätzlich eine Datei namens „install“ erstellen, die festlegt, in welche Ordner auf dem Zielsystem unsere Skripte aus unserem Entwicklungsordner kopiert werden sollen.

touch debian/install
vi debian/install

In diese Datei tragen wir nun ein, wo die Dateien bei Installation des Pakets hinkopiert werden sollen. Für den „GBG-Client“ sieht das wie folgt aus:

scripts/gbgclient.sh usr/bin
scripts/delete_connections.sh usr/bin
scripts/nutzerdatenerfassung.sh usr/bin
scripts/delete_connections.py usr/bin
gdm3/PostLogin/Default etc/gdm3/PostLogin
gdm3/PostSession/Default etc/gdm3/PostSession
gdm3/PreSession/Default etc/gdm3/PreSession
updater/updater.sh usr/bin
updater/updater.desktop usr/share/applications
updater/updater.svg usr/share/icons
misc/clear_connections.desktop etc/xdg/autostart
sudoers.d/sudogbgclient etc/sudoers.d/

Ich habe im Entwicklungsordner für meine Skripte verschiedene Unterordner eingerichtet, um eine übersichtlichere Struktur zu haben.

Jetzt muss man noch in der Datei debian/control im Archivordner eine Angabe hinzufügen, damit man das Paket erfolgreich bauen kann: Das Feld „section“ muss noch gesetzt werden. Die Datei debian/control könnte in Zeile 2 zum Beispiel so aussehen:

Section: utils

Außerdem muss man jetzt noch in der Datei debian/changelog nach der Versionsnummer focal hinzufügen, wenn man das Paket für 20.04 baut:

gbgclient (0.1-1) focal; urgency=medium

Damit man das Paket bei launchpad hochladen und dort bauen lassen kann, muss man debuild jetzt mit den folgenden Parametern ausführen:

debuild -us -uc -S -sa

Möchte man das Paket lokal auf dem eigenen Entwicklungssystem bauen, so geht das mit diesem Befehl:

debuild -us -uc

Als Nächstes muss man aus dem Entwicklungsordner heraus wechseln und das Paket, genauer die Datei name-version_source.changes (in meinem Fall z. B. gbgclient_0.1-1_source.changes) signieren.

cd ../
debsign -k schlüssel_id gbgclient_0.1-1_source.changes

Dabei muss „schlüssel_id“ durch die ID des zu verwendenden OpenPGP-Schlüssels ersetzt werden. Damit man das Paket dann auf launchpad hochladen kann, muss der öffentliche Schlüssel dort natürlich auch hochgeladen werden. Im nächsten Schritt kann dann das Paket auf launchpad in das persönliche ppa hochgeladen werden. In meinem Fall sieht der Befehl so aus:

dput ppa:feschoppe/gbgclient gbgclient_0.1-1_source.changes

Nach einiger Zeit bekommt man eine Bestätigung per Mail, dass das Paket akzeptiert wurde. Nach dem Hochladen wird es auf launchpad gebaut und steht dann über das entsprechende ppa zum Download bereit. Wenn man nun an dem Paket weiterarbeitet und zum Beispiel Dateien hinzufügt oder verändert, muss man diese Änderungen mit dem folgenden Befehl in das Paket übernehmen:

dpkg-source --commit --include-removal

Danach muss man im changelog die Versionsnummer erhöhen, damit man das Paket dann als neue Version hochladen kann:

nano debian/changelog

Danach muss man es neu bauen, signieren und hochladen. Führt nun die Schülerin oder der Schüler zuhause ein Update aus, so wird die neue Version des „GBG-Clients“ installiert. Auf diese Weise kann ich nun auch bei entliehenen Laptops Konfigurationsänderungen und Ähnliches durchführen.

IServ-Linux-Client per LTSP an festplattenlose Rechner ausliefern

In diesem Blog-Artikel werde ich erläutern, wie man einen zuvor in VirtualBox über die IServ-Softwareverteilung installierten Linux-Client über einen LTSP an festplattenlose Clients ausliefert, sodass man in einem PC-Raum dann nur noch das VirtualBox-Image pflegen muss und mit den Clients keinerlei Aufwand mehr hat.

Dieser Artikel setzt voraus, dass ein LTSP mit zwei Netzwerkkarten, so wie in diesem Beitrag beschrieben, vorhanden ist.

Prinzipielle Netzwerktopologie mit einem LTSP und einem IServ-Schulserver

Diese LTSP-Installation muss man nun verändern, damit man das in VirtualBox installierte IServ-Client-Image verwenden kann. Die LTSP-Standardinstallation geht davon aus, dass die Nutzer auf dem LTSP-Server vorhanden sind und dass deren user homes über sshfs vom Server auf die Clients eingebunden werden. Das ist bei uns nicht der Fall, da die user homes auf dem IServ liegen. Aus diesem Grund muss diese Funktion des LTSP-Servers (pamltsp) deaktiviert werden. Dieses geschieht, indem man folgende leere Datei anlegt (die Ordner client und init müssen dabei erst noch manuell mit mkdir angelegt werden) und danach ltsp initrd aufruft (beides als root).

nano /etc/ltsp/client/init/54-pam.sh
ltsp initrd

Jetzt muss noch der Export der user homes über sshfs deaktiviert werden:

ltsp nfs -h1

Jetzt ist der Server vorbereitet, um unser IServ-Linux-Image auszuliefern. Es ist an der Zeit, in VirtualBox ein solches zu erstellen. Dabei ist wichtig, dass man als Festplattentyp VMDK mit fester Größe (10 GB reichen) wählt. Zudem muss man in den Netzwerkeinstellungen auswählen, dass eine Netzwerkbrücke verwendet werden soll. Die dort angezeigte MAC-Adresse kann man dann in die IServ-Geräteverwaltung eintragen und dort auswählen, dass auf dem Client Ubuntu installiert werden soll. Beim Start der virtuellen Maschine muss dann F12 gedrückt werden, um auswählen zu können, dass diese über das Netzwerk booten soll. Hat man das gemacht, so startet automatisch die Installation des Linux-Clients.

Nach der erfolgreichen Installation des Clients in VirtualBox müssen wir diesen nun noch etwas bearbeiten, damit wir ihn über unseren LTSP ausliefern können. Wenn der Client nun von einem festplattenlosen Rechner vom LTSP gestartet wird, gibt der LTSP dem Client einen neuen Hostnamen, der auf der IP-Adresse basiert, den der festplattenlose Rechner vom LTSP bekommt. Nun muss dieser Rechner beim Hochfahren mit dem jeweiligen Hostnamen der IServ-Domäne beitreten, andernfalls ist er nicht nutzbar und man kann sich nicht anmelden. Diesen Domänenbeitritt beim Hochfahren habe ich über eine systemd service unit mit dem Namen „join.service“ realisiert (als root ausführen):

nano /etc/systemd/system/join.service
[Unit]
Description=Join Domain
After=network-online.target winbind.service

[Service]
Type=simple
ExecStart=/usr/local/bin/join-domain.sh

[Install]
WantedBy=multi-user.target

Korrekte Berechtigungen setzen:

chmod 755 /etc/systemd/system/join.service

Dann muss die Unit aktiviert werden:

systemctl enable join.service 

Jetzt muss das eigentliche Skript angelegt werden, was den Domänenbeitritt bewerkstelligt:

nano /usr/local/bin/join-domain.sh
#!/bin/sh
echo -n 'passwd' | net rpc join -U administrator

Dieses Skript enthält das Passwort eines IServ-Domänen-Administrators im Klartext, was natürlich unschön ist. Leider habe ich noch keine andere Möglichkeit gefunden, um diesen Domänenbeitritt anders zu bewerkstelligen. „administrator“ ist hier durch den Benutzernamen eines IServ-Domänen-Administrators zu ersetzen. Da dieses Skript das Passwort des Domänen-Administrators enthält, ist es um so wichtiger, die Berechtigungen so zu setzen, dass nur root dieses Skript lesen kann:

chmod 700 /usr/local/bin/join-domain.sh

Normale Nutzer können das Skript nicht lesen oder ausführen. Ferner ist es nur im VirtualBox-Client-Image vorhanden, was auf dem Server liegt. Ein Angriffsszenario, bei dem beispielsweise Linux im Single User Mode gestartet wird, ist auch nicht möglich, da die Clients keine Festplatten haben.

Jetzt ist die virtuelle Maschine fertig vorbereitet und sie kann heruntergefahren und auf den LTSP kopiert werden (z. B. per scp). Nach dem Kopieren der Datei „TestClient5-flat.vmdk“ auf den LTSP muss man folgende Befehle ausführen:

ln -s "/home/user/TestClient5-flat.vmdk" /srv/ltsp/TestClient5.img
ltsp image TestClient5
ltsp ipxe
ltsp initrd

Wenn man jetzt einen Client, der mit der internen Netzwerkkarte des LTSP verbunden ist, über pxe-Boot startet, sollte man „TestClient5“ im pxe-Menü auswählen und den Client starten können. Jetzt hat man einen normalen IServ-Linux-Client, der per pxe-Boot über den LTSP ausgeliefert wird. Damit gehört das umständliche Installieren und Aktualisieren aller Clients der Vergangenheit an, da nur noch das VirtualBox-Image gepflegt werden muss. Nach jedem Update des Image muss dieses wieder auf den LTSP kopiert und „ltsp image TestClient5“ ausgeführt werden.

Installation von LTSP 19.08

Da die neue LTSP Version 19.08, die in den Sommerferien im Rahmen des Google Summer of Code vollständig von Grund auf neu geschrieben wurde, viele Neuerungen bietet, habe ich mich entschlossen, sie in einer virtuellen Maschine auszuprobieren. Besonders reizvoll ist die Neuerung, dass man in 19.08 verschiedene Images auf dem Server zum Booten für die Clients zur Auswahl stellen kann. Es ist sogar möglich, von virtuellen Festplattenabbildern (vmdk) zu booten. Das ermöglicht es, dass man ein Schulsystem in VirtualBox pflegt und dieses dann den Clients über den LTSP zur Verfügung stellt.

Im Folgenden beschreibe ich die zur Installation erforderlichen Schritte. Diese Beschreibung basiert auf einer normalen Desktop-Installation von Ubuntu Mate 18.04 LTS.

Als ersten Schritt muss man die Netzwerkkarten so konfigurieren, dass eine Netzwerkkarte per DHCP bedient wird und dass die andere Netzwerkkarte eine feste IP zugewiesen bekommt. Über diese zweite Netzwerkkarte wird der Server dann die Clients bedienen.

sudo nano /etc/network/interfaces

Die Konfigurationsdatei /etc/network/interfaces sollte wie folgt aussehen. Dabei können die Netzwerkkarten anders heißen als in meinem Beispiel.

auto lo
iface lo inet loopback

auto enp0s3
iface enp0s3 inet dhcp

auto enp0s8
iface enp0s8 inet static
    address 192.168.67.1
    netmask 255.255.255.0
    broadcast 192.168.67.255

Nach diesen Änderungen sollte der Systemdienst, der für die Netzwerkkommunikation verantwortlich ist, neugestartet werden, damit die Änderungen sofort wirksam werden.

sudo systemctl restart networking.service

Im nächsten Schritt müssen einige Pakete entfernt werden, die Probleme verursachen.

sudo apt purge --yes --auto-remove indicator-application mate-hud snapd

Synaptic muss installiert werden.

sudo apt install --yes synaptic

Im nächsten Schritt muss das PPA der LTSP-Entwickler hinzugefügt werden, damit man die aktuellen Pakete erhält. In den Ubuntu-Paketquellen sind derzeit noch die alten Pakete enthalten.

sudo add-apt-repository ppa:ltsp
sudo apt update

Jetzt können die für den Betrieb des LTSP erforderlichen Pakete installiert werden.

sudo apt install ltsp dnsmasq nfs-kernel-server openssh-server squashfs-tools ethtool net-tools epoptes

Der nächste Befehl ermöglicht es dem Systemadministrator, das Monitoring-Tool epotes auszuführen. „administrator“ muss dabei durch den Benutzernamen des LTSP-Admins ersetzt werden.

sudo gpasswd -a administrator epoptes

Der nächste Befehl konfiguriert den LTSP so, dass er auf der internen Netzwerkkarte als DHCP-Server arbeitet und die Clients mit den Images versorgt. Das ist an dieser Stelle eine gewaltige Vereinfachung, weil kein umständliches Bearbeiten von Konfigurationsdateien mehr erforderlich ist.

sudo ltsp dnsmasq --proxy-dhcp=0

Der nächste Befehl erzeugt aus dem Server-Wurzel-Verzeichnis ein bootbares Images für die Clients. Das System, was an die Clients ausgeliefert wird, entspricht also in dieser Konfiguration dem System des Servers. An dieser Stelle wäre es jetzt aber auch möglich, aus einem virtuellen Festplattenabbild (vmdk) ein bootbares Image zu erzeugen. Wie das geht, werde ich ein anderes Mal beschreiben.

sudo ltsp image /

Im nächsten Schritt erzeugt man einen Eintrag für das PXE-Startmenü.

sudo ltsp ipxe

Der nächste Befehl konfiguriert den Server so, dass er das neu erzeugte Image per nfs an die Clients ausliefert.

sudo ltsp nfs

Schließlich wird die initial ramdisk zum Booten erzeugt:

sudo ltsp initrd

Folgendes Skript richtet das Routing vom internen Netz ins externe Netz ein:

#!/bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -P FORWARD ACCEPT
iptables --table nat --append POSTROUTING --jump MASQUERADE --source 192.168.67.0/24

Soll der LTSP 19.08 in die IServ-Domäne aufgenommen werden, geht dieses auch. Leider funktioniert dieses nicht mehr so, wie in der Version LTSP5. Mir ist es dennoch gelungen, den LTSP Server in die IServ-Domäne aufzunehmen und für die Nutzerauthentifizierung zu nutzen. Wie das genau geht, darüber werde ich in meinem Blog noch berichten.

Zentrales Management von Desktop-Clients mit einem Linux-Terminalserver

Ungeachtet der vielen mobilen Endgeräte und dem Wunsch, flexibel mit einem mobilen Gerät arbeiten zu können, haben bei uns in der Schule die Desktop-Clients noch längst nicht ausgedient. Um die Administration wesentlich zu vereinfachen, haben wir uns vor eineinhalb Jahren entschieden, auf festplattenlose Fat-Clients mit einem Linux-Terminalserver zu setzen.

In diesem Blog-Beitrag werde ich die Installation eines solchen Systems in Verbindung mit dem IServ-Schulserver beschreiben. Meine Anleitung bezieht sich auf LTSP5. Diesen Sommer wurde das LTSP-Projekt von Grund auf neu programmiert.

Wir nutzen aber weiterhin die alte Version, da jetzt alles geschmeidig läuft. Nichtsdestotrotz bietet die neue Version viele Verbesserungen. Deswegen werden wir nächstes Jahr umsteigen und ich werde alles hier dokumentieren.

Diese Anleitung bezieht sich auf Ubuntu Mate 18.04 LTS (Bionic) und einen Server mit zwei Netzwerkkarten (eno1 und eno2).

Der Ubuntu-LTSP-Server in Raum 501 stellt für die dort vorhanden Computer („Clients“) ein Festplattenabbild über das Netzwerk zur Verfügung, von dem die Clients starten. Auf diese Weise benötigen die Clients keine eigene Festplatte mehr und der Wartungsaufwand reduziert sich auf die Aktualisierung des Festplattenabbildes auf dem Server. Zudem können neue Clients direkt und ohne Installationsaufwand in das bestehende Netzwerk integriert werden.
Die Clients im Raum 501 befinden sich in einem eigenen Subnetz, was von der internen Netzwerkkarte des Servers bedient wird. Auf dem Server läuft ein DHCP-Server, der den Clients IP-Adressen sowie das Festplattenabbild zum Starten des Betriebssystems zur Verfügung stellt. Ferner arbeitet der Server als Router in das IServ-Netzwerk, sodass ein Zugriff auf dieses sowie auf das Internet möglich ist. Bei der Benutzeranmeldung an einem Client erfolgt eine Authentifizierung über ssh am Server und es wird das Heimatverzeichnis des Nutzers per sshfs eingebunden.

Netzwerktopologie unserer LTSP-Installation

Installation des Grundsystems

Als erstes muss das Grundbetriebssystem Ubuntu Mate 18.04 LTS installiert werden. Von diesem System wird später das Festplattenabbild erstellt, mit dem die Clients starten werden. Dieses bedeutet, dass das Betriebssystem von Server und Clients dasselbe ist. Alle Programme, die auf den Clients verfügbar sein sollen, müssen somit immer zuerst auf dem Server installiert werden. Die Installation des Grundbetriebssystems kann beispielsweise von einem USB-Stick erfolgen. Da es sich hierbei um eine Standardinstallation handelt, wird diese in diesem Handbuch nicht weiter dokumentiert.
Im nächsten Schritt müssen die Netzwerkkarten entsprechend unserer Anforderungen konfiguriert werden. Dieses geschieht bei Ubuntu durch das Bearbeiten der Konfigurationsdatei /etc/network/interfaces mit einem Texteditor mit root-Rechten.

sudo nano /etc/network/interfaces

Die Datei muss so angepasst werden, dass eine Netzwerkkarte (in unserem Fall eno1) die IP-Adresse dynamisch per DHCP von dem IServ-DHCP-Server bezieht. Die andere Netzwerkkarte benötigt eine statische IP-Adresse (in unserem Fall eno2). Auf dieser wird dann der interne DHCP-Server „lauschen“ und IP-Adressen sowie das Festplattenabbild an die mit dieser Netzwerkkarte verbundenen Clients verteilen. Diese Konfiguration wird bei unserem Server mit folgender Konfiguration von /etc/network/interfaces erreicht.

auto lo
iface lo inet loopback

auto eno1
iface eno1 inet dhcp

auto eno2
iface eno2 inet static
    address 192.168.0.1
    netmask 255.255.255.0
    broadcast 192.168.0.255

Nach diesen Änderungen sollte der Systemdienst, der für die Netzwerkkommunikation verantwortlich ist, neugestartet werden, damit die Änderungen sofort wirksam werden.

sudo systemctl restart networking.service

Nach der Konfiguration der beiden Netzwerkkarten muss der LTSP-Server installiert werden, der die Programme bereitstellt, die für die Erstellung und Auslieferung des Festplattenabbildes an die Clients verantwortlich sind. Mit folgenden Befehl werden die hierfür erforderlichen Programme installiert.

sudo apt-get install ltsp-server-standalone isc-dhcp-server tftpd-hpa ltsp-client ldm-ubuntu-theme

Im nächsten Schritt muss der interne DHCP-Server so konfiguriert werden, dass er das gewünschte Verhalten zeigt. Als erstes muss dem DHCP-Server mitgeteilt werden, auf welcher Netzwerkkarte er IP-Adressen verteilen soll. Dieses geschieht durch Bearbeiten der Konfigurationsdatei /etc/default/isc-dhcp-server. In dieser Datei muss folgende Bedingung eingetragen werden, damit der DHCP-Server auf der Netzwerkkarte eno2 arbeitet.

INTERFACESv4="eno2"

Für die weitere Konfiguration muss die Datei /etc/ltsp/dhcpd.conf bearbeitet werden.

#
# Default LTSP dhcpd.conf config file.
#

authoritative;

subnet 192.168.0.0 netmask 255.255.255.0 {
    range 192.168.0.100 192.168.0.250;
    option domain-name "501.ltsp";
    option domain-name-servers 10.0.0.1;
    option broadcast-address 192.168.0.255;
    option routers 192.168.0.1;
    next-server 192.168.0.1;
#    get-lease-hostnames true;
    option subnet-mask 255.255.255.0;
    option root-path "/opt/ltsp/amd64";
    if substring( option vendor-class-identifier, 0, 9 ) = "PXEClient" {
        filename "/ltsp/amd64/pxelinux.0";
    } else {
        filename "/ltsp/amd64/nbi.img";
    }
}

Nach diesen Änderungen muss der DHCP-Server neugestartet werden, damit die Änderungen sofort wirksam werden.

sudo systemctl restart isc-dhcp-server.service

Jetzt ist das Netzwerk eingerichtet und Clients, die mit der internen Netzwerkkarte des Servers verbunden sind, sollten eine IP-Adresse bekommen. Als nächster Schritt muss das Festplattenabbild erzeugt werden, von dem die Clients starten sollen. Hierfür muss als erstes ein LTSP-Kernel-Update durchgeführt werden.

sudo /usr/share/ltsp/update-kernels

Als nächstes muss das Festplattenabbild erzeugt werden. Je nach Prozessorleistung des Servers und Größe des Abbilds kann dieses mehrere Minuten dauern.

sudo ltsp-update-image --cleanup /

Um Probleme zu vermeiden, sollte an dieser Stelle der nbd-Server neugestartet werden, der die Aufgabe hat, das Festplattenabbild für die Clients zur Verfügung zu stellen.

sudo systemctl restart nbd-server.service

Jetzt bekommen mit der internen Netzwerkkarte des Servers verbundene Clients nicht nur eine IP-Adresse, sondern sie sollten auch mit dem soeben erzeugten Festplattenabbild starten. Allerdings wird man mit den Clients zu diesem Zeitpunkt noch nicht ins Internet kommen, weil der Server noch nicht so konfiguriert ist, dass er Datenpakete von den Clients in das IServ-Netz weiterleitet.

Einrichtung des Servers als Router

In der Konfigurationsdatei /etc/sysctl.conf muss folgende Zeile hinzugefügt werden, die dafür sorgt, dass Datenpakete weitergeleitet werden.

net.ipv4.ip_forward=1

Diese Änderung ist erst nach einem Neustart wirksam. Mit folgendem Befehl kann man das Verhalten aber dennoch sofort erzielen.

sudo sysctl -w net.ipv4.ip_forward=1

Als nächstes muss NAT aktiviert werden. Dieses geschieht mit dem folgenden Befehl.

sudo iptables --table nat --append POSTROUTING --jump MASQUERADE  --source 192.168.0.0/24

Um NAT permanent zu aktivieren, müssen wir diese Konfiguration in der Textdatei /etc/ltsp/nat hinterlegen.

sudo sh -c 'iptables-save > /etc/ltsp/nat'

Im folgenden Schritt müssen wir die NAT-Konfiguration in der Datei /etc/network/interfaces für die entsprechende Netzwerkkarte hinterlegen. Dieses geschieht, in dem die folgende Zeile für eno2 als letzte Zeile ergänzt wird.

up iptables-restore < /etc/ltsp/nat

An dieser Stelle sollte nochmals der Netzwerkdienst neugestartet werden.

sudo systemctl restart networking.service

Um sicherzugehen, dass alle Dienste mit der richtigen Konfiguration laufen, kann man aber auch einfach einen kompletten Neustart des Servers durchführen.

sudo reboot

Einrichtung der Anmeldung mit der IServ-Kennung

Damit man sich einfach mit der IServ-Kennung an einem Client anmelden kann, muss man am Server die Benutzerauthentifizierung an der Samba-Domäne „SCHULE“ einrichten. Hierfür müssen zunächst folgende Pakete installiert werden.

sudo apt-get install winbind libpam-winbind libnss-winbind cifs-utils libpam-mount

Als nächstes muss der LTSP-Server der Domäne „SCHULE“ beitreten.

net rpc join -U benutzername

Hierbei ist „benutzername“ durch den Benutzernamen eines IServ-Domänen-Administrators zu ersetzen. Bei dem Beitritt zur Domäne wird das Passwort des IServ-Domänen-Administrators abgefragt. Als nächstes ist die Konfigurationsdatei /etc/samba/smb.conf wie folgt zu bearbeiten.

[global]
workgroup = SCHULE
security = DOMAIN
os level = 0
local master = No
domain master = No
template homedir = /home/%U
template shell = /bin/bash
winbind separator = +
winbind cache time = 10
winbind enum users = Yes
winbind enum groups = Yes
winbind use default domain = Yes
idmap config * : range = 10000-20000
idmap config * : backend = tdb

Im folgenden Schritt ist in der Datei /etc/nsswitch.conf in den Zeilen, die mit „passwd:“ sowie mit „group“ beginnen noch „winbind“ als letzter Eintrag zu ergänzen. In der Konfigurationsdatei /etc/security/pam_mount.conf.xml muss noch festgelegt werden, wie die Samba-Shares eingebunden werden sollen. Dafür müssen die folgenden Zeilen in /etc/security/pam_mount.conf.xml direkt nach „<!– Volume definitions –>“ eingefügt werden.

<volume uid="10000-20000" fstype="cifs" server="iserv" path="home" mountpoint="/home/%(USER)/Files" options="iocharset=utf8,dir_mode=0700"/>
<volume uid="10000-20000" fstype="cifs" server="iserv" path="groups" mountpoint="/home/%(USER)/Groups" options="iocharset=utf8,dir_mode=0700"/>

Um die Änderungen wirksam werden zu lassen, muss winbind neugestartet werden.

sudo systemctl restart windbind.service

Nach diesen paar kleinen Schritten hat man einen LTSP-Server mit Fat-Clients, an denen man sich mit der IServ-Kennung anmelden und die Netzwerklaufwerke mit Samba nutzen kann.

Aktuellere Software

Um aktuellere Software als die aus den Ubuntu-Paketquellen zu erhalten, ist es empfehlenswert das Repository des „Hellenic Schools Technical Support Team“ zu den Paketquellen hinzuzufügen. Dieses wird sehr gut gewartet und Bugs werden schnell durch entsprechende Updates behoben.

sudo add-apt-repository ppa:ts.sch.gr/ppa
sudo apt-get update

Update des Images

Um das Festplattenimage zu aktualisieren, aktualisiert man zunächst den Server.

sudo apt-get update
sudo apt-get dist-upgrade

Falls im Rahmen der Updates ein Kernel-Update eingespielt wurde, muss man auch ein Kernel-Update im LTSP-Verzeichnis durchführen:

sudo /usr/share/ltsp/update-kernels

Jetzt kann man das Image neu erzeugen:

sudo ltsp-update-image --cleanup /

Schließlich sollte man noch den NBD-Server neustarten, um Probleme zu vermeiden:

sudo systemctl restart nbd-server.service

Management von Clients mit Ansible

Zur Verwaltung unserer zahlreichen Linux-Notebooks verwenden wir die Open-Source-Software Ansible. Diese ermöglicht uns eine extrem leichte Softwareverteilung, eine Ad-hoc-Kommando-Ausführung auf allen unseren Clients sowie ein einfaches Konfigurationsmanagement. Ansible verwaltet Netzwerkcomputer über SSH und erfordert keinerlei zusätzliche Software auf dem zu verwaltenden System. Ansible kann sogar Windows-Clients managen.

Ansible lässt sich bei Ubuntu sowie Debian ganz bequem über die Paketquellen installieren:

sudo apt install ansible

Damit sich Ansible auf den Client-Systemen anmelden kann, benötigt man einen ssh-Schlüssel, den man mit dem folgenden Befehl erstellt:

ssh-keygen -b 4096

Nach der Erstellung muss dieser Schlüssel auf die Clients kopiert werden, die verwaltet werden sollen. Dieses geschieht mit dem folgenden Befehl:

ssh-copy-id -i .ssh/id_rsa.pub benutzer@IP-Adresse

Dabei muss „benutzer“ durch den Benutzernamen ersetzt werden, unter dem Ansible laufen soll und zudem muss „IP-Adresse“ durch die korrekte IP-Adresse des Clients ersetzt werden. Nach der Verteilung des öffentlichen ssh-Schlüssels an die Clients müssen diese in die Datei /etc/ansible/hosts eingetragen werden. Es folgt ein Beispiel für unsere Roboter-AG-Laptops:

[RoboLaptops]
10.1.11.1
10.1.11.2

Ad-hoc-Kommando-Ausführung auf den Clients

Nachdem alle Clients, die verwaltet werden sollen, in die Datei /etc/ansible/hosts eingetragen und der öffentliche ssh-Schlüssel auf die Geräte übertragen wurde, kann man Ansible testen und einen Befehl auf allen Clients einer Gruppe (z.B. „RoboLaptops“) ausführen:

ansible RoboLaptops -u benutzer -a "shutdown -h now"

Dieses Kommando führt nun auf allen entsprechenden Geräten, die der Gruppe „RoboLaptops“ angehören, den Befehl „shutdown -h now“ aus und fährt die Geräte somit herunter. Zum Herunterfahren sind allerdings root-Privilegien erforderlich, weswegen der Befehl, so wie angegeben, nur funktioniert, wenn der Benutzer root ist.

Nutzung von „playbooks“

Damit man nicht immer einzelne Befehle eingeben muss, die dann auf allen Clients ausgeführt werden, gibt es sogenannte „playbooks“. Dabei handelt es sich um eine YAML-Datei, die die zu erreichende Konfiguration und Befehlsabfolge auf den Clients beschreibt. Die folgende Datei „e31.yml“ sorgt dafür, dass alle Clients im PC-Raum E31 die Paketquellen aktualisieren, alle verfügbaren Updates installieren und nicht mehr benötige Abhängigkeiten entfernen:

---
- hosts: E31
  remote_user: root
  tasks:
  - name: Run the equivalent of "apt-get update" as a separate step
    apt:
     update_cache: yes
  - name: Update all packages to the latest version
    apt:
     upgrade: dist
     dpkg_options: 'force-confold,force-confdef'
  - name: Remove dependencies that are no longer required
    apt:
     autoremove: yes

Meine Playbooks sind bei github verfügbar:

https://github.com/feschoppe/ansible-manage-ubuntu-clients

Das Ringen amerikanischer Großkonzerne um die Vorherrschaft im Klassenraum

Microsoft bietet sein Office-Paket „Office 365“ als Webversion für Schülerinnen und Schüler sowie für Lehrkräfte kostenlos an. Google stellt mit seiner Software „Google Classroom“ ebenfalls eine für Schulen kostenlose Internetplattform zur Erstellung von Dokumenten und zum gegenseitigen Austausch zur Verfügung. Apple versucht mit seinem vor wenigen Tagen vorgestellten neuen preiswerten 9,7″ iPad ebenfalls auf dem Bildungsmarkt Fuß zu fassen.

Diese amerikanischen Großkonzerne bieten mitnichten ihre Dienstleistungen aus reinem Interesse an digitaler Bildung kostenlos an, sondern sie sind in erster Linie darauf bedacht, möglichst früh neue Nutzerinnen und Nutzer zu gewinnen, die dann aus Bequemlichkeit der Software, mit der sie als erstes gearbeitet haben, ein Leben lang treu bleiben.

Die amerikanische Journalistin Natasha Singer bringt dieses in ihrem am 13. Mai 2017 in der New York Times erschienenen Artikel „How Google Took Over the Classroom“ pointiert auf den Punkt, in dem sie die Nutzung der Google Dienste mit folgenden Worten kommentiert:

„Schools may be giving Google more than they are getting: generations of future customers“.

In Deutschland ist die Nutzung von Google Classroom noch wenig verbreitet, dafür besteht, wie die ARD-Dokumentation „Das Microsoft-Dilemma“ (abrufbar bis zum 19.05.2018) hervorragend zeigt, eine große und einseitige Abhängigkeit von Microsoft.

Im Bereich des mobilen Lernens besteht derzeit die große Gefahr, dass sich Schulen in Deutschland in eine ähnliche Abhängigkeit von Apple begeben. Zumal Medienkompetenz vielfach in der Medienberichterstattung und bedauerlicherweise auch bei Schulträgern, Medienzentren und sogar an Schulen mit der Einführung von iPad-Klassen gleichgesetzt wird.

Wir sollten an unseren Schulen nicht das Ziel haben, unsere Schülerinnen und Schüler zu willfährigen künftigen Kunden von Microsoft, Google oder Apple zu erziehen, sondern wir sollten ihnen zeigen, dass mit Open-Source-Software eine Alternative zum herrschenden Softwareoligopol besteht. Ferner sollten wir es nicht zulassen, dass Google, Apple und Microsoft in den Schulen Daten über das Nutzungsverhalten unserer Schülerinnen und Schüler sammeln, mit denen sie dann Marketing betreiben können.

Unser „GBG-Linux“ sammelt keinerlei Daten und es stellt eine Alternative zu den Systemen von Google, Apple und Microsoft dar.

Modifiziertes Ubuntu im Laptop-Einsatz: Automatische Updates deaktivieren

Bei unseren Mobilgeräten haben die Schülerinnen und Schüler keine Möglichkeit, Programme oder Updates zu installieren. Aus diesem Grund ist es unnötig und sogar störend, wenn Ubuntu auf zur Verfügung stehende Updates hinweist.

Dieses Verhalten lässt sich ändern, wenn man die Konfigurationsdatei /etc/apt/apt.conf.d/10periodic bearbeitet. Dabei ist in der ersten Zeile die Zahl 1 zu einer 0 zu verändern:


#Alt:

APT::Periodic::Update-Package-Lists "1";

#Neu:

APT::Periodic::Update-Package-Lists "0";

Modifiziertes Ubuntu im Laptop-Einsatz: Lesezeichen für IServ-webdav-Laufwerk bei Anmeldung erstellen

Auf unseren Laptops werden keinerlei Daten dauerhaft gespeichert. Aus diesem Grund müssen die Schülerinnen und Schüler bearbeitete Dateien in der Cloud speichern. Wir nutzen an unserer Schule zurzeit den IServ-Schulserver, der es den Nutzerinnen und Nutzern ermöglicht, auf ihre Dateien über ein webdav-Laufwerk zuzugreifen.

Das Hinzufügen eines webdav-Laufwerks im Dateimanager ist für erfahrene Computernutzerinnen und -nutzer sicherlich kein Problem. Allerdings sind Einstellungen nötig, für die man genaue Informationen über die Erreichbarkeit des Speichers benötigt. Über diese Informationen verfügen Schülerinnen und Schüler in der Regel nicht. Aus diesem Grund soll nach dem Anmelden direkt ein fertig konfiguriertes Lesezeichen erstellt werden, was nur noch im Dateimanager angeklickt werden muss, um eine Verbindung herzustellen.

Hierfür benötigt man ein kleines Bash-Skript („erstelle_lesezeichen.sh“), was nach dem IServ-Benutzernamen fragt und dann das Lesezeichen passend anlegt. Dieses Skript sollte in /usr/local/bin abgelegt und ausführbar gemacht werden.


#!/bin/bash

if ! NAME=$(zenity --entry --text "IServ-Benutzername:" --title "Nutzername"); then
exit;
fi

sed "s/\__NUTZERNAME/$NAME/g" /etc/skel/.templates/bookmarks_TEMPLATE >~/.config/gtk-3.0/bookmarks

Dieses Skript erfordert eine Blanko-Lesezeichendatei („bookmarks_TEMPLATE“), die wie folgt aussehen muss und die ich in /etc/skel/.templates/ abgelegt habe:


davs://__NUTZERNAME@gbg-seelze.eu/webdav IServ

Damit das Skript zur Abfrage des Benutzernamens und zum Anlegen des Lesezeichens auch nach der Anmeldung automatisch startet, muss man hierfür in /etc/xdg/autostart/ eine *.desktop-Datei anlegen:


[Desktop Entry]
Type=Application
Name=IServ-Lesezeichen erstellen
Exec=/usr/local/bin/erstelle_lesezeichen.sh
X-GNOME-Autostart-enabled=true