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

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.

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

Modifiziertes Ubuntu im Laptop-Einsatz: Anlegen eines temporären Benutzeraccounts

Durch Anpassen von Ubuntu lassen sich die im vorangegangenen Blogbeitrag skizzierten Anforderungen an ein Mobilgerät umsetzen.

Für die Schülerinnen und Schüler wird ein Account angelegt, der bei der Anmeldung angelegt und dessen Daten nach der Abmeldung komplett gelöscht werden. Zudem werden alle Einstellungen bei der Abmeldung wieder auf die Standardwerte zurückgesetzt, sodass die Schülerinnen und Schüler die Geräte nicht „verstellen“ können. Auf diese Weise ist zudem sichergestellt, dass alle personenbezogenen Daten bei der Abmeldung vollständig gelöscht werden.

Der von Ubuntu verwendete Gnome Display Manager GDM, der die Aufgabe hat, den grafischen Anmeldebildschirm anzuzeigen und die Sitzung zu starten, lässt sich durch die Verwendung von Skripten an die eigenen Bedürfnisse anpassen. Wie dieses möglich ist, erklärt diese Seite des Gnome-Projekts:

https://help.gnome.org/admin/gdm/stable/configuration.html.en

Es besteht mithilfe dieser Skripte die Möglichkeit, ein temporäres Heimatverzeichnis für den von den Schülerinnen und Schülern verwendeten Nutzeraccount anzulegen, das nach Abmeldung wieder gelöscht wird. Hierfür muss ein PostLogin-Skript erstellt werden, das nach erfolgreicher Anmeldung ausgeführt wird. Dieses Skript hat den Dateinamen Default und muss in /etc/gdm3/PostLogin/ abgelegt werden. In unserem Fall sieht dieses Skript wie folgt aus:

#!/bin/sh
#/etc/gdm3/PostLogin/Default
guestuser="gbg"
if [[ "$USER" = "$guestuser" ]]; then mkdir /tmp/"$guestuser"
cp /etc/skel/* /tmp/"$guestuser"
chown -R "$guestuser":"$guestuser" /tmp/"$guestuser"
fi
exit 0

Dieses Skript hat die Aufgabe in /tmp/ das Heimatverzeichnis für den Nutzer „gbg“ zu erstellen, indem es das Grundgerüst für das Heimatverzeichnis aus /etc/skel/ kopiert und nach dem Kopieren den Nutzer „gbg“ zum Eigentümer seines Heimatverzeichnisses macht.

Nun muss nach dem Abmelden das Heimatverzeichnis auch wieder gelöscht und alle Einstellungen auf die Standardwerte zurückgesetzt werden. Dieses geschieht mit dem Skript Default in /etc/gdm3/PostSession/:

#!/bin/sh
#/etc/gdm3/PostSession/Default
guestuser="gbg" ## Next clear the guest user session files/folders
if [[ "$USER" = "$guestuser" ]]; then
#Löscht das Heimatverzeichnis des Nutzers
rm -rf /tmp/"$guestuser"
#Setzt alle Einstellungen auf Standardwerte zurück
dconf reset -f /
#Löscht alle W-Lan-Verbindungseinstellungen
rm /etc/NetworkManager/system-connections/*
rm /var/lib/NetworkManager/seen-bssids
rm /var/lib/NetworkManager/timestamps
#Lädt den NetworkManger neu
nmcli con reload
fi
exit 0

Dieses Skript wird, wie ich bemerkt habe, aber erst bei einem Neustart wirksam. Möchte man, dass die Dateien auch nach einfachem Ab- und wieder Anmelden, ohne dass ein Herunterfahren oder Neustart erfolgt, gelöscht werden, dann muss man in /etc/gdm3/PreSession/ ein weiteres Skript mit dem Namen Default anlegen:

#!/bin/sh
PATH="/usr/bin:$PATH"
guestuser="gbg"
if [[ "$USER" = "$guestuser" ]]; then
rm -rf /tmp/"$guestuser"
fi

Mit diesen drei Skripten erreicht man, dass Dateien über die Sitzung hinaus nicht gespeichert werden und dass das Gerät alle Einstellungen zurücksetzt. Diese Skripte setzen allerdings voraus, dass ein Benutzer existiert, der in unserem Fall „gbg“ heißt. Diesen kann man, wie folgt anlegen (die Befehle müssen als root ausgeführt werden!):

useradd -d /tmp/gbg gbg
passwd gbg
#Setzen der Gruppenzugehörigkeiten
adduser gbg dip
adduser gbg netdev
adduser gbg plugdev
adduser gbg lpadmin
adduser gbg dialout