Comment puis-je rendre un fichier NON modifiable?

35

Une fois connecté, je peux effectuer les tâches suivantes:

mkdir foo
touch foo/bar
chmod 400 foo/bar 
chmod 500 foo

Ensuite, je peux ouvrir vim (pas en tant que root), éditer bar, forcer une écriture avec w!, et le fichier est modifié.

Comment puis-je faire en sorte que le système d'exploitation n'autorise aucune modification de fichier?

MISE À JOUR 02 mars 2017

  1. chmod 500 fooest un fouillis rouge: l'autorisation d'écriture sur un répertoire n'a rien à voir avec la possibilité de modifier le contenu d'un fichier - uniquement la possibilité de créer et de supprimer des fichiers.

  2. chmod 400 foo/barempêche en fait le contenu du fichier d'être modifié. Toutefois , cela n'empêche pas les autorisations d'un fichier d'être modifiées - le propriétaire d'un fichier peut toujours modifier les autorisations de son fichier (en supposant qu'il puisse accéder au fichier, c'est-à-dire qu'il dispose d' une autorisation d'exécution sur tous les répertoires ancêtres). En fait, strace (1) révèle que c’est ce que fait vim (7.4.576 Debian Jessie): vim appelle chmod (2) pour ajouter temporairement l’autorisation d’écriture du propriétaire du fichier, le modifie, puis appelle chmod ( 2) à nouveau pour supprimer l'autorisation d'écriture. C'est pourquoi en utilisant chattr +iworks - seul root peut appeler chattr -i. Théoriquement, vim (ou n'importe quel programme) pourrait faire la même chose avec chattr comme avec chmod sur un fichier immuable s'il était exécuté en tant que root.

utilisateur2141130
la source
3
Je crois que sous le capot, vimest en train de modifier les autorisations, puis de les rétablir.
Jordanie
Vous ne courez pas comme root?
Alvin Wong
Alvin, je le fais en tant qu'utilisateur non root. J'ai édité le post pour clarifier.
user2141130

Réponses:

49

Vous pouvez définir l'attribut "immuable" avec la plupart des systèmes de fichiers sous Linux.

chattr +i foo/bar

Pour supprimer l'attribut immuable, vous utilisez -au lieu de +:

chattr -i foo/bar

Pour voir les attributs actuels d'un fichier, vous pouvez utiliser lsattr:

lsattr foo/bar

La page de manuel chattr (1) fournit une description de tous les attributs disponibles. Voici la description pour i:

   A  file with the `i' attribute cannot be modified: it cannot be deleted
   or renamed, no link can be created to this file  and  no  data  can  be
   written  to  the  file.  Only the superuser or a process possessing the
   CAP_LINUX_IMMUTABLE capability can set or clear this attribute.
Jordan
la source
3
Sous Linux, cet indicateur immuable est disponible sur de nombreux systèmes de fichiers, pas seulement ext2 / 3/4 (au moins btrfs, hfsplus, jfs, nilfs2, xfs, ocfs2, ubifs, gfs2, reiserfs AFAICT à partir d’un rapide coup d’œil dans le code)
Stéphane Chazelas
@StephaneChazelas J'ai vu que la chattrcommande faisait partie du e2fsprogspackage de mon système. C'est pourquoi j'ai fait cette déclaration. J'ai mis à jour la réponse en fonction de votre commentaire.
Jordanie
Cela ne fonctionne pas pour les liens symboliques :-(. Cette solution serait géniale, car je veux éviter que le lien symbolique puisse être modifié par inadvertance par tout utilisateur, y compris root.
natenho
Immutable est un drapeau d'inode correct, pas un xattr? Le drapeau ioctl pour être précis?
Ytpillai
1

Vous pouvez:

  1. Changez le propriétaire du fichier en rootou un nouveau nom d'utilisateur créé
  2. Gardez le bon groupe.
  3. Utilisez chmod 440pour permettre la lecture par groupe (qui est vous).

Si le bon utilisateur n'est pas le seul de ce groupe, vous devez créer un nouveau groupe, y ajouter uniquement celui-ci et utiliser ce groupe pour celui-ci. Cependant, vous n'êtes pas le propriétaire du fichier, vous vine pouvez donc pas changer le propriétaire du fichier.

yo '
la source
3
Si vous pouvez écrire dans le répertoire parent, vim peut alors supprimer le fichier et en créer un nouveau (et c'est ce qu'il fait quand vous le faites :w!). vim ne va cependant pas jusqu'à changer les permissions du répertoire temporairement. Donc, garder le répertoire non-inscriptible devrait être sûr.
Stéphane Chazelas
0

Pour rendre une arborescence de répertoires complète en lecture seule:

cd <directory>
find ./ -print0 | sudo xargs -I {} -0 chattr +i {}

Pour le rendre à nouveau lisible, changer +ien -i.

Robin A. Meade
la source