Vous avez lancé rsync. Il s’est terminé. Vous vous êtes senti brièvement puissant. Puis tous les services ont commencé à échouer parce que la moitié de vos fichiers appartient maintenant au mauvais utilisateur,
ont le mauvais mode, ou ont perdu leurs ACL. La nouvelle machine Debian 13 a l’air correcte jusqu’à ce que vous essayiez de démarrer PostgreSQL, recharger nginx, ou laisser votre application écrire dans son propre cache.
Le chaos des permissions après rsync n’est que rarement « rsync qui fait n’importe quoi ». Il s’agit presque toujours de notre part à donner de mauvaises instructions, de copier à travers une frontière où
l’identité change (mappage UID/GID), ou de copier sur un système de fichiers qui ne peut pas représenter ce que vous tentez de préserver. Ce guide est la méthode propre pour préserver
la propriété sur Debian 13 — quoi faire, quoi éviter, et comment prouver que vous l’avez fait correctement.
Le modèle mental : ce que « propriété » signifie réellement
Sur Debian (et Linux en général), un fichier n’appartient pas à un « nom d’utilisateur ». Il appartient à un identifiant utilisateur numérique et à un identifiant de groupe numérique. Les noms ne sont que des étiquettes dans
/etc/passwd et /etc/group (ou LDAP/SSSD), traduites à l’affichage. Si vous copiez un fichier appartenant à l’UID 1001 depuis l’hôte A vers l’hôte B,
et que l’UID 1001 est « alice » sur l’hôte A mais « postgres » sur l’hôte B, vous venez d’assigner ce fichier à « postgres » sur l’hôte B. rsync a fait ce que vous avez demandé ; vous avez posé la mauvaise question.
La préservation de la propriété comporte trois couches :
- Bits de mode (rwx pour user/group/other plus setuid/setgid/sticky) : stockés par inode ; la plupart des systèmes de fichiers les supportent.
- Identifiants numériques propriétaire/groupe (uid/gid) : stockés par inode ; la capacité à les définir dépend des privilèges et des options de montage.
- Permissions étendues (ACL POSIX) et métadonnées (xattrs comme étiquettes SELinux, capabilities, tags user.*) : optionnelles et dépendantes du système de fichiers.
rsync peut préserver tout cela, mais seulement si vous lui dites de le faire et si la destination peut le représenter. Si vous ciblez rsync vers une destination qui ment (bonjour, certaines configurations CIFS),
ou si vous l’exécutez sans les privilèges nécessaires pour définir la propriété, vous obtiendrez un « succès » et des permissions cassées. Ce n’est pas un paradoxe ; c’est un mardi.
Playbook de diagnostic rapide
Quand les permissions « semblent incorrectes » après rsync, le chemin le plus rapide est de déterminer quelle couche a cassé : IDs, bits, ou extras. Ne devinez pas. Mesurez.
1) Première étape : confirmer ce qui ne va pas (IDs vs modes vs ACL/xattr)
- Si la propriété est incorrecte globalement : suspectez un mismatch UID/GID, un problème de privilège, ou root-squash.
- Si les modes sont incorrects (par ex. tout en 755) : suspectez umask, absence de
-p/-a, ou une destination qui normalise les permissions. - Si seules des applications spécifiques échouent (par ex. unités systemd, clés ssh, binaires) : suspectez la perte d’xattrs/capabilities, la perte de bits setuid, ou la disparition d’ACL.
2) Deuxième étape : vérifier la frontière de transport
- Disque local vers disque local : le plus simple ; rsync devrait préserver presque tout en tant que root.
- Sur SSH : cela dépend de rsync distant et des privilèges ; root-vers-root fonctionne si configuré ; sinon vous verrez des déclassements silencieux.
- NFS : root-squash va volontiers ruiner la « préservation de la propriété » sans vous le dire de façon que votre cerveau fatigué remarquera.
- CIFS/SMB : la sémantique des permissions peut être émulée ; la préservation peut être impossible ou mappée.
3) Troisième étape : reproduire sur un seul fichier avec verbosité maximale
Choisissez un fichier avec propriétaire/mode/ACL/xattr connus, rsyncez-le avec -vv, et inspectez-le aux deux extrémités. Vous cherchez précisément la classe de métadonnées qui n’a pas été transférée.
Paraphrase d’une idée de Gene Kim (auteur DevOps) : « La fiabilité vient de rendre le travail visible et reproductible, pas des exploits à 2 h du matin. »
Faits et contexte historique (pourquoi cela revient)
- UID/GID sont la source de vérité. Les noms d’utilisateur sont du sucre syntaxique ; rsync peut préserver les IDs même si le nom n’existe pas — si vous le lui demandez.
- Le mode « archive » de rsync est un paquet.
-aest un raccourci pour plusieurs options, mais pas toutes celles que les gens supposent. - Les ACL POSIX précèdent beaucoup de commodités Linux “modernes”. Elles existent depuis des décennies en Unix d’entreprise et sont arrivées dans Linux comme citoyen de première classe, mais on les oublie souvent lors des migrations.
- Les capabilities Linux sont stockées dans des xattrs. Si vous perdez les xattrs, un binaire avec
cap_net_bind_servicepeut cesser de lier le port 80 sans être setuid root. - Le root-squash NFS est hostile à la « préservation de la propriété ». C’est une mesure de sécurité qui mappe root sur nobody, ce qui casse couramment les schémas de sauvegarde/restauration naïfs.
- Les liens physiques ne sont pas « copiés » sauf si vous les préservez. Sans
-H, rsync peut dupliquer des fichiers liés, augmenter l’utilisation disque et changer la sémantique pour certains arbres gérés par paquets. - Le sticky bit et les répertoires setgid comptent pour les chemins d’écriture partagés. Copier les bits de mode incorrectement dans des lieux comme
/tmpou des répertoires de groupe partagés peut devenir un problème de sécurité, pas juste une panne. - Les labels SELinux et les métadonnées AppArmor vivent en dehors des bits de mode classiques. Même sur Debian (souvent orienté AppArmor), les xattrs peuvent importer pour les runtimes de conteneurs, les environnements type snap, ou des configurations LSM personnalisées.
- Certaines filesystems ne peuvent pas représenter les métadonnées souhaitées. FAT et exFAT sont les évidents, mais les montages CIFS peuvent être « Unixy » ou « pas Unixy » selon les options.
Ce que rsync préserve (et ce qu’il ne préserve pas)
Le premier mensonge qu’on se raconte : « J’ai utilisé -a, donc tout est identique. » Le mode archive est excellent, mais ce n’est pas « chaque bit de métadonnée dans l’univers ». Il inclut :
-rrécursif-lpréserver les liens symboliques-ppréserver les permissions (bits de mode)-tpréserver les timestamps-gpréserver le groupe-opréserver le propriétaire (require root)-Dpréserver les périphériques et spéciaux (require root)
Ce que -a n’inclut pas automatiquement :
- Les ACL sauf si vous ajoutez
-A - Les xattrs sauf si vous ajoutez
-X - Les liens physiques sauf si vous ajoutez
-H(et oui, cela peut être coûteux) - La préservation des IDs numériques à travers des services de noms différents sauf si vous ajoutez
--numeric-ids
C’est l’essentiel : si vous tenez à la propriété, vous tenez à l’identité numérique. Si vous voulez que « l’application fonctionne toujours », vous tenez aux ACL, aux xattrs, et parfois aux capabilities.
Blague #1 : rsync ne « perd » pas les permissions. Il suit les instructions avec la confiance d’un stagiaire qui ne pose jamais de questions clarificatrices.
Les lignes de commande propres pour les migrations Debian 13
Voici des valeurs par défaut opinionnées qui se comportent bien lors de vraies migrations. Ajustez-les délibérément. Si vous ne pouvez pas expliquer pourquoi vous avez retiré un drapeau, gardez-le.
Copie local vers local (même hôte, disques différents)
Si vous copiez au sein d’un seul hôte (ou vers un système de fichiers monté où vous avez de vrais privilèges root), ceci est la base propre :
cr0x@server:~$ sudo rsync -aHAX --numeric-ids --info=stats2,progress2 /src/ /dst/
...output...
Pourquoi cet ensemble :
-a: préserver les métadonnées de base-H: préserver les liens physiques (utile pour certains arbres système, couches de conteneurs, caches de paquets)-A: préserver les ACL-X: préserver les xattrs (capabilities, labels, métadonnées personnalisées)--numeric-ids: préserver les UID/GID numériques, pas les noms (critique entre hôtes)
Sur SSH, root vers root (préféré pour migrations fidèles)
cr0x@server:~$ sudo rsync -aHAX --numeric-ids --info=stats2,progress2 -e "ssh -o BatchMode=yes" /src/ root@newhost:/dst/
...output...
Si SSH root est interdit (commun et pas nécessairement mauvais), utilisez un compte d’automatisation plus sudo sur la destination et exécutez rsync en mode serveur. Cela devient nuancé.
Pour la plupart des équipes, le meilleur choix est : copier en tant que root sur SSH depuis un réseau de gestion autorisé, puis refermer l’accès.
Quand vous ne pouvez pas être root (et que vous voulez quand même des résultats sensés)
Si vous êtes non privilégié, vous ne pouvez pas définir des propriétaires arbitraires. rsync préservera ce qu’il peut. Ne prétendez pas que vous faites une migration fidèle ; traitez cela comme une copie de données
où les propriétaires devront être réaffectés après.
cr0x@server:~$ rsync -aAX --info=stats2,progress2 /src/ user@newhost:/dst/
...output...
Remarque : -o et -g inclus dans -a ne réussiront pas comme vous le voulez sans privilège. rsync s’exécutera quand même. Il ne fera pas de miracles.
Quand la destination est NFS (gérer root-squash comme un adulte)
Si l’export NFS utilise root-squash (souvent par défaut), root sur le client ne peut pas définir la propriété. Vous avez trois options propres :
- Exporter temporairement avec
no_root_squashdepuis un hôte restreint pour la fenêtre de migration (sécurisé, revu, limité dans le temps). - Migrer vers le disque local sur le serveur de destination, puis déplacer les données côté serveur (préservant la propriété localement).
- Accepter que vous ne pouvez pas préserver la propriété et planifier un chown/chgrp/réapplication des ACL contrôlée.
Tâches pratiques : commandes, sorties, décisions
Vous ne réparez pas les permissions en plissant les yeux devant ls -l et en espérant. Vous réparez les permissions en posant des questions au système et en laissant les réponses guider votre
prochaine étape. Voici des tâches pratiques que j’exécute vraiment pendant les migrations et la réponse aux incidents.
Tâche 1 : Confirmer la version de rsync et les fonctionnalités compilées (support ACL/xattr)
cr0x@server:~$ rsync --version
rsync version 3.2.7 protocol version 32
Capabilities:
64-bit files, 64-bit inums, 64-bit timestamps, ACLs, xattrs, iconv, symtimes
...output...
Ce que cela signifie : Vous cherchez ACLs et xattrs dans les capabilities. S’ils manquent, des drapeaux comme -A
et -X ne feront pas ce que vous pensez.
Décision : Si ACLs/xattrs ne sont pas supportés, mettez à jour rsync ou changez de méthode (tar avec xattrs, réplication de snapshot de filesystem, etc.).
Tâche 2 : Inspecter les métadonnées complètes d’un fichier problématique (mode, UID/GID, ACL)
cr0x@server:~$ sudo stat -c '%n mode=%a uid=%u(%U) gid=%g(%G)' /dst/app/config.yml
/dst/app/config.yml mode=640 uid=1001(alice) gid=1001(alice)
Ce que cela signifie : Les IDs numériques sont la vérité ; les noms entre parenthèses sont l’interprétation locale. Si l’UID est « correct » mais que le nom est « faux », vous avez
un problème de mappage, pas de copie.
Décision : Si les UID/GID diffèrent des attentes source, arrêtez et corrigez l’alignement d’identité avant de copier davantage.
Tâche 3 : Vérifier que les ACL existent et comparer l’accès attendu
cr0x@server:~$ sudo getfacl -p /dst/app
# file: /dst/app
# owner: 1001
# group: 1001
user::rwx
group::r-x
group:33:r-x
mask::r-x
other::---
Ce que cela signifie : Le répertoire accorde lecture/exécution au groupe 33 (souvent www-data). Si cette ACL a disparu, votre service web ne peut pas lire
l’arborescence de l’application même si les bits de mode « ont l’air corrects ».
Décision : Si les ACL manquent là où vous les attendez, vous devez relancer rsync avec -A et vous assurer que le système de fichiers de destination supporte
les ACL et qu’elles sont activées.
Tâche 4 : Vérifier les xattrs sur un fichier susceptible de porter des capabilities ou labels
cr0x@server:~$ sudo getfattr -d -m- /dst/usr/local/bin/myhelper
# file: /dst/usr/local/bin/myhelper
security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=
Ce que cela signifie : Le binaire a des capabilities Linux stockées dans un xattr. Perdez cela, et vous aurez des « permission denied » mystérieux sur des opérations privilégiées sans aucun
changement de propriétaire.
Décision : Si les xattrs manquent, recopiez avec -X. Si le système de fichiers de destination ne peut pas stocker d’xattrs, vous avez besoin d’une autre cible.
Tâche 5 : Valider que rsync s’exécute réellement en tant que root aux deux extrémités
cr0x@server:~$ sudo rsync -a --rsync-path="id && rsync" /src/ root@newhost:/dst/ 2>/dev/null | head
uid=0(root) gid=0(root) groups=0(root)
Ce que cela signifie : Le côté distant a imprimé son identité avant d’exécuter rsync. Si vous voyez un UID non-root, la préservation de la propriété sera limitée.
Décision : Si le distant n’est pas root, corrigez l’approche SSH/sudo ou acceptez une stratégie de chown post-copie.
Tâche 6 : Détecter le mismatch UID/GID entre hôtes pour un compte de service spécifique
cr0x@server:~$ getent passwd www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
cr0x@server:~$ ssh root@newhost getent passwd www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
Ce que cela signifie : Bon : UID/GID cohérents pour www-data. Mais ne vous arrêtez pas là ; vos utilisateurs applicatifs sont souvent des comptes personnalisés, pas des défauts Debian.
Décision : Si les IDs ne correspondent pas, alignez-les (préférable avant la copie) ou utilisez --numeric-ids et corrigez le service de noms ensuite.
Tâche 7 : Inventorier les propriétaires numériques « inconnus » sur la destination
cr0x@server:~$ sudo find /dst -xdev -printf '%u %g %p\n' | awk '$1 ~ /^[0-9]+$/ || $2 ~ /^[0-9]+$/' | head
1001 1001 /dst/app
1001 1001 /dst/app/config.yml
Ce que cela signifie : Propriétaires numériques sans résolution de nom. Ce n’est pas nécessairement incorrect : cela peut être une préservation numérique correcte avec des définitions de compte manquantes.
Décision : Si beaucoup d’IDs numériques apparaissent, corrigez la cohérence de /etc/passwd//etc/group (ou LDAP/SSSD) avant de laisser les services tourner.
Tâche 8 : Confirmer que les options de montage permettent les permissions POSIX et les ACL
cr0x@server:~$ mount | grep " on /dst "
/dev/sdb1 on /dst type ext4 (rw,relatime,acl)
Ce que cela signifie : ext4 monté avec le support acl. Sur certains environnements, les ACL sont activées par défaut ; sur d’autres, l’option de montage explicite compte.
Décision : Si vous ne voyez pas acl et que les ACL ne se comportent pas correctement, remontez avec ACL activé ou ajustez les paramètres du système de fichiers.
Tâche 9 : Détecter le root-squash sur un montage NFS à la dure (en essayant)
cr0x@server:~$ sudo touch /dst/.rootsquash-test && sudo chown 0:0 /dst/.rootsquash-test; ls -ln /dst/.rootsquash-test
-rw-r--r-- 1 65534 65534 0 Dec 29 12:00 /dst/.rootsquash-test
Ce que cela signifie : UID/GID sont devenus 65534 (nobody/nogroup). C’est le comportement classique du root-squash.
Décision : Arrêtez d’essayer de préserver la propriété sur ce montage. Changez la politique d’export temporairement, ou copiez côté serveur.
Tâche 10 : Exécuter un dry-run de rsync avec changements itemisés pour voir quelles métadonnées changeraient
cr0x@server:~$ sudo rsync -aHAX --numeric-ids -n -i /src/ /dst/ | head
.d..t...... ./
>f..tpogax app/config.yml
>f..t...... app/static/logo.png
Ce que cela signifie : La sortie itemisée encode les changements. Dans >f..tpogax, les lettres montrent ce qui sera mis à jour : temps (t),
perms (p), propriétaire (o), groupe (g), ACL (a), xattr (x).
Décision : Si vous voyez beaucoup de changements o/g inattendus, votre propriété n’est pas alignée ; corrigez cela avant d’exécuter.
Tâche 11 : Confirmer qu’un arbre de répertoires a les bits setgid/sticky attendus
cr0x@server:~$ sudo find /dst/shared -maxdepth 1 -type d -printf '%m %p\n'
2775 /dst/shared
2775 /dst/shared/team-a
2770 /dst/shared/private
Ce que cela signifie : Le 2 dans le chiffre initial indique setgid sur les répertoires (héritage de groupe). Si ceux-ci sont passés à 0775,
les nouveaux fichiers peuvent appartenir au mauvais groupe, provoquant des bugs d’accès à long terme.
Décision : Si les bits setgid/sticky manquent, recopiez en préservant les permissions, ou corrigez-les explicitement puis ré-auditez.
Tâche 12 : Vérifier que les « fichiers spéciaux » (périphériques, sockets) n’ont pas été abîmés
cr0x@server:~$ sudo find /dst/dev -maxdepth 1 -type c -o -type b | head
/dst/dev/null
/dst/dev/zero
/dst/dev/random
Ce que cela signifie : Les nœuds de périphériques existent. Si vous avez copié une image système ou un chroot et que ceux-ci sont devenus des fichiers ordinaires, quelque chose a très mal tourné (probablement
manque de privilèges root ou omission de -D).
Décision : Pour les arbres système, copiez toujours en tant que root avec -a. Si les périphériques sont incorrects, reconstruisez-les (ou recopiez correctement) avant de booter
ou d’exécuter le chroot.
Tâche 13 : Vérifier le symptôme « tout appartient à l’utilisateur rsync »
cr0x@server:~$ sudo find /dst -xdev -printf '%u\n' | sort | uniq -c | sort -nr | head
152340 backup
2193 root
812 www-data
Ce que cela signifie : La plupart des fichiers appartiennent à backup. Cela signifie généralement que la copie s’est faite sans privilège, ou que la destination a refusé le chown.
Décision : Si vous avez besoin de fidélité, refaites la copie avec les privilèges appropriés et une destination qui permet les changements de propriété. Ne tentez pas de « corriger plus tard »
à moins d’avoir un mappage déterministe.
Tâche 14 : Comparer rapidement propriété source et destination pour un échantillon
cr0x@server:~$ sudo (cd /src && find . -maxdepth 2 -type f -printf '%u:%g %m %p\n' | head) > /tmp/src.sample
cr0x@server:~$ sudo (cd /dst && find . -maxdepth 2 -type f -printf '%u:%g %m %p\n' | head) > /tmp/dst.sample
cr0x@server:~$ diff -u /tmp/src.sample /tmp/dst.sample
--- /tmp/src.sample
+++ /tmp/dst.sample
@@
-alice:alice 640 ./app/config.yml
+postgres:postgres 640 ./app/config.yml
Ce que cela signifie : Même mode, propriété différente. Le fichier est lisible, mais par la mauvaise identité. C’est soit un mismatch UID, soit un mappage basé sur les noms.
Décision : Utilisez --numeric-ids (ou alignez les comptes) et refaites, ou engagez une réaffectation planifiée des propriétaires.
Mismatching UID/GID : le tueur silencieux des permissions
Debian 13 n’a pas inventé le mismatch UID/GID, mais c’est un moment courant car les upgrades/migrations coïncident souvent avec des changements de services d’annuaire, l’adoption de conteneurs, ou un « on nettoiera plus tard ».
« Plus tard » est la façon d’obtenir des pannes.
Mode d’échec typique : sur l’ancien hôte, votre utilisateur applicatif est UID 1005. Sur le nouvel hôte, l’UID 1005 appartient à un autre compte de service créé précédemment. Vous rsyncez
« en préservant la propriété ». Maintenant les secrets de votre appli appartiennent à un démon non lié. L’appli ne démarrera pas, et vous avez aussi créé une fuite de privilège accidentelle.
Que faire à la place (opinionné et ennuyeux)
- Avant de copier, assurez-vous que la destination a les mêmes assignations UID/GID pour les comptes de service qui possèdent les données.
- Utilisez
--numeric-idspour que rsync ne tente pas d’être malin avec le mappage par nom. - Si vous dépendez de LDAP/SSSD, validez qu’il est opérationnel sur la destination avant de lancer la copie. Un fallback temporaire vers des utilisateurs locaux peut créer des mismatches.
Quand vous ne pouvez pas aligner les IDs
Parfois vous héritez d’un bazar : le nouvel environnement utilise une identité centralisée et l’ancien était fait à la main. Dans ce cas, ne transformez pas la « préservation de la propriété » en religion. Traitez-la comme une transformation contrôlée :
- Copiez d’abord les données avec intégrité (contenu et timestamps).
- Puis appliquez la politique de propriété/ACL de façon déterministe (scripts, manifests, ou outils applicatifs).
- Enfin, exécutez un audit des permissions et démarrez les services sous supervision.
ACL et xattrs : préserver les permissions « invisibles »
Les bits de mode constituent les premiers 80% des permissions. Les ACL et xattrs sont les 20% finaux qui causent 80% des pannes.
ACL : le piège « pourquoi www-data ne peut-il pas lire ? »
Les ACL sont couramment utilisées pour accorder à un groupe de service l’accès en lecture à des répertoires appartenant à un autre groupe, ou pour permettre aux développeurs de déployer sans rendre tout l’arbre group-writable.
Si vous les perdez, ls -l ne l’avouera pas. Vous pouvez voir un + dans certaines sorties, mais les gens l’ignorent comme ils ignorent le voyant de vérification moteur.
Préservez les ACL avec -A. Puis vérifiez avec getfacl sur quelques chemins connus. Si vous migrez des serveurs applicatifs, portez une attention spéciale à :
- répertoires d’upload partagés
- répertoires de déploiement à propriété mixte
- chemins où un utilisateur de service a besoin d’accès mais ne devrait pas posséder les fichiers
xattrs : capabilities, labels, et l’effet « mais ça marchait hier »
Les attributs étendus servent à tout, des contextes SELinux aux métadonnées définies par l’utilisateur en passant par les capabilities. Sur Debian, les capabilities sont souvent le gros point en production : elles permettent à un binaire
de binder des ports bas ou d’effectuer du raw networking sans tourner en root.
Préservez les xattrs avec -X. Puis vérifiez un binaire ou fichier connu censé porter des xattrs. Si les xattrs ne sont pas préservés, les symptômes peuvent être étranges :
services qui ne peuvent plus binder, conteneurs qui ne démarrent plus, ou comportement différent des outils de sécurité.
Frontières des systèmes de fichiers : ext4 vs XFS vs ZFS vs NFS vs CIFS
rsync ne peut préserver que ce que le système de fichiers de destination peut stocker, et ce que les options de montage vous permettent de définir. Le moyen le plus simple d’obtenir du « chaos des permissions » est de
copier d’un filesystem Unix vers quelque chose qui fait semblant d’en être un.
Systèmes de fichiers Linux locaux (ext4, XFS)
Généralement sûrs pour les bits de mode, la propriété, les ACL, les xattrs. Surveillez les options de montage. Surveillez aussi si vous copiez vers un filesystem avec un comportement ACL par défaut différent.
ZFS on Linux
ZFS supporte permissions, ACL, xattrs, mais le mode ACL peut différer (POSIX vs NFSv4 ACL). Si vous voyez une traduction d’ACL étrange, confirmez les propriétés du dataset et comment vos outils attendent les ACL.
rsync peut préserver les ACL, mais si le modèle ACL sous-jacent diffère, « préservé » peut ne pas signifier « équivalent ».
NFS
NFS est fantastique jusqu’au moment où vous voulez faire des opérations de propriété Unix depuis un client en tant que root et que le serveur dit « absolument pas ». C’est le root-squash. C’est normal.
Planifiez-le plutôt que de vous battre contre lui.
CIFS/SMB
Les montages CIFS peuvent mapper la propriété et les permissions selon les options de montage et les capacités du serveur. Certains environnements peuvent stocker les bits de mode Unix ; d’autres mappent tout à un UID/GID unique.
Si votre destination est CIFS et que vous avez besoin d’une sémantique Unix réelle, testez avec un petit jeu de fichiers avant de migrer quoi que ce soit de sérieux.
Blague #2 : les permissions CIFS sont comme les machines à café de bureau — quelqu’un jure que c’est bien configuré, puis ça fait de la bouillie.
Trois mini-histoires d’entreprise depuis le terrain
Mini-histoire 1 : l’incident causé par une mauvaise hypothèse
Une équipe a migré une flotte de serveurs applicatifs Debian vers du nouveau matériel. Le plan était propre : construire Debian 13, rsyncer les arbres applicatifs, basculer le load balancer.
Ils ont utilisé rsync -a et un compte « deploy » non-root parce que le SSH root était banni (politique raisonnable). La migration s’est terminée tôt. Tout le monde est allé déjeuner avec cette sensation d’inquiétude que l’on ignore quand le graphe est vert.
Les premiers rapports d’erreur concernaient des « 403 aléatoires » et des « uploads qui échouent ». Ils ont redémarré un serveur, même. Revenu en arrière vers l’ancien pool, tout allait bien. De retour sur le nouveau,
cassé. Les gens ont commencé à discuter de chemins réseau et règles de firewall parce que c’est ce que font les gens quand ils ne veulent pas penser aux permissions de fichiers.
Le vrai problème : des ACL étaient utilisées sur les anciens serveurs pour accorder au groupe worker web l’accès à un arbre de répertoires appartenant à un autre compte de service. L’utilisateur deploy pouvait lire les fichiers, donc rsync a copié le contenu,
mais il n’a pas préservé les ACL parce que -A n’avait pas été utilisé. Les bits de mode semblaient similaires. Les ACL manquantes ne se sont manifestées que lorsque le service web a tenté d’écrire de nouveaux objets.
La correction n’a pas été héroïque. Ils ont relancé rsync avec -aA (puis -X pour être complets) en utilisant un workflow sudo contrôlé sur la destination. Ensuite ils ont ajouté une vérification d’ACL dans le runbook de migration : choisir trois répertoires connus avec ACL, comparer la sortie de getfacl,
échouer la migration si discordance.
La mauvaise hypothèse était simple : « archive mode veut dire tout ». Archive mode veut dire « beaucoup », pas « tout ».
Mini-histoire 2 : l’optimisation qui s’est retournée contre eux
Une autre organisation avait un pipeline média volumineux déplaçant des données entre serveurs la nuit. Ils ont voulu accélérer une fenêtre rsync lente, alors ils ont retiré des flags « coûteux »
et activé des options agressives. Quelqu’un a proposé : supprimer -H et -X, et ajouter --inplace et --no-owner parce que « la propriété n’a pas d’importance pour les fichiers média ».
Ça a donné de meilleures mesures sur un dataset de laboratoire calme. Le changement est passé en production.
Deux semaines plus tard, l’utilisation disque sur la destination a explosé. Ce n’était pas un net « il nous faut plus d’espace » ; les jobs ont commencé à échouer en cours d’exécution à cause de volumes pleins, ce qui a entraîné des retards en cascade.
Les opérations ont passé une nuit à supprimer des répertoires temporaires et rejouer des jobs. Le postmortem a d’abord attribué cela à une « croissance d’entrée inattendue ». C’était réconfortant et faux.
La cause racine était les liens physiques. Certains arbres sources utilisaient des hard links pour dédupliquer des payloads identiques générés par des étapes antérieures. Supprimer -H signifiait que rsync a copié chaque fichier lié comme fichier séparé,
multipliant l’espace utilisé. Le changement de propriété a aussi supprimé un contrôle de sécurité subtil : quelques répertoires étaient protégés par des règles de propriété de groupe et setgid ; aplatir la propriété a fait que des jobs ultérieurs écrivaient là où ils ne devaient pas,
produisant un « succès » trompeur avec des sorties mal placées.
Ils ont annulé l’« optimisation », puis révisé le pipeline correctement : garder -H là où le dataset l’utilise, garder -X pour les outils portant des capabilities,
et concentrer le travail de performance sur les motifs I/O (batching, éviter les rescans inutiles) plutôt que d’enlever des flags de correction. Rapide et faux reste faux ; ça échoue avec confiance.
Mini-histoire 3 : la pratique ennuyeuse mais correcte qui a sauvé la mise
Une troisième équipe a fait une migration Debian 13 pour un monolithe legacy. L’appli était assez vieille pour avoir des opinions sur les modes de fichiers, et l’arbre de déploiement contenait un mélange de répertoires setgid,
quelques concessions ACL étranges, et un binaire avec des capabilities pour binder un port bas sans root. Le lead de l’équipe était têtu sur le processus : vérifications préalables, dry-runs, et une petite copie canary avant de toucher le dataset principal.
Ils ont commencé par l’identité : s’assurer que les comptes de service avaient des UID/GID identiques entre anciens et nouveaux serveurs. Pas « même nom », mêmes numéros. Ils ont vérifié la disponibilité LDAP/SSSD.
Puis ils ont lancé rsync en dry-run avec sortie itemisée et ont capturé la sortie dans un ticket. C’était fastidieux. C’était aussi le but.
Pendant le canary, ils ont remarqué une poignée de fichiers qui perdraient des xattrs. La destination était un montage NFS avec root-squash. Personne ne l’avait mentionné parce que c’était « juste du stockage ».
Ce détail aurait cassé tout le cutover : les binaires auraient perdu leurs capabilities, et certains répertoires seraient possédés par nobody. Comme ils l’ont détecté tôt, ils ont changé de plan : staged les données sur disque local d’abord,
puis ont fait un déplacement côté serveur dans l’hôte de stockage où la propriété pouvait être préservée.
Le jour du cutover a été ennuyeux. Les services sont revenus. La surveillance est restée silencieuse. La victoire n’était pas du génie ; c’était le refus de sauter les vérifs ennuyeuses qui attrapent les problèmes de permission avant les clients.
Erreurs fréquentes : symptôme → cause → correction
-
Symptôme : Tout sur la destination est possédé par l’utilisateur qui a lancé rsync.
Cause : rsync s’est exécuté sans privilège, ou la destination a refusé lechown(root-squash, mappage CIFS).
Correction : Exécutez rsync en root de bout en bout sur un filesystem qui supporte la propriété ; ou acceptez une réapplication chown/ACL après copie pilotée par politique. -
Symptôme : Les propriétaires semblent corrects par nom, mais les services échouent encore avec « permission denied ».
Cause : ACL ou xattrs perdus ; les bits de mode seuls ne suffisent pas.
Correction : Relancez avec-Aet-X; vérifiez avecgetfacletgetfattr. -
Symptôme : Les fichiers montrent des modes corrects, mais la propriété est assignée au mauvais compte local.
Cause : Mismatch UID/GID entre hôtes ; rsync a mappé par nom sans préserver les IDs numériques, ou la destination résout les noms différemment.
Correction : Alignez UID/GID avant la migration ; utilisez--numeric-ids; validez avecstatetgetent. -
Symptôme : L’application web peut lire les fichiers mais ne peut pas écrire uploads ou caches après migration.
Cause : Bits setgid/sticky manquants ou ACLs par défaut de répertoire manquantes qui accordent l’écriture au groupe de service.
Correction : Préservez permissions et ACL ; réappliquez les ACL par défaut ; validez avecgetfaclsur les répertoires. -
Symptôme : Un binaire qui bindait le port 80 échoue maintenant sauf s’il est exécuté en root.
Cause : xattr de capability perdu (security.capability).
Correction : Recopiez avec-X, ou réappliquez les capabilities avecsetcappuis assurez-vous que les migrations futures préservent les xattrs. -
Symptôme : L’utilisation disque a explosé après migration ; des arbres « identiques » prennent beaucoup plus d’espace.
Cause : Liens physiques non préservés car-Homis.
Correction : Relancez avec-Hpour les datasets qui utilisent des hard links ; testez sur un sous-ensemble et évaluez le coût. -
Symptôme : rsync indique un succès, mais les fichiers spéciaux/périphériques sont faux (ou manquent).
Cause : La copie n’a pas été exécutée en root ou n’a pas préservé les spéciaux (-Dvia-a), ou le filesystem de destination ne peut pas les stocker.
Correction : Utilisez root + archive mode sur un filesystem compatible ; pour des images système, envisagez une migration basée sur snapshot. -
Symptôme : Certains répertoires sont inscriptibles par « other » après migration.
Cause : Quelqu’un a utilisé--chmodde façon large ou a copié via un montage qui normalise les permissions ; ou a corrigé un symptôme en relâchant tout.
Correction : Annulez le chmod large. Restaurez depuis la source avec les flags de préservation appropriés. Auditez avecfindpour les chemins world-writable.
Listes de contrôle / plan étape par étape
Plan A : Migration fidélité complète (préférée)
- Confirmer alignement d’identité : comptes de service et groupes ont des UID/GID cohérents sur source et destination. Si vous utilisez LDAP/SSSD, vérifiez-le sur la destination.
- Valider la sémantique du filesystem de destination : filesystem Linux local préféré. Évitez CIFS pour les arbres critiques pour les permissions Unix. Traitez root-squash NFS comme une contrainte dure.
- Choisir un répertoire canary : inclure un fichier avec ACL et un binaire avec xattrs/capabilities si applicable.
-
Dry-run rsync avec
-n -iet sauvegardez la sortie itemisée. Cherchez owner/group/ACL/xattr. -
rsync réel :
sudo rsync -aHAX --numeric-ids --info=stats2,progress2. -
Vérifier : échantillon
stat,getfacl,getfattr. Faire un petit test application qui touche les chemins d’écriture. - Sync final : relancer rsync pour rattraper les deltas juste avant le cutover (mêmes flags).
- Cutover : démarrer les services ; surveiller les logs pour erreurs liées aux permissions ; garder les anciennes données en lecture seule tant que la confiance n’est pas établie.
Plan B : Transformation contrôlée (quand les IDs ne peuvent pas correspondre)
- Copier le contenu avec timestamps : utiliser rsync mais ne pas prétendre que la propriété correspondra.
- Appliquer la politique de propriété :
chown/chgrpexplicite et scripts d’ACL par répertoire. - Valider avec un audit : vérifier les propriétaires numériques, chemins world-writable inattendus, et ACL attendues manquantes.
- Documenter le mappage pour que la prochaine migration ne soit pas de l’archéologie.
Plan C : Destination NFS avec root-squash (choix pragmatiques)
- Préférer le staging sur disque local sur l’hôte de destination, en préservant la propriété là.
- Puis déplacer les données côté serveur (sur le serveur NFS) dans le chemin exporté, où la propriété peut être préservée localement.
- Si vous devez copier directement vers NFS : acceptez que la préservation de propriété puisse être impossible et traitez cela comme un travail de ré-propriété.
FAQ
1) Est-ce que rsync -a préserve la propriété ?
Il inclut -o et -g, mais il préserve réellement la propriété seulement si rsync a suffisamment de privilèges pour définir uid/gid sur la destination. Sur SSH,
cela signifie typiquement root côté distant aussi.
2) Pourquoi ai-je besoin de --numeric-ids ?
Parce que les noms peuvent correspondre à différents IDs numériques sur différents hôtes. --numeric-ids indique à rsync de préserver les numéros exactement, évitant le mappage « utile »
qui peut réassigner silencieusement la propriété.
3) J’ai exécuté en root, mais la propriété est quand même mauvaise. Pourquoi ?
Causes courantes : la destination est NFS avec root-squash ; la destination est CIFS avec mappage uid/gid forcé ; ou vous avez copié sur un filesystem/montage qui refuse le chown.
Testez avec un chown manuel sur le chemin de destination.
4) Quels drapeaux préservent les ACL et xattrs ?
-A préserve les ACL. -X préserve les attributs étendus. Si vous tenez à ce que les applications « continuent de fonctionner », vous voudrez généralement les deux.
5) Dois-je toujours utiliser -H ?
Pas toujours. -H peut augmenter l’usage mémoire et le temps d’exécution, car rsync doit suivre les relations de hard link. Utilisez-le quand votre dataset utilise des hard links
(certains arbres système, contenu dédupliqué, certains caches de paquets) et que vous tenez à les préserver.
6) Puis-je préserver la propriété en copiant en tant qu’utilisateur non-root ?
Pas en général. Un utilisateur non-root ne peut définir la propriété que sur lui-même (et parfois sur des groupes auxquels il appartient). Si vous avez besoin de fidélité de propriété, utilisez root ou un
workflow privilégié contrôlé.
7) Pourquoi les permissions ont l’air correctes mais les services systemd échouent ?
Les services peuvent échouer à cause de capabilities manquantes sur des binaires (xattrs), de l’absence d’accès à des répertoires runtime à cause de perte d’ACL, ou d’une propriété incorrecte sur des répertoires d’état sous
/var. Vérifiez getfattr pour les capabilities et getfacl pour les répertoires.
8) Est-il sûr de « tout corriger » avec chmod -R 777 ou un large chown -R ?
C’est rapide, ça « marche », et c’est la façon de transformer une migration en incident de sécurité. Si vous devez réécrire la propriété, faites-le avec un plan mappé et auditez le résultat.
9) Quelle est la façon la plus rapide de prouver que la source et la destination correspondent ?
Utilisez rsync en dry-run avec sortie itemisée (-n -i) et focalisez-vous sur les marqueurs p, o, g, a, et x.
Puis validez un échantillon avec stat, getfacl, et getfattr.
10) Je copie vers un filesystem qui ne supporte pas la propriété Unix. Que faire ?
Alors vous ne pouvez pas « préserver la propriété » de manière significative. Changez la destination (préférable), ou acceptez que les permissions seront représentées différemment
et faites appliquer l’accès via le modèle de ce système au lieu de prétendre que c’est POSIX.
Conclusion : prochaines étapes concrètes
Si vous voulez que les migrations Debian 13 soient ennuyeuses, cessez de traiter les permissions comme un effet secondaire. Traitez-les comme des données primaires. La propriété est des IDs numériques, pas des noms.
Les ACL et xattrs ne sont pas optionnels quand vous déplacez de vrais systèmes de production. Et les frontières de filesystem sont l’endroit où les bonnes intentions meurent.
Étapes pratiques :
- Choisissez un répertoire problématique et exécutez les vérifications canary :
stat,getfacl,getfattr. - Exécutez un rsync dry-run avec
-aHAX --numeric-ids -n -iet lisez les lettres comme si c’était un contrat. - Confirmez l’alignement UID/GID pour vos comptes de service avec
getentsur les deux hôtes. - Si vous ciblez NFS/CIFS, testez la définition de propriété avec un seul fichier avant de lancer la migration. S’il ne peut pas chown, il ne peut pas préserver la propriété — argumenter n’aidera pas.
- Puis faites la copie réelle avec l’ensemble de flags fidélité, et vérifiez avant le cutover.