Права доступа в *NIX системах
В этой статье я не претендую на написание чего-то нового. Видел подобную статью на античате, но решил побольше раскрыть эту тему именно для новичков, которые часто задают вопросы на эту тему. Так как статья рассчитана на новичков, постараюсь описать вопрос в доступной форме и с примерами, из-за этого придется пожертвовать некоторыми техническими деталями (так что сильно не придирайтесь). В общем поехали.
Прежде всего, надо сказать, что в *NIX ОС каждый пользователь, зарегистрированный в системе, имеет свой уникальный номер не равный нулю (0 – номер администратора ОС), по которому ОС определяет (идентифицирует) пользователя. Этот номер в *NIX называется UID, но для удобства (например, авторизации) UID`у присваивается символьное значение (имя), для этого в *NIX существует файл passwd, хранящийся в каталоге /etc (всем известный /etc/passwd). В этом файле находятся настройки пользователей, в том числе и сопоставление имени и UID`а.
Не ищите в этом файле паролей, их там попросту нет (когда-то давно были), а хранятся пароли (вернее не пароли, а их хеши) в файле shadow в Linux и master.passwd в BSD. Вот пример строки из файла passwd:
merabi:*:1012:80:Merab Lomia:/usr/local/www/asthma:/usr/local/bin/bash
как мы видим, строка состоит из условных “секций” разделенных двоеточием.
Такая запись означает, что имени пользователя
merabi (секция 1) присваивается идентификатор пользователя UID
1012 (секция 3), и идентификатор группы GID
80 (секция 4). Для администратора (обычно root) эта запись будет такой: root:*:0:0. В принципе возможно создать двух пользователей с правами администратора (UID - 0, GID – 0) но не будем на этом останавливаться.
Также в строке есть
* (секция 2) означает это, что пароль хранится не в этом файле, а в другом (shadow или master.passwd). 5 секция не на что не влияет и просто дает описание пользователя, в нашем случае, это, наверное, имя и фамилия, но в ней может быть, что угодно или она может быть пустая. Дальше, в 6 секции описан домашний каталог пользователя, (у нас:
/usr/local/www/asthma) каталог в который попадает пользователь после авторизации. В последней, 7 секции, описывается шелл, командный интерпретатор который загружается при входе пользователя в систему (в нашем примере
/usr/local/bin/bash), если пользователю не предназначен шелл, то сюда обычно записывают /sbin/nologin.
Еще раз замечу, что символьное имя пользователя существует для удобства, все операции ведутся именно с числом UID.
Также, каждый пользователь в *NIX должен принадлежать к какой-то группе, группа также определяется числом-идентификатором GID, которому также присваивается и символьное представление (имя группы). Одной группе могут принадлежать несколько пользователей, и наоборот, один пользователь может принадлежать нескольким группам, иногда это бывает удобно, но не будем заострять на это внимание. Часто для конкретного пользователя заводят свою группу с именем этого пользователя.
Просмотреть UID и GID, а также их символьные представления можно с помощью команды id в шелле, для этого нужно выполнить id имя пользователя, id без параметров выведет значения для текущего пользователя.
Ну, с этим вроде разобрались, едем дальше.
В *NIX каждый файл принадлежит какому либо пользователю, будь то администратор (дальше root) или nobody или любой другой. Когда создается файл, в его атрибуты записывается UID создавшего его пользователя. Root может изменять этот атрибут, т.е. фактически изменять владельца файла, с помощью команды chown, но нам сейчас это не важно. Владелец файла может изменять атрибуты файла (например, изменять права доступа, об этом ниже) читать файл, записывать в файл, исполнять файл. Иногда, можно столкнуться с такой ситуацией, что владелец файла не может его удалить или переименовать, объясню на примере:
Допустим у нас пользователь с именем user
Root создает каталог /inet разрешенный на чтение всем, но запрещенный для записи в него
В этом каталоге root создает файл filo.txt
Root выполняет команду chown user filo.txt и user становится владельцем файла filo.txt
User записывает данные в этот файл
User пытается удалить этот файл, но выдается ошибка permission denied
Происходит это из-за того, что когда user удаляет файл, он изменяет кроме всего прочего еще и каталог /inet, а так как владелец каталога root и user`у не разрешено изменять (записывать) каталог, возникает такая ошибка. Тоже самое и с переименованием.
Теперь об атрибутах файла. Выполнив в шелле команду
ls –lp мы можем увидеть список файлов в текущем каталоге, и некоторые атрибуты этих файлов, пример строки:
Код:
-rw-r--r-- 1 nobody nobody 899 Dec 5 17:08 default.htm
Здесь вначале показаны права доступа
-rw-r--r--, далее количество жестких ссылок на файл
1 (не будем рассматривать), владелец файла
nobody (или UID), группа, к которой принадлежит владелец
nobody (или GID), размер файла в байтах
899, дата и время создания файла
Dec 5 17:08 и собственно имя файла
default.htm
Вот о правах доступа поговорим поподробнее.
Возьмем наш пример и условно разделим на четыре секции:
.1| 2....|3....|4
- | rw- | r-- | r--
Секция 1 показывает тип файла и может принимать следующие значения:
- (как в данном примере) – обычный файл
d – каталог (каталог тоже является файлом но об этом позже)
l – символьная ссылка (не будем рассматривать)
есть еще два типа, которые встречаются реже, их мы тоже рассматривать не будем:
s – сокет
p – FIFO канал (вроде стека или буфера)
например:
-rw-r--r-- говорит о том, что это обычный файл,
drwxr-xr-x говорит о том, что это каталог,
lrwxrwxrwx говорит, что это символьная ссылка.
Секция 2 показывает права доступа для владельца файла (у нас
rw-), секция 3 показывает права доступа для группы в которую входит владелец файла (у нас
r--), секция 4 показывает права доступа для всех остальных пользователей, кроме администратора,
root является по сути владельцем всех файлов, т.е. имеет такие же права как и владельцы файлов.
Рассмотрим теперь секцию 2 (3 и 4 абсолютно идентичны второй)
r – говорит о том, что можно читать файл
w – говорит о том, что можно изменять файл (записывать в него или удалять из него)
x – говорит о том, что можно исполнять файл (это не относится к каталогам)
тире (-) показывает что данное действие запрещено.
У нас
-rw-r--r-- значит владельцу файла разрешено читать файл и записывать в него (
rw), но не исполнять, т.к. на месте
x стоит
тире, т.е. действие «исполнение файла» отключено, группе в которую входит владелец разрешено только читать файл, т.к. на месте
w и
x стоят пробелы, аналогично и с остальными пользователями.
Если в секции 2 стоит
r--, т.е. не включена возможность записи, то и владелец файла не сможет в него записывать, но он всегда может изменить права доступа к файлу с помощью команды шелла
chmod, т.е. добавить
w и после этого записывать в файл.
x – дает возможность исполнять файл, например если это бинарник или скрипт шелла или cgi скрипт (например perl-скрипт) то для исполнения файла наличие
x необходимо, компилятор gcc сам добавляет эту опцию к откомпилированой программе, т.е. на выходе получается файл с включенной опцией
x во всех трех секциях.
PHP скрипты для исполнения не нуждаются в включенной опции x, главное что бы была включена опция
r,
если php является cgi-скриптом, т.е. в начале файла есть строчка #! /путь до php/php,
то наличие x обязательно (если ошибаюсь поправьте меня).
Опции
rwx жестко привязаны к своему положению в строке (к последовательности), т.е. мы можем записать права доступа виде двоичного числа, где единица означает включенную опцию, а 0 значит, что опция выключена (т.е. стоит тире) обратимся к нашему примеру:
r w - | r - - | r - -
1 1 0 | 1 0 0 | 1 0 0
т.е.
rw-r--r-- можно обозначить как двоичное число
110100100, обычно двоичное число переводят в восьмеричную систему исчисления, тогда
110100100 будет обозначаться как
644, команда шелла
chmod как раз работает с восьмеричным числом (ну или символьным обозначением прав доступа)
Посчитать это восьмеричное число не сложно, каждая цифра числа показывает права доступа для каждой секции (у нас
6 – для владельцев,
4 –для группы,
4 – для остальных)
3 тире(---) - 0
r - +4
w - +2
x - +1
чтобы получить значение для включенной
r, надо к
0 (---) прибавить
4, у нас получилось
r--, чтобы теперь добавить атрибут
w надо к
4 прибавить
2 получится
6 или
rw- теперь, чтобы убрать опцию
r надо из этого числа вычесть
4,
6-4=2 или
-w-
При использовании функций для изменения прав доступа в различных языках программирования надо быть осторожным в использовании восьмеричной си, возьмем, к примеру,
php, в
php для этих целей существует функция
chmod(права, “имя файла”). Обычно в ЯП для обозначения числа в восьмеричной системе исчисления, перед числом ставится
0 (0x для hex и т.д.), так вот если этот
0 забыть
мы получим совсем другой результат, т.к. функция воспримет это число как
десятичное, попробуйте сами:
открываем калькулятор -> ставим вид инженерный->пишем число 644 в восьмеричной си (Oct) -> переводим в двоичную(Bin) видим 110100100 , все правильно.
Теперь пишем число 644 в десятичной си (Dec), переводим в Oct, видим 1204, переводим в Bin, видим 1010000100, совсем другой результат, можете поэкспериментировать, если у вас есть вебшелл на *NIX с возможностью исполнять php код (попробуйте например поставить права 700 в десятичной си, очень красноречивый пример получится).
Теперь о каталогах, каталоги в *NIX,
это такие же файлы, хранящие информацию о файлах и подкаталогах, например во FreeBSD каталоги можно читать, как обычные файлы с помощью команды cat или средствами php, но при этом будет отображаться много «мусора», на самом деле, это конечно же не мусор а именно информация о файлах и подкаталогах, для парсинга файла каталога, я написал скрипт на php вот здесь его можно увидеть:
http://forum.antichat.ru/thread55237.html
Права доступа обычных файлов и файлов каталогов немного различаются, а именно, отличие их в атрибутах
r и
x. В
файле каталога, находится информация о файлах и подкаталогах, а именно отображаемые имена и ссылки на физическое расположение файлов и подкаталогов на диске. Атрибут
r при этом отвечает за доступ к отображаемым именам, а атрибут
x за доступ к ссылкам на физическое расположение. Что же у нас получается, если включена опция
r в атрибутах каталога, а
x выключена, то мы можем просмотреть файлы внутри этого каталога, т.к. доступ на чтение имен файлов у нас есть (
r включена),
но мы не сможем прочитать, изменить, или выполнить файл даже если у нас есть соответствующие права доступа на файл (при этом мы их не увидим), т.к. доступа к физическому расположению файла у нас нет, другими словами мы “незнаем” где физически расположен файл (опция
x выключена). Если опция
x включена, а опция
r выключена то мы можем производить с файлами действия соответствующие нашим правам доступа к файлу, но
отобразить имена у нас не получится. Хотя обычно опции
r и
x всегда вместе включены на каталогах. Интересно и поведение опции
w установленной для каталога, дело в том, что каталог не знает о правах доступа его файлов, поэтому если у нас есть права на запись/изменение каталога, то
мы можем удалять файлы независимо от того, какие права доступа стоят для этого файла.
То есть, допустим у нас есть права на запись в веб-каталог, в котором есть файл
index.html
, который нам запрещено изменять, мы можем просто удалить этот файл, и записать новый в который запишем содержание старого
index.html, c нашими изменениями.
Ну, вот вроде бы и все, надеюсь, я понятно все объяснил, и эта статья кому-то пригодится…
PS статью писал сам, так что в копипасте меня не обвиняйте
Спасибо за прочтение, с уважением Scipio