Paperless Setup etwas abhärten mit folgenden Anforderungen
- NAS Administrators Gruppe hat immer Vollzugriff auf meinen paperless-office Ordner und darunter aber die Docker werden nicht mit allmächtigen Admin User ausgeführt.
- Docker wird über einen eigenen Docker User ausgeführt (mit Lese/Schreibrechten aber ohne Admin Rechten)
- Ein anderer NAS User (PC und/oder Scanner) bekommt schreibenden Zugriff auf den CONSUME Ordner aber auf nichts anderes
Folgende Probleme traten auf wenn man wie gewohnt nur über FileStation Rechte vergibt/entzieht
- Nicht immer blieben alle gesetzten Rechte erhalten beim Erstellen eines Dockerprojektes (z.B. postgres nur der User, der in der compose.yaml mit uid angegeben wurde). Es war auch ein Unterschied ob die Ordner leer oder bereits befüllt waren.
- Nur wenn ich den Administrator explizit überall berechtigte, liefen alle Container stabil obwohl eine Docker User ja nur Lese/Schreibrechte braucht.
- Es ist mühselig und fehleranfällig immer alles manuell nachzukontrollieren (zu müssen)
Eine Erklärung?
Ich vermute das Zusammenspiel von Synology und Linux. ACL werden nicht komplett durchgereicht bzw. gesetzt. Und manche Docker haben ihre eigenen Vorstellungen ob sie gewährte Rechte akzeptieren oder verändern.
Unteres Bash Script hilft
Nach Stunden des Probierens entstand ein Script, was folgendes tut:
- Sofern die nötigen Paperless Ordner nicht vorhanden sind, werden diese einmalig angelegt
- Sofern die Paperless Ordner noch leer sind, wird eine leere .keep Datei angelegt
- Rechte Reset: Sämtliche Rechte auf Ordner und Dateien werden gelöscht und dann neu gesetzt. Zuerst die Administartoren Gruppe, dann der Docker User und schließlich die SMB User (PC und Scanner)
- Alle Konsolenausgaben des letzten Durchlaufs werden parallel auch in eine Logdatei geschrieben (macht Suchen/Finden von Fehlern manchmal einfacher als das Hochscrollen in der Konsole)
Zusammenfassung
Wann das Script laufen lassen?
- Ersterstellung eines Paperless Projektes (weil es nötigen Ordner und Berechtigungen anlegt)
- Nachdem das Projekt erfolgreich erstellt/gestartet/gestoppt wurde
#!/bin/bash
# Bacardi, Version 1.3
# 1.1: Bugfix: Wegen unzureichender ACL Löschung kam es zu Mehrfach User Berechtigungen
# 1.2: Code cleanup / Code Reduzierung um 50 % (was man nach 1 Tag Abstand doch alles so sieht)
# 1.3: 2 SMB User berechtigen (Trennung Drucker und PC)
# 1.3: Scriptabbruch sobald einer der User nicht existiert
# WARNUNG! Vorher komplettes Backup der Verzeichnisse anlegen. (Nur zur Sicherheit) Diese Script ändert Berechtigungen.
# Was tut dieses Script:
# -----------------------
# Sofern die nötigen Paperless Ordner nicht vorhanden sind, werden diese einmalig angelegt
# Sofern die Paperless Ordner noch leer sind, wird eine leere .keep Datei angelegt (verhindert, daß Docker Rechte überschreibt)
# Alle Rechte werden gelöscht und sukzessive wieder gesetzt
# - Administratoren Vollzugriff
# - Docker User Lese-/Schreibrechte
# - SMB users (PC und Scanner) Leserechte auf ausschließlich! Root Ordner (damit sie überhaupt zugreifen können)
# - SMB users (PC und Scanner) Schreibrechte auf CONSUME Ordner (damit Dokumente abgelegt werden können)
# Alle Konsolenausgaben des letzten Durchlaufs werden parallel auch in eine Logdatei geschrieben (macht Suchen/Finden manchmal einfacher)
# Vorbereitung zur Ausführung des Scripts:
# ---------------------------------------
# Das Script als dateiname.sh speichern (ich habe das paperless-office Root Verzeichnis)
# Option 1: Aufgabenplaner
# - Falls noch nicht geschehen Protokoll Verzeichnis einrichten
# - Aufgabe anlegen ohne zu aktivieren und als root
# - Script in die Aufgabe kopieren
# - Aufgabe manuell ausführen
# Option 2: SSH (mag ich lieber weil man sofort den Output sieht)
# - per SSH als Admin anmelden und sudo -i (Vorsicht: Ab hier keine Befehle eingeben wo man sich nicht sicher ist was die tun)
# - Einmalig die Script Datei ausführbar machen: chmod +x dateiname.sh -> Dateiname natürlich anpassen
# - In das Speicherverzeichnis wechseln: bei mir cd /volume1/docker/paperless-office
# - Script starten: sh dateiname.sh
# - ssh ausloggen nicht vergessen mit exit
# === Konfiguration ===
BASEPATH="/volume1/docker/paperless-office" # Dein Verzeichnis wo Paperless installiert ist
DOCKERUSER="dockeruser" # Der Username des Users, den Du auf der NAS ausschließlich für das Docker Verzeichnis berechtigt hast
DOCKER_UID=1099 # zugehörig zum obigen user (per SSH anmelden und "id dockeruser" eingeben
DOCKER_GID=100 # zugehörig zum obigen User
CONSUMER_pc="bacardi" # Name des NAS Users für PC Zugriff
CONSUMER_scan="lulu" # Name des Nas User für Scanner Zugriff
REQUIRED_DIRS=(consume data export media postgres redis) # Ordner die für eine Paperless Installation nötig sind
LOGFILENAME="paperless_logfile.log" # Name der Protokolldatei, die im gleichen Verzeichnis wie das Script abgelegt wird
# === Prüfen, ob die Benutzer wirklich existieren ansonsten Abbruch ===
if ! id "$DOCKERUSER" &>/dev/null; then
echo "Fehler: Der Benutzer $DOCKERUSER existiert nicht!"
exit 1
fi
if ! id "$CONSUMER_pc" &>/dev/null; then
echo "Fehler: Der Benutzer $CONSUMER_pc existiert nicht!"
exit 1
fi
if ! id "$CONSUMER_scan" &>/dev/null; then
echo "Fehler: Der Benutzer $CONSUMER_scan existiert nicht!"
exit 1
fi
# === Pfad für Logdatei ermitteln ===
SCRIPT_DIR="$(dirname "$(realpath "$0")")" # Script Pfad
LOGFILE="$SCRIPT_DIR/$LOGFILENAME"
ERROR_FOUND=false
# === Lösche bestehende Log-Datei, falls vorhanden ===
if [ -f "$LOGFILE" ]; then
echo "Lösche bestehende Log-Datei: $LOGFILE" | tee -a "$LOGFILE"
rm "$LOGFILE"
fi
# === Ausgabe des Zeitstempels im Logfile ===
echo "Script gestartet am: $(date '+%Y-%m-%d %H:%M:%S')" | tee -a "$LOGFILE"
echo "[INFO] Starte ACL-Bereinigung & Neuvergabe für $BASEPATH" | tee -a "$LOGFILE"
# === Paperless Ordnerstruktur prüfen / vervollständigen ===
echo "[INFO] Lege fehlende Verzeichnisse an" | tee -a "$LOGFILE"
for DIR in "${REQUIRED_DIRS[@]}"; do
FULLPATH="$BASEPATH/$DIR"
if [ ! -d "$FULLPATH" ]; then
echo " → Erstelle $FULLPATH" | tee -a "$LOGFILE"
mkdir -p "$FULLPATH" 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Erstellen von $FULLPATH" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
fi
# .keep-Datei hinzufügen, um leeres Volume zu vermeiden
if [ -z "$(ls -A "$FULLPATH")" ]; then
touch "$FULLPATH/.keep" 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Erstellen der .keep Datei in $FULLPATH" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
fi
done
# === Alle ACLs rekursiv löschen ===
echo "[INFO] Entferne ACLs rekursiv" | tee -a "$LOGFILE"
find "$BASEPATH" \( -type d -o -type f \) -exec synoacltool -del {} \;
# === Setze Admin für das Root-Verzeichnis und alle Unterverzeichnisse ===
echo "[INFO] Setze Admin-ACLs für alle Verzeichnisse und Dateien" | tee -a "$LOGFILE"
find "$BASEPATH" \( -type d -o -type f \) -exec synoacltool -add {} group:administrators:allow:rwxpdDaARWcCo:fd-- \; 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Setzen der ACLs für Administratoren auf Unterverzeichnisse und Dateien" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
# === Setze Docker User für das Root-Verzeichnis und alle Unterverzeichnisse ===
echo "[INFO] Setze Docker User ACLs für alle Verzeichnisse und Dateien" | tee -a "$LOGFILE"
find "$BASEPATH" \( -type d -o -type f \) -exec synoacltool -add {} user:$DOCKERUSER:allow:rwxpdDaARWcxo:fd-- \; 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Setzen der ACLs für Docker User auf Unterverzeichnisse und Dateien" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
# === Setze SMB User Leserechte auf Paperless Root Verzeichnis ===
synoacltool -add "$BASEPATH" user:$CONSUMER_pc:allow:rx:fd-- 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Setzen der ACLs für $CONSUMER_pc auf $BASEPATH" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
synoacltool -add "$BASEPATH" user:$CONSUMER_scan:allow:rx:fd-- 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Setzen der ACLs für $CONSUMER_scan auf $BASEPATH" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
# === Setze SMB User Schreibrechte auf CONSUME ===
CONSUMEPATH="$BASEPATH/consume"
echo "[INFO] Setze SMB-User ($CONSUMER_pc) Rechte für $CONSUMEPATH" | tee -a "$LOGFILE"
synoacltool -add "$CONSUMEPATH" user:$CONSUMER_pc:allow:rwxpdDaARWcxo:fd-- 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Setzen der ACLs für $CONSUMER_pc auf $CONSUMEPATH" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
synoacltool -add "$CONSUMEPATH" user:$CONSUMER_scan:allow:rwxpdDaARWcxo:fd-- 2>&1 | tee -a "$LOGFILE" || { echo "[ERROR] Fehler beim Setzen der ACLs für $CONSUMER_scan auf $CONSUMEPATH" | tee -a "$LOGFILE"; ERROR_FOUND=true; }
# === Abschluss ===
echo "" # kosmetische Leerzeile
echo "" # kosmetische Leerzeile
if [ "$ERROR_FOUND" = true ]; then
echo "[FEHLER] Es wurden Fehler während der ACL-Bearbeitung gefunden. Kontrolliere obige Ausgabe!" | tee -a "$LOGFILE"
else
echo "[OK - FERTIG] ACLs gesetzt wie gewünscht:" | tee -a "$LOGFILE"
echo " → Administrator: Vollzugriff" | tee -a "$LOGFILE"
echo " → Docker User ($DOCKERUSER): Vollzugriff ohne Adminrechte" | tee -a "$LOGFILE"
echo " → SMB User ($CONSUMER_pc): Lesend, nur auf consume schreibend" | tee -a "$LOGFILE"
echo " → SMB User ($CONSUMER_scan): Lesend, nur auf consume schreibend" | tee -a "$LOGFILE"
fi
Wann das Script laufen lassen?
- Ersterstellung eines Paperless Projektes (weil es nötigen Ordner und Berechtigungen anlegt)
- Nachdem das Projekt erfolgreich erstellt/gestartet/gestoppt wurde
Anregungen, Verbesserungen oder ganz andere Ansätze sind sehr willkommen !
EDIT1:
Script Version 1.1 hinzugefügt
EDIT2:
Script Version 1.2 und Artikel etwas aufgeräumt
EDIT3
Script Version 1.3
