open atlas
↑ К треку
Linux: операционная система LIN · 05 · 02

права доступа глубже

За пределами rwx: setuid заставляет бинарник выполняться от имени владельца; setgid на каталоге принудительно наследует группу; sticky на /tmp не даёт удалять чужие файлы. umask отсекает права по умолчанию, а POSIX ACL дают доступ конкретным пользователям.

LIN Middle ◷ 22 min
Уровень
ОсновыJuniorMiddleSenior

Ты уже знаешь rwx. Но потом видишь /usr/bin/passwd с правами -rwsr-xr-x — буква s вместо бита выполнения это не опечатка. Или создаёшь общий каталог /var/project/, а файлы упорно оказываются во владении первичной группы создателя, и половина команды не может их изменить. Или пентестер говорит: «вот твой путь повышения привилегий — этот setuid-бинарник». Или аудит безопасности помечает мировой каталог без sticky-бита — и ты не сразу понимаешь угрозу. Модель rwx из девяти битов — это только пол; специальные биты и ACL выше неё — там живут реальные системы.

Цель

После этого урока ты сможешь объяснить, что делают биты setuid, setgid и sticky (с реальной моделью угроз), вычислить эффективные права из umask и предоставить доступ конкретному пользователю через POSIX ACL, когда членства в группе недостаточно.

1

Бит setuid заставляет бинарник выполняться от имени его владельца, а не вызывающего. Именно так непривилегированные пользователи могут менять собственные пароли: /usr/bin/passwd принадлежит root и имеет бит setuid, поэтому когда alice запускает его, effective UID процесса становится 0 (root), что позволяет записывать в /etc/shadow.

# Видим setuid в действии
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 59976 Feb  6 16:54 /usr/bin/passwd
#    ^-- строчная 's' на месте execute-бита владельца = setuid + исполняемый
#        заглавная 'S' означала бы setuid без права выполнения (бесполезно)

# Восьмеричное значение: setuid — бит 4 в старшем полубайте
stat -c '%a %n' /usr/bin/passwd
# 4755 /usr/bin/passwd
# 4 = setuid, 7 = rwx (владелец), 5 = r-x (группа), 5 = r-x (остальные)

# Найти все setuid-root бинарники в системе
find /usr/bin /usr/sbin /bin /sbin -perm -4000 -ls 2>/dev/null
# -rwsr-xr-x root   /usr/bin/passwd
# -rwsr-xr-x root   /usr/bin/sudo
# -rwsr-xr-x root   /usr/bin/su
# -rwsr-xr-x root   /usr/bin/newgrp

Каждый setuid-root бинарник — потенциальный вектор повышения привилегий. Если /usr/bin/customtool имеет уязвимость к инъекции команд или path traversal, атакующий может использовать его для запуска root-оболочки. Поэтому аудиты безопасности считают setuid-бинарники, а пентестеры целятся именно в них — один эксплуатируемый setuid-бинарник обходит все остальные контроли доступа.

2

Бит setgid на каталоге принудительно наследует группу. В обычном каталоге новые файлы получают первичный GID создателя. С setgid на каталоге новые файлы наследуют группу самого каталога — именно этот механизм делает общие каталоги проектов рабочими.

# Общий каталог без setgid — хаос с группами
mkdir /var/project
chown root:devteam /var/project
chmod 775 /var/project
# alice (первичная группа: alice) создаёт файл:
touch /var/project/notes.txt
ls -l /var/project/notes.txt
# -rw-rw-r-- 1 alice alice 0 ...   <- группа 'alice', не 'devteam'
# bob не может писать, хотя состоит в devteam

# Исправление: добавить setgid на каталог
chmod g+s /var/project
# или в восьмеричном: chmod 2775 /var/project
ls -ld /var/project
# drwxrwsr-x 2 root devteam 4096 ...   <- 's' на месте group-execute

# Теперь alice создаёт файл:
touch /var/project/report.txt
ls -l /var/project/report.txt
# -rw-rw-r-- 1 alice devteam 0 ...   <- группа 'devteam' унаследована!

# Setgid на исполняемом бинарнике имеет другой смысл:
# процесс выполняется с GID файла как effective GID (аналогично setuid)
# Пример: /usr/bin/wall имеет setgid 'tty', чтобы писать в терминалы
ls -l /usr/bin/wall
# -rwxr-sr-x 1 root tty 35048 ...

Каталоги с setgid — правильное решение для общих рабочих каталогов. Без него получается смесь владений разными группами и половина команды не может редактировать файлы друг друга.

3

Sticky-бит на каталоге не позволяет пользователям удалять чужие файлы. Без него любой пользователь с правом записи в каталог может удалить любой файл в нём — даже тот, которым он не владеет.

# /tmp — канонический пример: доступен всем для записи, но sticky
ls -ld /tmp
# drwxrwxrwt 20 root root 4096 ...
#          ^-- 't' на месте other-execute = sticky + world-executable
#              'T' = sticky без права выполнения для остальных (редко)

# Без sticky: alice может удалить файл bob, если у неё есть право записи в каталог
# С sticky:
# - можно удалять свои файлы
# - можно удалять файлы, которыми ВЛАДЕЕШЬ, независимо от других в каталоге
# - root может удалить всё
# - НЕЛЬЗЯ удалять файлы, принадлежащие другим

# Установить sticky-бит
chmod +t /var/shared
# восьмеричное: chmod 1777 /var/shared   (1 = sticky, 777 = rwxrwxrwx)
stat -c '%a %n' /var/shared
# 1777 /var/shared

# Реальная угроза: world-writable каталог БЕЗ sticky-бита
# Любой с правом записи может unlink() любой файл в каталоге
# Классическая атака: rm /var/run/app.pid ; ln -s /etc/cron.d/evil /var/run/app.pid
# Затем дождаться, когда приложение запишет свой PID — оно перезапишет /etc/cron.d/evil

Атака через симлинк — классика. World-writable каталог без sticky позволяет любому пользователю удалить файл, заменить его симлинком и ждать, пока привилегированный процесс запишет через него. Поэтому find / -type d -perm -0002 ! -perm -1000 (world-writable каталоги без sticky) — стандартная проверка аудита безопасности.

4

umask определяет биты прав, которые убираются из вновь создаваемых файлов и каталогов. Это маска битов для снятия, применяемая в момент создания.

# Посмотреть текущий umask
umask
# 0022

# Как вычисляются права новых файлов:
# Файлы начинаются с 0666 (rw-rw-rw-) — execute никогда не устанавливается по умолчанию
# Каталоги начинаются с 0777 (rwxrwxrwx)
# Эффективные = начальные & ~umask

# umask 022:
# ~022 = 755 (binary: 111101101)
# новый файл: 666 & ~022 = 666 & 755 = 644  (rw-r--r--)
# новый каталог: 777 & ~022 = 777 & 755 = 755  (rwxr-xr-x)

touch test_file && ls -l test_file
# -rw-r--r-- 1 alice alice 0 ...   <- 644, подтверждено

# Более строгий umask для общих сред:
umask 027    # убирает group write + все права остальных
# новый файл: 666 & ~027 = 666 & 750 = 640  (rw-r-----)
# новый каталог: 777 & ~027 = 777 & 750 = 750  (rwxr-x---)

# Установить umask в профиле оболочки для постоянства
echo 'umask 027' >> ~/.bashrc

# Системный умолчальный в /etc/login.defs (строка UMASK)
grep '^UMASK' /etc/login.defs
# UMASK    022

umask 022 означает «не давать группе и остальным право записи». umask 027 добавляет «и остальным не давать право чтения или выполнения». Сервисы, записывающие лог-файлы или временные файлы, наследуют umask демона — демон с umask 000 создаёт world-writable файлы, что является распространённой ошибкой в init-скриптах, не устанавливающих umask явно до сброса привилегий.

5

POSIX ACL позволяют давать права конкретным пользователям и группам за пределами модели из девяти битов. Когда нужно «alice, bob и группа ci-runner могут читать этот файл, но больше никто» — ACL дают такой ответ, который стандартная модель owner/group/other выразить не может.

# Установить инструменты ACL (обычно уже установлены)
apt install acl   # Debian/Ubuntu

# Дать alice права rw на файл, которым она не владеет
setfacl -m u:alice:rw /etc/app/config.conf
setfacl -m g:ci-runners:r /etc/app/config.conf

# Прочитать ACL
getfacl /etc/app/config.conf
# # file: etc/app/config.conf
# # owner: root
# # group: root
# user::rw-          <- права владельца (root)
# user:alice:rw-     <- alice получает rw
# group::r--         <- owning group (root) получает r
# group:ci-runners:r-- <- группа ci-runners получает r
# mask::rw-          <- потолок эффективных прав для именованных записей
# other::---         <- остальные ничего не получают

# Маска: именованные ACL-записи ANDируются с маской при применении
setfacl -m m::r /etc/app/config.conf  # теперь alice:rw & mask:r → эффективно r

# Удалить конкретную ACL-запись
setfacl -x u:alice /etc/app/config.conf

# Удалить все ACL (вернуть стандартные права)
setfacl -b /etc/app/config.conf

# ACL на каталогах: -d устанавливает умолчальные ACL, наследуемые новыми файлами
setfacl -d -m u:alice:rw /var/project/
# Новые файлы в /var/project/ унаследуют alice:rw

Символ + в конце вывода ls -l сигнализирует о наличии ACL (-rw-r--r--+). Маска — функция ACL, которая чаще всего удивляет операторов: если ты выполнишь chmod g+w file на файле с ACL, ты изменишь маску, что незаметно ограничит эффективные права всех именованных записей.

Разбор примера

Настройка общего каталога сборки, куда пишут и разработчики, и CI, но файлы всегда принадлежат группе проекта.

Цель: /var/builds/myapp/ — разработчики (группа dev) и CI-runner (пользователь ci-runner) оба могут писать. Файлы должны всегда принадлежать группе dev. Никто вне dev или ci-runner не должен ничего читать.

# Шаг 1: создать каталог с setgid и строгими правами
sudo mkdir -p /var/builds/myapp
sudo chown root:dev /var/builds/myapp
sudo chmod 2770 /var/builds/myapp
# 2 = setgid, 7 = rwx (владелец/root), 7 = rwx (группа/dev), 0 = --- (остальные)
ls -ld /var/builds/myapp
# drwxrws--- 2 root dev 4096 ...

# Шаг 2: дать ci-runner права через ACL (он не в группе dev)
sudo setfacl -m u:ci-runner:rwx /var/builds/myapp
sudo setfacl -d -m u:ci-runner:rwx /var/builds/myapp  # наследовать новым файлам

# Шаг 3: проверить
getfacl /var/builds/myapp
# user::rwx
# user:ci-runner:rwx
# group::rwx
# mask::rwx
# other::---
# default:user::rwx
# default:user:ci-runner:rwx
# default:group::rwx
# default:mask::rwx
# default:other::---

# Шаг 4: тест — ci-runner создаёт файл
sudo -u ci-runner touch /var/builds/myapp/artifact.tar.gz
ls -l /var/builds/myapp/artifact.tar.gz
# -rw-rw----+ 1 ci-runner dev 0 ...   <- группа 'dev' через setgid; + означает ACL

Комбинация setgid (наследование группы) и умолчального ACL (права конкретного пользователя, распространяющиеся на дочерние файлы) — идиоматическое решение для таких сценариев с несколькими владельцами.

Частая ошибка

Распространённая ошибка при установке ACL — забыть о маске. Если ты выполнишь setfacl -m u:alice:rw file, а затем chmod 644 file, ты только что установил маску в r-- (chmod на файле с ACL изменяет маску через биты группы). Запись rw для alice теперь имеет эффективное право r, потому что ANDируется с маской. Всегда перепроверяй getfacl после любого chmod на файле с ACL, чтобы убедиться, что эффективные права соответствуют ожиданиям.

Почему это работает

Почему sticky-бит имеет такое странное название? В оригинальном Unix на PDP-11 (начало 1970-х) sticky-бит означал «держать текстовый сегмент этой программы в свопе, даже когда она не запущена» — подсказка производительности для часто используемых бинарников. Современные ядра полностью игнорируют его на файлах (VM-подсистема справляется сама). Бит был переосмыслен для каталогов в BSD Unix: «только удаляй свои файлы». Linux унаследовал семантику для каталогов, но отказался от семантики для файлов. Поэтому man chmod до сих пор документирует оба значения — одно историческое, второе реально используемое.

Проверь себя
Викторина

Ты выполняешь 'umask 027', затем 'mkdir newdir'. Какие права получит newdir, и какими будут права нового файла, созданного командой 'touch newfile'?

Итог

За пределами rwx существуют три специальных бита. Setuid (4000) заставляет бинарник выполняться от имени его владельца — механизм /usr/bin/passwd и вектор повышения привилегий при злоупотреблении. Setgid (2000) на каталоге принудительно наследует группу для новых файлов — решение для общих рабочих каталогов. Sticky (1000) на world-writable каталоге не позволяет пользователям удалять чужие файлы — именно так работает /tmp. umask — это маска, применяемая при создании: файлы начинаются с 0666, каталоги с 0777, минус биты umask. POSIX ACL (setfacl/getfacl) добавляют права конкретным пользователям и группам за пределами модели из девяти битов; маска ACL ограничивает эффективные права именованных записей. Запусти chmod на файле с ACL — изменишь маску, а не только права группы.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.