Спец-права: SUID, SGID, sticky bit и ACL

Углубляемся в права доступа: восстанавливаем числовую и символьную запись, разбираем особые биты SUID/SGID/sticky на реальных примерах (passwd, общие каталоги, /tmp) и добавляем гибкие права через ACL.

SUID — бит, заставляющий программу выполняться с правами её ВЛАДЕЛЬЦА, а не запустившего пользователя. sticky bit на каталоге запрещает удалять чужие файлы, даже если каталог общий.

Зачем это знать на практике

Почему обычный пользователь может сменить себе пароль, хотя файл /etc/shadow доступен только root? Почему в общем каталоге команды все создают файлы, но никто не может стереть чужой? Почему один лишний бит на скрипте — это дыра, через которую получают root? Ответы — в специальных битах прав. А ACL нужны, когда классической модели «владелец-группа-остальные» не хватает.

Числовая и символьная запись: освежаем

Права делятся на три набора: для владельца (u), группы (g) и остальных (o). В каждом — чтение (r=4), запись (w=2), исполнение (x=1). Сумма даёт цифру: rwx=7, rw-=6, r-x=5.

chmod 640 secret.conf       # rw- r-- ---  (владелец r/w, группа r, прочие ничего)
chmod u=rw,g=r,o= secret.conf  # то же самое символьно
chmod g+x,o-r script.sh     # точечно: добавить группе x, снять у прочих r
ls -l secret.conf
# -rw-r----- 1 user staff ... secret.conf

Для каталога x означает не «исполнить», а право входить в каталог; r — читать список имён; w — создавать и удалять записи. Поэтому каталог почти всегда нуждается в x.

Специальные биты: четвёртая цифра

Перед обычными тремя цифрами есть четвёртая — для особых битов: SUID=4, SGID=2, sticky=1.

SUID (4xxx) — выполнить от имени владельца

Классический пример — /usr/bin/passwd. Менять пароль = писать в /etc/shadow, владелец которого root. Бит SUID разрешает любому пользователю запустить passwd с правами root — но только в рамках этой программы.

ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
#    ^ s вместо x в наборе владельца = SUID

chmod u+s myprog        # символьно
chmod 4755 myprog       # числом: 4 = SUID, далее 755

Маленькая s в позиции исполнения владельца — это SUID. Если файл при этом НЕ исполняемый, увидите большую S (бит стоит, но «вхолостую»).

SGID (2xxx) — наследование группы в каталоге

На исполняемом файле SGID работает аналогично SUID, но для группы. Куда полезнее SGID на каталоге: все файлы, созданные внутри, автоматически получают группу каталога (а не основную группу автора). Это идеальный приём для совместной папки проекта:

sudo mkdir /srv/project
sudo chgrp developers /srv/project
sudo chmod 2775 /srv/project          # 2 = SGID
ls -ld /srv/project
# drwxrwsr-x 2 root developers ... /srv/project
#       ^ s в наборе группы = SGID на каталоге

Теперь любой файл, созданный членом группы developers в этом каталоге, унаследует группу developers, и коллеги смогут его читать/править без ручного chgrp.

sticky bit (1xxx) — защита от удаления чужого

Эталон — каталог /tmp. Он доступен на запись всем (rwx для всех), иначе общие временные файлы не создать. Но без защиты любой стёр бы чужие файлы. Sticky bit меняет правило: удалить файл в каталоге может только владелец файла (или владелец каталога, или root), даже если у каталога w для всех.

ls -ld /tmp
# drwxrwxrwt 10 root root ... /tmp
#          ^ t на месте x для остальных = sticky bit

sudo chmod +t /shared        # включить sticky
sudo chmod 1777 /shared      # числом: 1 = sticky, далее 777

Буква t в позиции исполнения «остальных» — это sticky bit.

ACL: когда трёх наборов мало

Модель «владелец-группа-остальные» неудобна, если нужно дать доступ ОДНОМУ конкретному пользователю или нескольким разным группам с РАЗНЫМИ правами. Тогда подключают ACL (Access Control List) — список точечных правил поверх обычных прав.

setfacl -m u:alice:rw report.txt      # дать alice чтение+запись
setfacl -m g:auditors:r report.txt    # группе auditors — только чтение
getfacl report.txt
# user::rw-
# user:alice:rw-
# group::r--
# group:auditors:r--
# mask::rw-
# other::r--

Наличие ACL помечается плюсом в выводе ls -l (-rw-rw-r--+). Для каталогов задают «ACL по умолчанию» (setfacl -d), которые наследуются новыми файлами. Снять всё — setfacl -b file.

Как это работает под капотом

Биты SUID/SGID/sticky и обычные права — это режим файла (mode), хранящийся прямо в inode (то самое число 0644 или 04755). Когда ядро запускает программу с установленным SUID, оно подменяет эффективный идентификатор пользователя процесса на UID владельца файла — отсюда временно повышенные права. Реальный UID при этом остаётся вашим, поэтому программа может при желании понизить привилегии обратно. ACL хранятся в расширенных атрибутах файла (xattr), а поле mask в выводе getfacl ограничивает максимум прав, который могут получить именованные пользователи и группы — это предохранитель.

Частые ошибки

  • SUID на скрипте или своей программе «чтобы работало от root». Это серьёзная уязвимость: ошибка в такой программе = root-доступ для атакующего. Современные ядра вообще игнорируют SUID на интерпретируемых скриптах. Используйте sudo с точечными правилами вместо SUID.
  • Забыть SGID на общем каталоге. Без него файлы получают основную группу автора, и коллеги теряют доступ — «у меня создалось, а ты не видишь».
  • Путать sticky bit на файле и на каталоге. На современных Linux sticky на обычном файле игнорируется; смысл он имеет только на каталоге.
  • Делать аудит SUID-программ. Лишние SUID-бинарники — типовая цель атак. Список: find / -perm -4000 -type f 2>/dev/null.

Итоги

  • Права — три набора (u/g/o) по r=4, w=2, x=1; на каталоге x = право входить, w = создавать/удалять записи.
  • SUID (4) запускает программу с правами владельца — так работает passwd; на своих скриптах это опасно.
  • SGID (2) на каталоге заставляет новые файлы наследовать его группу — приём для общих папок.
  • sticky bit (1) на общем каталоге (/tmp) разрешает удалять только свои файлы.
  • ACL (setfacl/getfacl) дают точечные права отдельным пользователям и группам, когда трёх наборов мало; их выдаёт + в ls -l.
Проверьте себя
1. Почему обычный пользователь может сменить себе пароль через /usr/bin/passwd, хотя файл /etc/shadow доступен на запись только root?
AНа /etc/shadow стоит sticky bit
BНа passwd установлен бит SUID, поэтому программа выполняется с правами своего владельца — root
Cpasswd временно делает пользователя членом группы root
DФайл /etc/shadow на самом деле доступен всем на запись
2. Что делает sticky bit на каталоге /tmp (drwxrwxrwt)?
AЗапрещает всем, кроме root, создавать файлы в каталоге
BЗаставляет новые файлы наследовать группу каталога
CРазрешает удалить файл только его владельцу (либо владельцу каталога/root), несмотря на общий доступ на запись
DШифрует все файлы внутри каталога