Как мне сделать файл НЕ изменяемым?

35

После входа в систему я могу сделать следующее:

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

Затем я могу открыть vim (не как root), редактировать bar, форсировать запись w!, и файл будет изменен.

Как я могу заставить операционную систему запретить изменение файла?

ОБНОВЛЕНИЕ 02 марта 2017

  1. chmod 500 fooэто красная сельдь: разрешение на запись в каталог не имеет ничего общего с возможностью изменять содержимое файла - только возможность создавать и удалять файлы.

  2. chmod 400 foo/barфактически предотвращает изменение содержимого файла. Но это не препятствует изменению прав доступа к файлу - владелец файла всегда может изменить права доступа к своему файлу (при условии, что они могут получить доступ к файлу, т. Е. Разрешение на выполнение для всех каталогов предков). Фактически, strace (1) показывает, что именно это делает vim (7.4.576 Debian Jessie) - vim вызывает chmod (2), чтобы временно добавить разрешение на запись для владельца файла, изменяет файл, а затем вызывает chmod ( 2) снова убрать разрешение на запись. Вот почему использование chattr +iработает - может звонить только root chattr -i. Теоретически, vim (или любая другая программа) может сделать то же самое с chattr, как и с chmod для неизменяемого файла, если он запускается от имени пользователя root.

user2141130
источник
3
Я полагаю, что под капотом vimпроисходит изменение прав доступа, а затем возвращение.
Иордания
Ты не бежишь как root?
Элвин Вонг
Элвин, я делаю это как пользователь без полномочий root. Я отредактировал пост, чтобы уточнить.
user2141130

Ответы:

49

Вы можете установить атрибут «неизменный» для большинства файловых систем в Linux.

chattr +i foo/bar

Чтобы удалить неизменный атрибут, вы используете -вместо +:

chattr -i foo/bar

Чтобы увидеть текущие атрибуты для файла, вы можете использовать lsattr:

lsattr foo/bar

Страница man chattr (1) содержит описание всех доступных атрибутов. Вот описание для 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.
jordanm
источник
3
В Linux этот неизменный флаг доступен во многих файловых системах, не только ext2 / 3/4 (по крайней мере, btrfs, hfsplus, jfs, nilfs2, xfs, ocfs2, ubifs, gfs2, reiserfs AFAICT из быстрого просмотра кода)
Стефан Chazelas
@StephaneChazelas Я видел, что chattrкоманда была частью e2fsprogsпакета в моей системе. Вот почему я сделал это заявление. Я обновил ответ на основе вашего комментария.
Иордания
Это не работает для символических ссылок :-(. Это решение было бы замечательно, потому что я хочу избежать того, что символическая ссылка может быть случайно изменена любым пользователем, включая root.
natenho
Неизменен ли флаг inode, а не xattr? Флаг ioctl, если быть точным?
ytpillai
1

Вы можете:

  1. Изменить владельца файла на rootфиктивного пользователя
  2. Держите правильную группу.
  3. Используйте, chmod 440чтобы разрешить чтение по группе (это вы).

Если правильный пользователь не единственный в этой группе, вы должны создать новую группу и добавить в нее только его, и использовать эту группу для нее. Однако вы не являетесь владельцем файла, поэтому вы viне можете изменить владельца файла.

Эй'
источник
3
Если вы можете записать в родительский каталог, то vim может удалить файл и создать новый (и это то, что он делает, когда вы это делаете :w!). vim не заходит так далеко, как временное изменение прав доступа к каталогу. Поэтому хранить каталог без записи должно быть безопасным.
Стефан Шазелас
0

Чтобы сделать все дерево каталогов доступным только для чтения:

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

Чтобы снова сделать его читабельным, измените +iна -i.

Робин А. Мид
источник