Может ли суперпользователь записывать в файлы только для чтения?

11

Я наткнулся на неожиданное (для меня) поведение разрешений во FreeBSD. Допустим, я работаю как пользователь без полномочий root . Я создаю файл, устанавливаю его разрешение только для чтения и затем пытаюсь записать в него:

$ touch f
$ chmod 400 f
$ ls -l f
-r--------  1 user  wheel  f
$ echo a >> t
t: Permission denied.

Все идет нормально. Теперь я делаю то же самое, что и root, и он записывает в файл:

# ls -l f2
-r--------  1 root  wheel  f2
# echo a >> f2
# echo $?
0

Это ошибка или предполагаемое поведение? Могу ли я с уверенностью предположить, что это будет работать на любом Unix и Linux?

arrowd
источник
Это CAP_DAC_OVERRIDEможет сделать любой пользователь с . Почти на всех системах Linux это означает, что root может сделать это, поэтому это сделано намеренно. Не могу говорить о части FreeBSD, но я думаю, что у них похожая настройка.
Братчли
1
Причина, по которой root должен ВСЕГДА иметь возможность записи в файл, заключается в том, что в традиционных файловых системах unix (ext4, zfs и т. Д.) Права доступа к файлам являются частью файла. Таким образом, если root не может записать в файл, то NOBODY может сделать файл доступным только для чтения для повторной записи, потому что chmodне может записать в файл.
Slebetman
1
@slebetman Вам не нужно иметь права на запись в файл, чтобы обновить разрешения. Просто попробуйте touch somefile; chmod 0000 somefile; chmod 0644 somefileкак обычный пользователь.
user253751
@immibis: Это у тебя есть. Root должен иметь возможность изменять права доступа к файлам, которые ему не принадлежат
slebetman
@slebetman Да ... но вы говорили об изменении разрешений для файлов, в которые вы не можете писать, а не об изменении разрешений для файлов, которыми вы не владеете.
user253751

Ответы:

13

Это нормально для rootвозможности переопределить разрешения таким способом.

Другим примером является rootвозможность чтения файла без доступа для чтения:

$ echo hello > tst
$ chmod 0 tst
$ ls -l tst
---------- 1 sweh sweh 6 Aug 16 15:46 tst
$ cat tst
cat: tst: Permission denied
$ sudo cat tst
hello

Некоторые системы имеют концепцию неизменяемых файлов. например, на FreeBSD:

# ls -l tst
-rw-r--r--  1 sweh  sweh  6 Aug 16 15:50 tst
# chflags simmutable tst
# echo there >> tst
tst: Operation not permitted.

Теперь даже rootне могу записать в файл. Но, конечно, rootможно убрать флаг:

# chflags nosimmutable tst
# echo there >> tst
# cat tst
hello
there

С FreeBSD вы можете пойти дальше и установить флаг ядра, чтобы предотвратить его rootудаление:

# chflags simmutable tst
# sysctl kern.securelevel=1
kern.securelevel: -1 -> 1
# chflags nosimmutable tst
chflags: tst: Operation not permitted

Теперь никто, даже не rootможет изменить этот файл.

(Систему необходимо перезагрузить, чтобы уменьшить уровень безопасности).

Стивен Харрис
источник
Как требуется перезагрузка эффективной меры безопасности? Кроме того, если root является root и может делать что угодно, зачем вообще пытаться запретить root делать то, что хочет root?
кот
1
В безопасной системе root не похож на Бога. FreeBSD securelevel - это небольшая попытка сделать root менее похожим на Бога. Уровень безопасности может быть установлен по умолчанию на 1 в конфигурации системы, поэтому он остается активным даже после перезагрузки. Так что тогда потребуется консольный доступ и однопользовательский режим, и это очень очевидно. Существует целое эссе о безопасности Unix, что слишком много для поля комментариев SE, но мы пытаемся перейти от модели «root is all access» к чему-то более нюансированному. Мы пытаемся обеспечить соблюдение, где это возможно (например, уровень безопасности), и обнаруживаем, где нет (перезагрузка доказательств, контрольные журналы).
Стивен Харрис
4
FWIW, в Linux chattr +i tstустанавливается неизменный атрибут.
Руслан
3

Да, это очень нормально. root не имеет ограничений на чтение / запись (за очень небольшим исключением), потому что он является root.

Ипор Сирсер
источник