layout: ../../../layouts/BlogLayout.astro title: “Wie NFS Root Squash heimlich deine Datei-Timestamps kaputt macht” description: “NFS root_squash lässt chmod bei der Migration lautlos fehlschlagen. Dieser chmod-Fehler kaskadiert: Timestamps werden nie gesetzt, aber die Datei gilt als erfolgreich übertragen.” date: “2026-02-17” author: “syncopio Team” category: “Best Practices” readingTime: “5 min” slug: “nfs-root-squash-metadata-chain-reaction” locale: “de” tags: [“nfs”, “root_squash”, “permissions”, “timestamps”, “migration”, “linux”]

2.014 Dateien erfolgreich übertragen. Null Fehler im Log. Checksummen bestanden. Daten intakt.

Dann startest du die Verifizierung, und jeder einzelne Timestamp ist falsch. Nicht ein paar. Alle. Die Änderungsdaten auf dem Ziel sind der Zeitpunkt des Transfers, nicht die Originaldaten von der Quelle.

Kein Fehler. Keine Warnung. Das Tool sagte, es sei fertig. Was ist passiert?

Darf ich vorstellen: root_squash

Wenn du NFS betreibst, läuft bei dir fast sicher root_squash. Es ist der Standard auf jeder großen NFS-Server-Distribution. Die meisten Admins ändern es nie, weil die meisten Admins nie darüber nachdenken müssen.

So funktioniert es: Wenn ein Client als Root (UID 0) verbindet, mappt der NFS-Server diesen Benutzer auf nobody (UID 65534). Root auf dem Client wird nobody auf dem Server. Das ist ein Sicherheitsfeature. Ohne root_squash hätte ein Root-Benutzer auf jeder Client-Maschine Root-Zugriff auf jede Datei deines NFS-Exports.

# /etc/exports (typische NFS-Server-Konfiguration)
/srv/data  192.168.1.0/24(rw,sync,root_squash)

Dieses root_squash ist der Standard. Du musst es nicht einmal hinschreiben. Wenn deine Exports-Zeile nicht no_root_squash enthält, ist Squashing aktiv.

root_squash ist der stille Standard

Wenn deine /etc/exports nur (rw,sync) sagt, ist root_squash trotzdem aktiv. Es ist nur dann aus, wenn du explizit no_root_squash hinzufügst. Das erwischt viele Leute, weil in der Konfiguration nichts steht, das dir sagt, dass es an ist.

Die Kettenreaktion

Dein Migrationstool läuft als Root. Das ist normal. Es braucht Root, um Dateien jedes Benutzers auf der Quelle lesen zu können und um Eigentümer auf dem Ziel setzen zu können. Hier ist die Abfolge, wenn es eine Datei auf ein NFS-Ziel mit aktiviertem root_squash schreibt:

  1. Dateikopie erfolgreich. Das Schreiben der Dateidaten funktioniert. Die Datei wird als nobody:nogroup erstellt, aber die Bytes stimmen.
  2. chown erfolgreich (manchmal). Wenn das Tool den Eigentümer setzt, funktioniert das je nach Server-Konfiguration vielleicht, aber konzentrieren wir uns auf die Berechtigungen.
  3. chmod schlägt fehl. Das Tool versucht, die Berechtigungsbits zu setzen. Aber nobody ist nicht in der erwarteten Weise der Eigentümer, und der SETATTR-Aufruf liefert EPERM zurück. Operation nicht erlaubt.
  4. Das Tool loggt den Fehler und macht weiter. Die meisten Tools behandeln chmod-Fehler als nicht fatal. Die Daten wurden übertragen. Berechtigungen sind zweitrangig.
  5. chtimes wird nie ausgeführt. Hier beginnt die Kettenreaktion. Die chmod- und chtimes-Aufrufe befinden sich im selben Metadaten-Erhaltungsblock. Wenn chmod einen Fehler zurückgibt, bricht die Funktion frühzeitig ab. Der chtimes-Aufruf, der den Änderungszeitstempel setzt, steht nach dem chmod-Aufruf. Er wird nie ausgeführt.
  6. Die Datei wird als erfolgreicher Transfer gezählt.

Die Daten sind da. Die Checksumme stimmt. Das Tool markiert es als erledigt. Aber der Timestamp ist falsch, weil die einzige Funktion, die ihn setzt, durch einen Early Return einer völlig unzusammenhängenden Operation übersprungen wurde.

Die stille Kaskade

chmod-Fehler ist der Auslöser, aber Timestamp-Verlust ist die Folge. Diese beiden Operationen haben keine logische Abhängigkeit. Berechtigungen und Timestamps sind unabhängige Metadaten. Aber in den meisten Implementierungen teilen sie sich einen Fehlerpfad, sodass ein Fehler beide killt.

Warum es unsichtbar ist

Dieses Fehlverhalten hat drei Tarnschichten:

Die Daten sind korrekt. Dateigrößen stimmen überein. Checksummen bestehen. Das Wichtigste, der eigentliche Inhalt, ist in Ordnung. Jede Verifizierung, die nur die Datenintegrität prüft, gibt dir grünes Licht.

Der chmod-Fehler geht unter. Er taucht vielleicht in Debug-Logs auf. Es ist kein Transfer-Fehler. Die meisten Tools stufen ihn bestenfalls als Warnung ein. Bei einer Migration von 100.000 Dateien registrierst du 2.000 chmod-Warnungen, die mit Vollgas durchscrollen, einfach nicht.

Der Timestamp-Verlust hinterlässt keine Spur. Es gibt keinen Fehler für chtimes, weil chtimes nie lief. Du kannst nicht nach einem Fehler greppen, der nicht stattgefunden hat. Der einzige Beweis ist die Abwesenheit korrekter Timestamps auf dem Ziel — und du müsstest sie mit der Quelle vergleichen, um es zu bemerken.

Wie du es erkennst

NFS-Exports prüfen:

# Auf dem NFS-Server
cat /etc/exports

Wenn du root_squash siehst oder no_root_squash nicht siehst, ist Squashing aktiv.

In den Tool-Logs nach EPERM suchen:

grep -i "EPERM\|operation not permitted\|permission denied" /var/log/migration*.log

Wenn du chmod-Fehler auf dem NFS-Ziel siehst, sind die Timestamps mit ziemlicher Sicherheit auch falsch.

Timestamps zwischen Quelle und Ziel vergleichen:

# Schneller Stichproben-Check
stat -c '%y %n' /source/path/to/file
stat -c '%y %n' /dest/path/to/file

Wenn das Ziel das Datum deines Migrationslaufs zeigt und nicht das Originaldatum, hat es dich erwischt.

Massenvergleich:

find /source -type f -exec stat -c '%Y %n' {} \; | sort > /tmp/src-times.txt
find /dest -type f -exec stat -c '%Y %n' {} \; | sort > /tmp/dst-times.txt
diff /tmp/src-times.txt /tmp/dst-times.txt | head -20

Wenn jeder Timestamp auf der rechten Seite sich um dasselbe Datum clustert (der Tag, an dem du die Migration ausgeführt hast), ist die Kettenreaktion eingetreten.

Lösungsmöglichkeiten

Option 1: root_squash deaktivieren (Sicherheits-Tradeoff)

# /etc/exports
/srv/data  192.168.1.0/24(rw,sync,no_root_squash)

Dann exportfs -ra zum Neuladen. Das gibt dem Client-Root vollen Zugriff auf den Export. chmod funktioniert, chtimes funktioniert, alles funktioniert. Aber du hast eine Sicherheitsgrenze entfernt. Mach das nur in einem vertrauenswürdigen Netzwerk mit vertrauenswürdigen Clients, und aktiviere Squashing idealerweise wieder nach Abschluss der Migration.

Option 2: Als Nicht-Root-Benutzer mit passenden UIDs ausführen

Wenn der Benutzer, der das Migrationstool ausführt, dem Dateieigentümer auf dem NFS-Server entspricht, funktioniert chmod ohne Root. Das bedeutet:

Nicht praktikabel für die meisten Migrationen, aber gut zu wissen.

Option 3: Fehler unabhängig behandeln

Das ist der eigentliche Fix. chmod und chtimes sind unabhängige Operationen. Es gibt keinen Grund, warum ein Fehler bei einer die andere blockieren sollte. Der Code sollte:

try chmod → Fehler loggen wenn fehlgeschlagen → weiter
try chtimes → Fehler loggen wenn fehlgeschlagen → weiter
berichten, welche Metadaten-Operationen erfolgreich waren und welche nicht

So werden selbst wenn root_squash das chmod blockiert, deine Timestamps trotzdem gesetzt. Und du bekommst ein klares Log, das genau zeigt, welche Operationen fehlgeschlagen sind und welche erfolgreich waren, anstatt einer stillen Kaskade.

syncopio advantage

syncopio behandelt chmod und chtimes als unabhängige Operationen. Wenn chmod fehlschlägt (häufig bei root_squash), loggt es den Fehler und setzt trotzdem den Timestamp. Wenn chtimes fehlschlägt, wird das separat geloggt. Keine Operation kann die andere blockieren. Dein Verifizierungsbericht zeigt genau, welche Metadaten erhalten wurden und welche nicht.

Checkliste für die Post-Migration-Verifizierung

Nach jeder NFS-Migration, besonders bei Ausführung als Root:

1. Prüfe root_squash auf dem Ziel

# Auf dem NFS-Server
grep -v "^#" /etc/exports | grep -v "no_root_squash"

Wenn Ergebnisse auftauchen, ist Squashing auf diesen Exports aktiv.

2. Berechtigungen vergleichen

stat -c '%a %n' /source/somefile
stat -c '%a %n' /dest/somefile

3. Timestamps vergleichen

stat -c '%y %n' /source/somefile
stat -c '%y %n' /dest/somefile

4. Logs auf EPERM prüfen

Jedes EPERM auf dem Ziel-Mount bei Metadaten-Operationen bedeutet, dass die Kettenreaktion ausgelöst worden sein könnte.

5. Abweichungen in großem Maßstab zählen

# Dateien, bei denen der Ziel-mtime von der Quelle abweicht
paste <(find /source -type f -exec stat -c '%Y %n' {} \; | sort -k2) \
      <(find /dest -type f -exec stat -c '%Y %n' {} \; | sort -k2) \
  | awk '$1 != $3 { count++ } END { print count " timestamp mismatches" }'

Wenn diese Zahl deiner Gesamtdateianzahl entspricht, war jede Datei betroffen. Das ist die Signatur einer vollständigen Kaskade.

Prüfe vor der Migration, nicht danach

Führe einen Testtransfer von 10 Dateien auf das NFS-Ziel durch und vergleiche sofort die Timestamps. Wenn root_squash Probleme verursacht, siehst du es bei Datei Nr. 1. Finde es nicht erst nach zwei Millionen übertragenen Dateien heraus.


Weiterführende Lektüre: