Тема пользователей и их прав в системе в первую очередь относится к функционированию самой операционной системы. Оболочка лишь предоставляет утилиты, позволяющие анализировать доступы и изменять их.
Взаимодействие с операционной системой всегда ведётся от какого-то конкретного пользователя, созданного в системе. Команда whoami позволяет выяснить, кто же я такой:
$ whoami rekoshed
Абсолютно любой процесс, запускаемый в операционной системе, стартует от имени некоторого пользователя. Соответственно, его возможности по влиянию на файловую систему ограничены теми правами, которые есть у пользователя, от имени которого процесс запущен. Обратите внимание на то, что я говорю не "пользователь запустил процесс", а "процесс запускается от имени пользователя". Дело в том, что присутствие пользователя для запуска необязательно. Да, работая в командной строке мы стартуем всё сами, но когда система загружается, то она стартует множество различных процессов и, как мы увидим ниже, для многих из них создаются собственные пользователи с ограниченным набором прав.
Команда ps (process status) выводит отчёт о работающих процессах. Информацию о том, какой процесс и под каким пользователем запущен, можно получить из вывода ps aux:
$ ps aux # Левый столбец имя пользователя rekoshed 1997 0.0 0.2 241028 8876 ? Ssl 08:36 0:00 /usr/lib/gvfs/gvfs-udisks2-volume-monitor root 1998 0.0 0.1 8084 4608 ? Ss 08:36 0:00 /usr/lib/bluetooth/bluetoothd rekoshed 2002 0.0 0.1 239364 7268 ? Ssl 08:36 0:00 /usr/lib/gvfs/gvfs-gphoto2-volume-monitor rekoshed 2018 0.0 0.1 236972 5972 ? Ssl 08:36 0:00 /usr/lib/gvfs/gvfs-mtp-volume-monitor root 2084 0.0 0.2 257220 9332 ? Ssl 08:36 0:00 /usr/lib/upower/upowerd rekoshed 2120 0.0 0.6 262120 27184 ? Sl 08:36 0:00 /usr/bin/lxqt-powermanagement rekoshed 2122 0.0 0.7 261612 29496 ? Sl 08:36 0:00 /usr/bin/qlipper rekoshed 2124 0.0 0.7 262840 29292 ? Sl 08:36 0:00 /usr/bin/nm-tray rekoshed 2178 0.1 1.2 368520 47944 ? Sl 08:38 0:03 qterminal rekoshed 2181 0.0 0.1 10860 4380 pts/0 Ss 08:38 0:00 /bin/bash rekoshed 2258 0.0 0.2 28200 9412 pts/0 S+ 08:38 0:00 mc rekoshed 2260 0.0 0.1 10832 4260 pts/1 Ss+ 08:38 0:00 bash -rcfile .bashrc rekoshed 2269 0.0 0.0 2568 784 pts/0 S+ 08:38 0:00 /bin/sh /tmp/mc-rekoshed/mcextXVE59Z rekoshed 2270 0.0 0.0 2568 720 pts/0 S+ 08:38 0:00 /bin/sh /usr/lib/mc/ext.d/web.sh open html rekoshed 2271 0.0 0.0 2568 1828 pts/0 S+ 08:38 0:00 /bin/sh /usr/bin/xdg-open /home/rekoshed/Github/Rekoshed.github.io/index.html rekoshed 2335 0.0 0.0 12696 1528 pts/0 S+ 08:38 0:00 cat rekoshed 2336 0.0 0.0 12696 1616 pts/0 S+ 08:38 0:00 cat rekoshed 2343 0.0 0.1 10964 4596 pts/2 Ss+ 08:39 0:00 /bin/bash rekoshed 4682 0.0 0.1 10832 4352 pts/4 Ss 08:53 0:00 /bin/bash rekoshed 4689 0.0 0.2 28360 9312 pts/4 S+ 08:53 0:00 mc rekoshed 4691 0.0 0.1 10836 5036 pts/5 Ss+ 08:53 0:00 bash -rcfile .bashrc root 4815 0.0 0.0 0 0 ? I 08:56 0:00 [kworker/0:1-events] rekoshed 4820 0.0 0.2 386756 8232 ? Sl 08:56 0:00 /usr/lib/gvfs/gvfsd
Взаимодействие с файловой системой происходит через запуск тех или иных утилит, модифицирующих, создающих или анализирующих файловую структуру. Это значит, что запуская, например, touch, мы стартуем процесс от своего имени, внутри которого запускается программа touch. Она, в свою очередь, создаёт файл (если его не было) и делает вас владельцем нового файла. Кстати, модификация существующих файлов не влияет на владельца — для его смены нужно воспользоваться специальной утилитой. В домашней директории пользователя всё принадлежит пользователю (хотя, если постараться, то можно навертеть как угодно):
$ ls -la total 44 drwxr-xr-x 5 rekoshed rekoshed 4096 Aug 29 11:34 . drwxr-xr-x 8 root root 4096 Apr 26 10:38 .. -rw------- 1 rekoshed rekoshed 2540 Aug 30 07:26 .bash_history -rw-r--r-- 1 rekoshed rekoshed 220 Aug 31 2015 .bash_logout -rw-r--r-- 1 rekoshed rekoshed 3771 Aug 31 2015 .bashrc drwx------ 2 rekoshed rekoshed 4096 Mar 30 18:10 .cache -rw------- 1 rekoshed rekoshed 55 Aug 28 18:49 .lesshst drwxrwxr-x 2 rekoshed rekoshed 4096 Aug 29 08:35 .nano -rw-r--r-- 1 rekoshed rekoshed 655 May 16 2017 .profile -rw-rw-r-- 1 rekoshed rekoshed 0 Aug 29 11:27 renamed-file drwx------ 2 rekoshed rekoshed 4096 Jan 22 2018 .ssh -rw------- 1 rekoshed rekoshed 513 Aug 29 08:06 .viminfo
Третий столбец в этом выводе — как раз владелец. Единственная запись, которая выбивается из всего списка это .., то есть родительская директория. Её владельцем является root, о котором мы позже поговорим. Если хорошо подумать, то это логично — ведь директория /home не является собственностью пользователей системы:
$ ls -la /home/ total 32 drwxr-xr-x 8 root root 4096 Apr 26 10:38 . drwxr-xr-x 23 root root 4096 Aug 27 06:53 .. drwxr-xr-x 5 egor.v egor.v 4096 Jan 22 2018 egor.v drwxr-xr-x 5 rekoshed rekoshed 4096 Aug 29 11:34 rekoshed drwxr-xr-x 4 robot robot 4096 Apr 26 10:05 robot drwxr-xr-x 4 robot.d robot.d 4096 Apr 26 10:41 robot.d
Каждый каталог в директории /home является домашним каталогом конкретного пользователя. Поэтому они все имеют разных владельцев, как правило, совпадающих с именем директории.
Имя пользователя в системе должно быть уникальным, но его можно менять. Если посмотреть под капот работы этой системы, то мы увидим, что имя пользователя связано с идентификатором, называемым UID. Это число, которое и определяет пользователя. Если поменяется имя пользователя, но идентификатор останется прежним, то все доступы останутся. Если же сменится идентификатор, то фактически сменится и пользователь. Соответственно, новый пользователь потеряет доступы ко всему старому. Посмотреть свой идентификатор можно разными способами. Первый способ — с помощью команды id:
$ id uid=1002(rekoshed) gid=1002(rekoshed) groups=1002(rekoshed),999(docker)
Второй способ связан с просмотром одного важного файла, который является основным хранилищем пользователей в *nix системах. Да, это обычный текстовый файл, как и всё остальное.
$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin rekoshed:x:1002:1002::/home/rekoshed:/bin/bash
Кроме имени и идентификатора, здесь также указана домашняя директория пользователя (и её можно поменять), а так же шелл по умолчанию. Запись /usr/sbin/nologin говорит о том, что данный пользователь не может входить в систему. Такие пользователи нужны для запуска программ, имеющих ограниченные права, и им, естественно, не нужно входить в систему.
Кроме имени, у пользователей *nix систем есть связанное с ним понятие группа. Группа, как можно догадаться из названия, создана для группового доступа к разделяемому (общему) ресурсу (например, файлу). Например, у нас есть группа разработчиков, которые регулярно ходят на сервер, и им нужно дать одинаковые возможности по управлению определёнными файлами. Так как владелец у файла ровно один, то мы не можем решить этот вопрос через смену владельца, но можем через создание группы. Достаточно её создать и привязать к самому пользователю. Группы, ассоциированные с текущим пользователем, показываются в выводе команды id:
$ id uid=1002(rekoshed) gid=1002(rekoshed) groups=1002(rekoshed),999(docker)
Здесь группа rekoshed является основной, такая группа может быть только одна, и именно в эту группу входят любые создаваемые файлы от имени текущего пользователя. Кроме основной, пользователь может входить в произвольное число дополнительных групп. То, как это влияет на доступы, мы рассмотрим в одном из следующих уроков.
В любой *nix системе присутствует специальный пользователь root, или, как говорят, суперпользователь. Главная его особенность — это идентификатор со значением 0 (а имя в теории можно поменять). Этот пользователь имеет особое значение для системы и может выполнять абсолютно любые действия в системе. У пользователя root в файле /etc/passwd будет вот такая запись:
Крайне не рекомендуется использовать этого пользователя на регулярной основе. И ни в коем случае нельзя входить под ним в систему. root — это прямой доступ ко всему и большая дыра в безопасности системы. Кроме того, систему очень легко убить, например, удалив случайно не тот файл или испортив важную конфигурацию, после чего вход в систему станет невозможным.
Sudo
Несмотря на это, root нужен для выполнения некоторых привилегированных действий, которые недоступны обычным пользователям.
Ситуаций, в которых необходимо повышать привилегии и выполнять команды от рута (пользователя root), довольно много. С некоторыми мы уже столкнулись, с другими познакомимся в следующих уроках:
- Установка новых программ
- Навигация по чужим директориям
- Изменение прав доступа и владельцев файлов, не принадлежащих текущему пользователю
- Создание, редактирование и удаление файлов в местах, где не хватает прав текущего пользователя
- Запуск программ, требующих повышенные привилегии
Стать другим пользователем, находясь прямо в системе, можно с помощью утилиты su (substitute user, switch user). Когда-то такой способ был основным, но сейчас он устарел и крайне не рекомендуется к использованию. Подробнее об этом можно прочитать в статье из дополнительных материалов. Основной способ повышать привилегии в современных системах — утилита sudo (substitute user and do — дословно "подменить пользователя и выполнить").
Используется судо очень просто, достаточно поставить её слева от любой команды и выполнить. По умолчанию она пытается повысить привилегии до суперпользователя:
# Нет прав на выполнение $ touch /etc/myfile touch: cannot touch '/etc/myfile': Permission denied # С sudo все работает $ sudo touch /etc/myfile # Видно что владелец файла root $ stat /etc/myfile File: '/etc/myfile' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: ca01h/51713d Inode: 2761 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) # Нет прав на удаление $ rm /etc/myfile rm: remove write-protected regular empty file '/etc/myfile'? y rm: cannot remove '/etc/myfile': Permission denied # Опять помогло sudo $ sudo rm /etc/myfile $
В зависимости от настроек sudo в системе, эта утилита может попросить ваш пароль для входа, либо вообще откажется работать, сказав, что у вас нет права её использовать. Как правило, в Ubuntu судо спрашивает пароль и запоминает его на 5 минут. На протяжении этого времени вы можете использовать sudo, не вводя пароль каждый раз.
Иногда бывает нужно выполнить команду из под пользователя, отличного от root. Тогда придётся добавить флаг -u:
$ sudo -u nobody mkdir /tmp/test # Файл создан от nobody $ stat /tmp/test File: '/tmp/test' Size: 4096 Blocks: 8 IO Block: 4096 directory Device: ca01h/51713d Inode: 4577 Links: 2 Access: (0755/drwxr-xr-x) Uid: (65534/ nobody) Gid: (65534/ nogroup)
Если стоит задача произвести сразу пачку действий от имени другого пользователя, то для этого можно запустить новую сессию поверх текущей:
$ sudo -i $ id uid=0(root) gid=0(root) groups=0(root)
Главное — не забыть переключиться обратно после завершения необходимых манипуляций. Для этого наберите exit.
Права доступа
Частая ошибка, с которой встречаются разработчики — ошибка доступа:
$ touch /etc/myfile touch: cannot touch '/etc/myfile': Permission denied
Она говорит о том, что текущий пользователь не имеет прав на создание файлов в каталоге /etc. Почему? Давайте разбираться.
Кроме имени пользователя и группы, с каждым файлом ассоциированы права доступа: r — чтение, w — запись и x — исполнение. Причём, эти права задаются для трёх типов пользователей: владельца (Owner), пользователей, входящих в ту же группу (Group) и остальных (Other) — тех, кто не попал в предыдущие две. Разберём на примере:
# Пример строчки из вывода команды ls -la -rw-r--r-- 1 rekoshed rekoshed 3771 Aug 31 2015 .bashrc
Запись слева представляет из себя один из вариантов описания прав доступа (permissions). Для удобства чтения разделим эту запись на группы символов - rw- r-- r--. Символ - в этой записи говорит о том, что перед нами обычный файл. За ним следует три группы, в каждой из которых по три символа. Каждая группа описывает доступы для разных типов пользователей. Первая описывает права доступа для владельца файла. rw- означает, что владелец этого файла может как читать (r) этот файл, так и писать (w) в него. Последний прочерк означает, что этот файл нельзя исполнять. Исполнение описывается символом x и будет рассмотрено в следующем уроке. Не важно, какой файл или директорию мы смотрим — порядок прав в этой группе всегда один и тот же чтение-запись-исполнение, а прочерк означает отсутствие данного права.
Следующая группа прав относится к тем, кто входит в группу rekoshed, так как именно этой группе принадлежит данный файл. Запись r-- говорит о наличии доступа только для чтения, а изменение запрещено. То же самое касается и тех, кто не входит в эту группу, то есть набор прав у последних двух одинаковый.
Попробуйте ответить на вопрос с подвохом: а кто может удалить этот файл? Для ответа на этот вопрос важно знать владельца, группу и права той директории, в которой лежит файл .bashrc. Сам файл не может обозначить прав на своё удаление, они всегда берутся из того места, где он находится. Удалить файл можно только, если у вас есть возможность писать в эту директорию (в соответствии с тем, к какому типу пользователей вы относитесь).
$ ls -la /home/ | grep kirill drwxr-xr-x 5 rekoshed rekoshed 4096 Aug 29 11:34 rekoshed
Домашняя директория имеет другие права. Первое отличие — это d вместо - в самом начале. d говорит о том, что перед нами директория. Права для владельца rwx, а для всех остальных r-x. Из этого описания видно, что кроме пользователя никто не может писать внутрь домашней директории этого пользователя.
Что такое x в отношении директорий? Это право позволяет перемещаться в директорию и обращаться ко всем расположенным в ней файлам и каталогам. Обращаться можно при условии, что эти файлы доступны на чтение или запись или выполнение: например, если положить доступный на чтение файл в директорию с правом x, то вы сможете прочитать этот файл. Если же убрать с директории право x, то вы вовсе лишитесь доступа к файлу.
Но что тогда такое чтение? Здесь всё более интуитивно понятно: директория, по сути, является списком файлов, поэтому право на чтение позволяет прочитать этот список файлов, а именно вывести список имён файлов, содержащихся в директории. Однако, если хотите посмотреть не простой список имён файлов, а список с дополнительной информацией (как при выводе ls -l), то требуется ещё и право x, потому что в этом случае надо обращаться к файлам за их метаданными (владелец, группа, дата изменения, права и др.). В любом случае, без права r на каталог вы не сможете посмотреть его содержимое.
В литературе (статьях, книгах, мануалах) иногда используется другой способ описания прав доступа: 775. Это не одно число, а три числа, каждое из которых представляет собой группу rwx для наших типов пользователя в том же порядке: для владельца, входящих в группу и всех остальных. 0 — означает, что нет никаких прав для данного типа пользователей.
| A | B | C | D | |
|---|---|---|---|---|
| 1 | # | Permission | rwx | Binary |
| 2 | 7 | read, write and execute | rwx | 111 |
| 3 | 6 | read and write | rw- | 110 |
| 4 | 5 | read and execute | r-x | 101 |
| 5 | 4 | read only | r-- | 100 |
| 6 | 3 | write and execute | -wx | 011 |
| 7 | 2 | write only | -w- | 010 |
| 8 | 1 | execute only | --x | 001 |
drwxr-xr-x в числовой форме соответствует 755, а -rw-r--r-- — 644.
Однако пользователь root находится вне этой системы. Для него не имеет никакого значения наличие любых прав — рут может всё.