So, da ich keine wirklich zufriedenstellende Lösung gefunden habe, habe ich mir eine selber gebaut.
Im Prinzip funktioniert das so, dass ich mit AuFS alle Änderungen via tmpfs in den RAM schreibe, beim Logout oder Ausschalten des PCs gehen somit alle Änderungen verloren. Die grundlegenden Schritte sind folgende:
1. beim Start des Skripts wird eine Kopie des Userverzeichnisses unter /home/template/<user> angelegt. Das Verzeichnis /home/template ist nur von root betretbar und dadurch von Manipulationen des Users sicher.
2. es wird zusätzlich zum Homeverzeichnis /home/<user> ein "Arbeitsverzeichnis" unter /home/<user>_working angelegt. Unter /home/<user>_working wird ein tmpfs gemountet. D.h., dass alles was darin geschrieben wird landet im RAM.
3. wird mit dem Layer FS AuFS nun das Template als readonly mit dem tmpfs als writable überlagert nach /home/<user> gemountet
So werden alle Änderungen im Homeverzeichnis im RAM abgespeichert und der User kann nichts permanent verändern oder abspeichern!
Das folgende Skript übernimmt alle nötigen Konfigurationen und trägt die mounts direkt in die fstab ein. Verschlüsselte Homeverzeichnisse habe ich nicht berücksichtigt! Das Skript verwendet zenity um grafische Abfragen und Rückmeldungen zu geben. Bis jetzt ist das Skript nur für Gnome ausgelegt. Da ich beim Logout die /etc/gdm/PostSession/Default verwende um das tmpfs zu löschen. Aber es sollte sowas auch für KDE geben, wenn jemand lust hat und mir die entsprechende Konfigdatei für KDE verrät baue ich das auch da ein.
#!/bin/bash
USER=""
TEMPLATEDIR="/home/template"
# Make sure only root can run our script
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
zenity --warning --text "Das Skript muss als Root ausgeführt werden!\n\"sudo $0\""
exit 1
fi
function creatingFoldersForUser() {
zenity --question --text "Es werden jetzt für den User: $USER folgende Verzeichnisse angelegt:\n ${TEMPLATEDIR}/${USER}_template\n /home/${USER}_working\nIn Verzeichnis: ${TEMPLATEDIR}/${USER}_template befindet sich nun das Template des Users.\n\n\nMöchten Sie fortfahren?"
abort $? && exit 1;
# Creating template directory
if [ ! -d $TEMPLATEDIR ]; then
mkdir -p $TEMPLATEDIR
chmod 700 $TEMPLATEDIR
fi
# Saving actual state
mv /home/$USER ${TEMPLATEDIR}/${USER}_template
mkdir /home/$USER/
chown ${USER}:${USER} /home/${USER}
# Adding working directory, for write operations
mkdir -p /home/${USER}_working
chown ${USER}:${USER} /home/${USER}_working
# placing logout script
#!/bin/bash
echo " #!/bin/bash
umount /home/${USER}
umount /home/${USER}_working
mount /home/${USER}_working
mount /home/${USER}
exit 0
" > ${TEMPLATEDIR}/${USER}_template/reset_home.sh
chmod +x ${TEMPLATEDIR}/${USER}_template/reset_home.sh
}
function addingLogoutStatement() {
FILE_BACK="Default_`date +\"%d.%m.%y_%s\"`";
cp /etc/gdm/PostSession/Default /etc/gdm/PostSession/${FILE_BACK}
sed s/"exit 0"//g -i /etc/gdm/PostSession/Default
echo "if [ \${USERNAME} = '${USER}' ]; then
${TEMPLATEDIR}/${USER}_template/reset_home.sh
fi
exit 0" | tee -a /etc/gdm/PostSession/Default
}
function settingFstabEntries() {
FILE_BACK="/etc/fstab_`date +\"%d.%m.%y_%s\"`";
cp /etc/fstab ${FILE_BACK}
# first entry sets up a ramdisk, so nothing is written on disk"
# second entry overlays /home/$USER with read only template and the ramdisk under /home/${USER}_working
echo "none /home/${USER}_working tmpfs size=1G,auto,user,users,owner 0 0
none /home/${USER} aufs br=/home/${USER}_working:${TEMPLATEDIR}/${USER}_template/=ro,auto,user,users,owner 0 0" | tee -a /etc/fstab
mount /home/${USER}_working
mount /home/${USER}
if [ $? -gt 0 ]; then
zenity --warning --text "Achtung! Beim mounten der Verzeichnisse für den User: $USER ist ein fehler aufgetreten!\n Bitte überprüfen Sie manuell was schiefgelaufen ist. Mounten Sie die Verzeichnisse in dieser Reihenfolge:\n\"mount /home/${USER}_working\"\n\"mount /home/${USER}\""
exit 1;
fi
}
function getUser(){
HOME=`ls /home | grep -v -e "_working\|_back\|template"`
USER=`zenity --list --column "user" $HOME`
abort $? && exit 1;
}
function checkPreconditions() {
if [ ! -e /etc/gdm/PostSession/Default ]; then
zenity --warning --text "FEHLER! Keine /etc/gdm/PostSession/Default Datei gefunden. Bitte erzeugen!\n \"echo \" #!/bin/bash exit 0\" /etc/gdm/PostSession/Default\""
exit 1;
fi
if [ -n "$( grep /home/${USER}_working /etc/fstab )" ]; then
zenity --warning --text "FEHLER! Es existieren schon Einträge in der fstab für diesen User bitte entfernen Sie diese manuell!"
exit 1;
fi
if [ -z "$USER" ]; then
zenity --warning --text "FEHLER! Es muss ein Nutzernamen angegeben werden!"
exit 1;
fi
}
abort(){
if [ $1 -gt 0 ]; then
if zenity --question --text="Wollen Sie wirklich abbrechen?"; then
return 0;
else
return 1;
fi
fi
return 1;
}
zenity --question --text "Achtung! Dieses Skript nimmt Änderungen an der fstab und an der /etc/gdm/PostSession/Default vor!\nSollte das System danach nicht mehr stabil laufen, ersetzen Sie die geänderten Dateien mit den Backups, die automatisch angelegt werden!\nAchtung! Dieses Skript funktioniert nicht mit verschlüsselten Homeverzeichnissen!\n\nMöchten Sie fortfahren?"
abort $? && exit 1;
getUser
checkPreconditions
creatingFoldersForUser
addingLogoutStatement
settingFstabEntries
exit 0