<?xml version="1.0" encoding="utf-8"?>
<entry title="Faire un lien symbolique immuable sur Linux">
  <date>2026-09-09</date>
<content>
  <p>Hier, j'ai cherché à faire un <wikipedia name="Lien symbolique">lien
  symbolique</wikipedia> « immuable » sur
  <wikipedia name="Noyau Linux">Linux</wikipedia>, plus exactement un lien que son ou sa
  propriétaire ne risquerait pas de supprimer par accident, tout en
  lui permettant de créer et détruire d'autres objets dans ce
  répertoire. Si vous connaissez Linux, vous allez probablement crier
  « <computer><unix>chattr</unix> +i</computer>, <computer>chattr
  +i</computer> ! ». Mais, non, cela ne marche pas.</p>
  <p>Essayons quand même, sur le compte d'un utilisateur nommé
  Bob. D'abord avec un fichier ordinaire :
  <code>
$ echo "Contenu sans intérêt" > myfile

$ sudo chattr +i myfile

$ ls -l myfile 
-rw-rw-r-- 1 bob bob 23 Sep  9 15:12 myfile
$ lsattr myfile 
----i---------e------- myfile

$ rm myfile 
rm: cannot remove 'myfile': Operation not permitted
  </code>
  Parfait, tout marche (une alternative à <unix>sudo</unix> aurait été
  la <wikipedia xml:lang="en" name="Capability-based security"
  anchor="POSIX_capabilities">capacité</wikipedia>
  <computer>CAP_LINUX_IMMUTABLE</computer> mais c'est une autre
  histoire). Essayons maintenant avec un lien symbolique :
  <code>
$ ln -s /etc/motd mylink

$ sudo chattr +i mylink 
chattr: Operation not supported while reading flags on mylink
  </code>
  Bon, c'est raté, <unix>chattr</unix> ne marche pas sur les
  <wikipedia name="Lien symbolique">liens symboliques</wikipedia>. (Le
  message exact dépend de votre <wikipedia name="Bibliothèque standard
  du C">libc</wikipedia> ; vous aurez peut-être plutôt
  « <foreign>Symbolic link loop</foreign> »<!-- Avec musl -->.) En
  tout cas, ça ne marche pas sur <wikipedia name="Noyau Linux">Linux</wikipedia>. (Il
  parait que cela fonctionne sur <wikipedia>FreeBSD</wikipedia>.)
  </p>
  <p>Comment faire, alors ? Changer le propriétaire du lien ne change
  rien car la suppression est une opération sur le répertoire. Le
  propriétaire du répertoire peut supprimer des fichiers qui ne lui
  appartiennent pas. Et changer le propriétaire du répertoire ne
  suffit pas, car on veut que Bob puisse continuer à lire et à écrire
  dans ce répertoire. Le <foreign><wikipedia xml:lang="en"
  name="Sticky bit">sticky bit</wikipedia></foreign> seul ne suffirait
  pas non plus, il empêche de supprimer les fichiers des autres, pas
  les siens.
  </p>
  <p><wikipedia>ChatGPT</wikipedia> a finalement trouvé une solution,
  mais à <link
  url="https://chatgpt.com/share/6aa15fb4-d53c-83ed-9f2e-e65e4cfcc2a7">la
  troisième itération</link>, après quelques idées qui ne marchaient
  pas (ChatGPT, comme tout utilisateur des réseaux sociaux, ne teste
  pas ses idées avant de les publier ; « <foreign>You're
  right</foreign> », « <foreign>Yes. Your suspicion is exactly
  correct</foreign> ») :
  <code>
$ ln -s /etc/motd mylink
$ sudo chown root:bob .
$ sudo chmod +t .
$ sudo chmod g+w .
$ sudo chown --no-dereference root:root mylink

$ rm mylink 
rm: cannot remove 'mylink': Operation not permitted

$ ls -alt                                
total 8
drwxrwxr-t 2 root bob  4096 Sep  9 15:26 .
lrwxrwxrwx 1 root root    9 Sep  9 15:26 mylink -> /etc/motd
drwxr-x--- 3 bob  bob  4096 Sep  9 15:25 ..
  </code>
  Détaillons cette solution. On met
  <computer><wikipedia>root</wikipedia></computer> comme propriétaire
  du répertoire (on peut aussi utiliser un autre utilisateur que
  <computer>root</computer>) mais le <wikipedia name="Groupe
  (Unix)">groupe</wikipedia> est <computer>bob</computer>, un groupe
  qui inclut Bob. On met ensuite le <foreign>sticky bit</foreign>. On
  donne au groupe le droit d'écriture dans le répertoire. Et enfin on
  change le propriétaire du lien pour que cela ne soit pas Bob (notez
  le <computer>--no-dereference</computer> sans lequel
  <computer><unix>chown</unix></computer> essaierait de changer la
  cible du lien et pas le lien).  Et Bob ne peut plus supprimer le
  lien, tout en pouvant lire et écrire dans le répertoire.
    </p>
  </content>
</entry>
