Спец-права: 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.