From d1f55c48712df34d5249a4cd9f3a6fa5fa4860b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Sat, 26 Nov 2022 00:33:17 +0100 Subject: [PATCH] initial commit --- LICENSE | 29 +++++ README.md | 95 ++++++++++++++++ lib/systemd/system/guest-home@.service | 21 ++++ lib/systemd/system/guest-session@.service | 10 ++ .../systemd/scripts/guest-session-homedir.sh | 107 ++++++++++++++++++ usr/lib/systemd/scripts/guest-session.sh | 62 ++++++++++ 6 files changed, 324 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 lib/systemd/system/guest-home@.service create mode 100644 lib/systemd/system/guest-session@.service create mode 100755 usr/lib/systemd/scripts/guest-session-homedir.sh create mode 100755 usr/lib/systemd/scripts/guest-session.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..67a1326 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, Jakobus Schürz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..83ba084 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +#Gast-Zugang für Debian + +Manchmal erscheint es sinnvoll, für Gäste einen Zugang am Rechner zu haben. Alle Inhalte die ein Gast abspeichert werden nach dem ausloggen wieder gelöscht. Jeder neue Login startet mit einem vollkommen frischen Profil und Home-verzeichnis. + +Dieses Paket stellt auf einfache Weise so einen Gast-Zugang zur Verfügung. + +##Systemvoraussetzungen +Dieser Gast-Zugang ist über systemd gelöst. Dies ermöglicht es sehr einfach den Gastzugang zu aktivieren (auch mehrere), und auch wieder zu deaktivieren. +Wenn am System btrfs als Dateisystem genützt wird, wird das Home-Verzeichnis als Btrfs-Snapshot von /etc/skelXXX angelegt. Beim Ausloggen wird der gesamte Snapshot wieder gelöscht. +In GDM erscheint der Gastzugang sofort nach dem aktivieren mittels systemd + +##Aktivieren des Gastzuganges +Bei der Installation des Paketes wird automatisch ein Gastzugang aktiviert. Der Username ist "gast", das Home-Verheichnis ist /home/gast, in GDM erscheint er als "Gast". +Bei der erstmaligen Anmeldung wird das Verzeichnis /etc/skel nach /etc/skelgast dupliziert und weiter nach /home/gast. +Zur Einrichtung muss man sich einmal als Gast anmelden, den Desktop so konfigurieren, wie man ihn dem Gast zur Verfügung stellen möchte (Alias, Shortcuts, Desktop-Icons, Favoriten, Gnome3-Erweiterungen...). +Wenn der Desktop fertig eingerichtet ist, eingeloggt bleiben und als root das gesamte /home/gast nach /etc/skelgast kopieren/synchronisieren. + +Dann kann man sich als Gast wieder ausloggen. + +Möchte man einen anderen Gastzugang einrichten (zusätzlich oder anstelle), so führe man folgenden Befehl aus: + + systemctl enable --now guest-session@Zweiter\\x20Zugang.service + +Zweiter\\x20Zugang wird als Username zu zweiterzugang aufgelöst. Der doppelte Backslash "\\" ist für das Shell-Escaping notwendig! +Will man das Skelet-Verzeichnis für den ersten Gastuser auch für den zweiten verwenden so ist dieses zu duplizieren. +Ohne Btrfs mit + + cp -r /etc/skelgast /etc/skelzweiterzugang + +mit BTRFS: + + btrfs subvolume snapshot /etc/skelgast /etc/skelzweiterzugang + +Für die Anpassung des zweiten Vorlagehome-Verzeichnisses gilt das selbe wie oben beschrieben. + +## Beenden aller Userprozesse +Seit einigen Versionen von logind ist es Standard, dass logind beim ausloggen (der letzten Usersession) alle noch laufenden Prozesse des Users beendet. +Dies ist eigentlich ein gutes Verhalten, da z.B. zeitgeist-datahub oder hplip-systray weiterlaufen würden und so weitere Usersessions erzeugt würden, wenn sich ein User erneut einloggt. +Werden alle außerhalb einer Session laufenden Prozesse beendet wird auch screen oder tmux beendet. Das ist ein unerwünschtes Verhalten, deshalb wird in Debian standardmäßig diese Option wieder deaktiviert. + +Prinzipiell ist es sehr sinnvoll alle User-Prozesse beim ausloggen zu beenden (systemd-Standardverhalten), daher muss man es in Debian manuell aktivieren: + + editor /etc/systemd/logind.conf + + KillUserProcesses=yes + + +Für das Problem mit screen ist im Paket my-services eine Service-Unit für Screen, die für jene User vom Administrator aktiviert werden muss, welche screen nutzen können sollen oder wollen. + + systemctl enable --now screen@$USER.service + +Soll das Debian-Standardverhalten für die User-Sessions aber beibehalten werden, so muss für eine korrekte Funktion der Guestsession aber das Beenden aller User-Prozesse für Guest explizit erlaubt werden: + +In /etc/systemd/logind.conf ist noch wichtig folgende Zeile zu aktivieren: + + editor /etc/systemd/logind.conf + KillOnlyUsers=gast + +(das "#" am Zeilenbeginn entfernen und "gast" hinzuzufügen.) + + +##Deaktivieren des Gastzuganges +Soll dieser Gastzugang deaktiviert werden, so führt man folgende Befehle als root aus: + + systemctl stop guest-session@Gast.service + systemctl disable guest-session@Gast.service + +Für den Zweiten Zugang sinngemäß: + + systemctl stop guest-session@Zweiter\\x20Zugang.service + systemctl disable guest-session@Zweiter\\x20Zugang.service + +Die entsprechenden Usernamen sind noch in /etc/systemd/logind.conf aus KillOnlyUsers= zu entfernen. +Und wenn notwendig ist noch das Skelet-Vorlage-Home /etc/skel$USERNAME zu entfernen. + +Die Steuerungs-Files (DropIns) für das Backup sind ebenfalls zu löschen. Siehe im Punkt "Backup" + +##Backup +Wenn mkbackup-btrfs in Verwendung ist, dann kann man das Home-Verzeichnis vom Gastzugang vom Backup ausnehmen. Dies geschieht über ein Konfigurations-DropIn in /etc/mkbackup-btrfs.conf.d/ +Default wird mit der Installation dieses Paketes eine Datei im genannten Verzeichnis mit dem Namen guestsession.conf mit folgendem Inhalt angelegt: + + [DEFAULT] + ignore = +/home/gast + +Damit wird der Gastzugang von allen Interval-Snapshots ausgenommen. Das "+" am Beginn veranlasst, dass /home/gast zu allfällig bestehenden Ignore-Listen hinzugefügt wird. + +Soll das Home-Verzeichnis des zweiten Gastzuganges wie im Beispiel weiter oben beschrieben vom Backup mit mkbackup-btrfs ausgenommen werden, so lege man eine neue Datei als root mit dem Inhalt an: + + editor /etc/mkbackup-btrfs.conf.d/zweiterzugang.conf + + [DEFAULT] + ignore = +/home/zweiterzugang + + + diff --git a/lib/systemd/system/guest-home@.service b/lib/systemd/system/guest-home@.service new file mode 100644 index 0000000..ba2924f --- /dev/null +++ b/lib/systemd/system/guest-home@.service @@ -0,0 +1,21 @@ +[Unit] +Description=Create and delete $HOME for Guest-Session USER: %i +Before=user@%i.service +#BindsTo=user@%i.service guest-session@%i.service +Conflicts=shutdown.target +BindsTo=user@%i.service +#RefuseManualStart=true + +[Service] +Type=oneshot +RemainAfterExit=true +#ExecStartPre=/bin/sh -c '/bin/systemctl set-environment SKEL=/etc/skel$(/usr/bin/id -un %i)' +#ExecStartPre=/bin/sh -c '/bin/systemctl set-environment SK=$(test -e $SKEL && echo -n $SKEL || echo -n "/etc/skel")' +#ExecStartPre=/bin/sh -c '/bin/systemctl set-environment UHOME=$(getent passwd %i | cut -d: -f6)' +#ExecStartPre=/etc/systemd/system/scripts/guest-session-homedir.sh create "$SKEL" "$UHOME" +ExecStart=/usr/lib/systemd/scripts/guest-session-homedir.sh create %i +#ExecStart=/bin/chown -R %i:%i "$UHOME" +ExecStop=-/usr/lib/systemd/scripts/guest-session-homedir.sh delete %i + +[Install] +WantedBy=user@%i.service diff --git a/lib/systemd/system/guest-session@.service b/lib/systemd/system/guest-session@.service new file mode 100644 index 0000000..e59b308 --- /dev/null +++ b/lib/systemd/system/guest-session@.service @@ -0,0 +1,10 @@ +[Unit] +Description=Create guest-user (%i) and activate volatile $HOME for it + +[Service] +RemainAfterExit=true +ExecStart=/usr/lib/systemd/scripts/guest-session.sh create "%I" +ExecStop=/usr/lib/systemd/scripts/guest-session.sh delete "%I" + +[Install] +WantedBy=multi-user.target diff --git a/usr/lib/systemd/scripts/guest-session-homedir.sh b/usr/lib/systemd/scripts/guest-session-homedir.sh new file mode 100755 index 0000000..b86f60e --- /dev/null +++ b/usr/lib/systemd/scripts/guest-session-homedir.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +#create or delete volatile homedir for a guest-session depending wheter btrfs is available or not. +BTRFS="/bin/btrfs" +RSYNC="/usr/bin/rsync" +MKDIR="/bin/mkdir" +RM="/bin/rm" +CHOWN="/bin/chown" + +action=$1 +uid=$2 +gid=$(/usr/bin/id -g $uid) +skel=/etc/skel +skeldir=$(dirname $skel) +uname=$(/usr/bin/id -u -n $uid) +uskel=/etc/skel${uname} +home=$(getent passwd $uid | cut -d: -f6) +homedir=$(dirname $home) + + + +check_btrfs () { + FS=$(stat -f --format=%T "$1" 2>/dev/null ) + if [ "$FS" = "btrfs" ]; then + return 0 + else + return 1 + fi +} + +check_btrfs_subvolume () { + FS=$(stat --format=%i "$1" 2>/dev/null ) + if [ $FS -eq 256 ]; then + return 0 + else + return 1 + fi +} + + +delete_home () { + if [ -d "$home" ]; then + if check_btrfs_subvolume "$home"; then + $BTRFS subvolume delete -c "$home" + else + $RM -rf "$home" + fi + fi + return 0 +} + +create_home () { + if check_btrfs "$uskel"; then + if check_btrfs "$homedir"; then + if check_btrfs_subvolume "$uskel"; then + $BTRFS subvolume snapshot "$uskel" "$home" + else + $BTRFS subvolume create "$home" + $RSYNC -a "$uskel/" "$home" + fi + else + $MKDIR "$home" + $RSYNC -a "$uskel/" "$home" + fi + else + if check_btrfs "$homedir"; then + $BTRFS subvolume create "$home" + else + $MKDIR "$home" + fi + $RSYNC -a "$uskel/" "$home" + fi + $CHOWN -R ${uid}:${gid} $home +} + +create_skel () { + if [ -d "$uskel" ]; then + return 0 + else + if check_btrfs "$skeldir"; then + if check_btrfs_subvolume "$skel"; then + $BTRFS subvolume snapshot "$skel" "$uskel" + else + $BTRFS subvolume create "$uskel" + $RSYNC -a "$skel/" "$uskel" + fi + else + $MKDIR "$uskel" + $RSYNC -a "$skel/" "$uskel" + fi + fi + return 0 +} + +case $action in + create) + create_skel + delete_home + create_home + ;; + delete) + delete_home + ;; + *) + exit 1 + ;; +esac diff --git a/usr/lib/systemd/scripts/guest-session.sh b/usr/lib/systemd/scripts/guest-session.sh new file mode 100755 index 0000000..8755838 --- /dev/null +++ b/usr/lib/systemd/scripts/guest-session.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +ACTION=$1 +shift + +_UNAME="$@" +echo "USERNAME ${_UNAME}" +_USERNAME=$(echo "${_UNAME}"|tr '[:upper:]' '[:lower:]'|sed -e 's/ *//g' ) +_UID='' + +check () { + _UID=$(/usr/bin/id -u "$1" 2>/dev/null) + if test $? -eq 0 ; then + echo $_UID + return 0 + fi + return 1 +} + +create () { + echo $@ + if [ $# -eq 2 ]; then + echo "Create User" + /usr/sbin/adduser --no-create-home --gecos "$2" --disabled-password "$1" + _UID=$(check "$1") + /usr/bin/passwd -d "$1" + /bin/systemctl enable guest-home@${_UID}.service + return 0 + else + return 2 + fi +} + +delete () { + if [ $# -eq 1 ]; then + echo "delete $1 $2" + _UID=$(check "$1") + /bin/loginctl kill-user "$1" + /bin/systemctl disable guest-home@${_UID}.service + /usr/sbin/deluser --remove-home "$1" + return 0 + else + return 3 + fi +} + +case $ACTION in + create) + check $_USERNAME || \ + create "$_USERNAME" "$_UNAME" + ;; + delete) + check $_USERNAME && \ + delete "$_USERNAME" + ;; + *) + echo "Wrong call for guestsesseion" + exit 4 + ;; +esac + +exit $?