Перейти к содержимому
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after a top-up of $10 or more. Until Nov 30.

How it works

Права в Linux: пользователи, группы, chmod и umask

Владельцы и группы в Linux, биты rwx, chmod, umask и setuid, а также лабораторная, где доступ проверяется от имени второго пользователя и ищутся опасные режимы файлов.

Начальный11 мин чтенияАвтор: NotHoly

Права в Linux определяют, кто может читать, менять и запускать каждый файл в системе. Большинство проблем, которые встречаются на ревью безопасности, обходятся без экзотических эксплойтов: конфиг, в который может писать любой локальный аккаунт, скрипт, который запускает root-сервис, а редактировать может обычный пользователь, или бинарник с битом setuid, который никто не помнит, как добавлял. Эта статья собирает механизм снизу вверх: владельцы, группы, биты rwx, chmod, umask и специальные биты, которые важнее всего на ревью. Вы будете создавать файлы, менять их режимы, проверять доступ от имени второго локального пользователя в лабораторной VM и искать опасные права.

В основе лежит принцип наименьших привилегий. У процесса должен быть только тот доступ, который ему нужен, а писать в файл должны только люди и программы, которым положено его менять. Режимы файлов — первое место, где Linux применяет это правило, поэтому их и проверяют первыми.

Что такое право доступа к файлу

У каждого файла и каталога есть три вещи, от которых зависит доступ:

  1. Владелец, один аккаунт пользователя.
  2. Группа, один аккаунт группы.
  3. Режим, набор битов, который говорит, что могут делать владелец, группа и все остальные.

Выполните это на любом файле в домашнем каталоге:

bash
ls -l notes.txt

Первый символ — тип файла (- обычный файл, d каталог, l символическая ссылка). Следующие девять символов — режим. Имена владельца и группы идут после счётчика ссылок.

Ядро проверяет права каждый раз, когда процесс открывает файл. Оболочка, веб-сервер и задача cron проходят одну и ту же проверку. Если она не пройдена, вы получаете Permission denied. Файловой системе всё равно, доверенный процесс или нет.

Владельцы, группы и все остальные

В режиме три триплета, по одному на каждый класс пользователей:

  • Пользователь (u): аккаунт, которому принадлежит файл.
  • Группа (g): участники группы, которой принадлежит файл.
  • Остальные (o): любой аккаунт, который не владелец и не участник группы.

Linux проверяет классы по порядку. Если ваш аккаунт владелец, применяются биты владельца, а биты группы и остальных игнорируются, даже если они дали бы больше прав. Многих это удивляет. Файл с битами владельца --- не откроется для своего владельца, даже если биты группы равны rwx и владелец в этой группе состоит.

Членство в группах хранится отдельным списком. Своё можно проверить так:

bash
id
groups

Изменение членства в группе обычно вступает в силу при следующем входе. В оболочке, где вы выполнили команду, оно ещё не действует.

Как читать биты rwx

В каждом триплете три бита:

Бит На обычном файле На каталоге
r (чтение, значение 4) Читать содержимое Видеть список имён внутри
w (запись, значение 2) Менять содержимое Создавать, переименовывать и удалять записи
x (выполнение, значение 1) Запускать как программу Входить в каталог и обращаться к его записям

На двух вещах часто спотыкаются новички.

Во-первых, проходить через каталог позволяет его бит x. В каталоге с r без x видны имена, но открыть их нельзя. В каталоге с x, но без r можно открыть файл, точное имя которого вы уже знаете, а получить список нельзя.

Во-вторых, право записи в файл не даёт права его удалить. Удаление зависит от прав записи и выполнения на каталоге, где лежит запись. Файл, которым вы владеете, в каталоге без права записи удалить не получится.

Символьная и восьмеричная запись

chmod принимает две записи одного и того же.

Восьмеричная. Каждый триплет превращается в одну цифру, сумму его битов: r равен 4, w равен 2, x равен 1. Значит, rw- это 6, r-- это 4, r-x это 5, а rwx это 7. Режим 644 означает чтение и запись для владельца (6), чтение для группы (4), чтение для остальных (4). Режим 600 означает, что читать и писать может только владелец.

Символьная. Вы указываете класс, оператор и биты:

  • Классы: u (владелец), g (группа), o (остальные), a (все). Если класс не указан, подразумевается a, но биты umask при этом не затрагиваются.
  • Операторы: + добавляет биты, - убирает их, = выставляет в классе ровно эти биты и сбрасывает остальные.

Так, chmod u=rw,go=r notes.txt даёт тот же результат, что и chmod 644 notes.txt. chmod g+w notes.txt добавляет запись для группы и не трогает остальные биты.

Восьмеричная запись компактна, и её удобно вставлять в скрипты. Символьная безопаснее для одиночного изменения, потому что не стирает биты, о которых вы не подумали. На ревью ждите обе, в файлах управления конфигурацией, Dockerfile и установочных скриптах.

chmod шаг за шагом

chmod меняет режим. Успешно выполнить его на файле может только владелец или root. Остальные получат Operation not permitted.

Безопасная привычка — прочитать режим, изменить его и прочитать снова:

bash
stat -c '%a %A %U:%G %n' notes.txt
chmod 600 notes.txt
stat -c '%a %A %U:%G %n' notes.txt

stat -c печатает восьмеричный режим (%a), символьный режим (%A), имена владельца и группы (%U, %G) и имя файла (%n). Этот формат будет использоваться на всей лабораторной.

chown меняет владельца, а chgrp меняет группу. Для передачи файла другому пользователю обычно нужен root. Не запускайте chown -R на дереве, пока не посмотрите, что будет затронуто.

umask: режимы по умолчанию для новых файлов

Создавая файл, программа запрашивает начальный режим. Для обычного файла это 666, для каталога 777. umask убирает биты из этого начального значения. Его устанавливает оболочка, и через него проходит каждый файл и каталог, который создают оболочка и её дочерние процессы.

В большинстве дистрибутивов Linux значение по умолчанию равно 022. Для файла 666 минус 022 даёт 644, поэтому новые файлы получают rw-r--r--. Для каталога 777 минус 022 даёт 755, поэтому новые каталоги получают rwxr-xr-x. umask только убирает права. Режим никогда не станет шире начального значения.

Проверьте своё значение:

bash
umask

Более строгий umask вроде 077 даёт файлы 600 и каталоги 700, доступные только владельцу. Более свободный вроде 002 даёт файлы 664 и каталоги 775, в которые может писать группа. umask, заданный в профиле оболочки, действует на эту оболочку и её дочерние процессы. На уже существующие файлы он не влияет.

setuid, setgid и sticky-бит

Четырёхзначные восьмеричные режимы добавляют первую цифру для трёх специальных битов:

  • setuid (4000): исполняемый файл запускается с ID пользователя владельца файла, а не вызывающего. Принадлежащий root бинарник с setuid работает от root.
  • setgid (2000): исполняемый файл запускается с ID группы файла. В каталоге новые записи наследуют его группу.
  • sticky (1000): в каталоге переименовать или удалить запись могут только её владелец или root, даже если писать в каталог могут все. Классический пример — /tmp.

ls -l показывает setuid как s в позиции выполнения владельца, а sticky как t в позиции выполнения остальных. В Ubuntu 24.04 строка для passwd выглядит так:

text
-rwsr-xr-x 1 root root 64152 May 30  2024 /usr/bin/passwd

Программам вроде passwd нужен setuid, потому что они записывают защищённые файлы учётных записей от имени обычного пользователя. Риск в том, что каждый setuid-бинарник root даёт обычному пользователю выполнять код с правами root. Баг в одном из них, например повреждение памяти или небезопасный вызов вспомогательной программы, может привести к локальному повышению привилегий. Ревьюеры ведут короткий список setuid-бинарников и сравнивают его с известным эталоном. Новый setuid-файл, который никто намеренно не устанавливал, — находка, на которую нужен ответ.

Другая частая проблема — файлы, доступные на запись всем. Файл с o+w может изменить любой локальный аккаунт. Если это скрипт, конфиг, который читает root-сервис, или бинарник в каталоге из PATH, эксплойт атакующему не нужен. Он просто редактирует файл. Проверяйте и каталоги. Доступный на запись каталог на пути, который использует root, может позволить атакующему заменить файл, даже если сам файл закрыт.

Практическая лабораторная: файлы и права

Выполняйте это в среде Linux под вашим контролем: в дистрибутиве WSL или в VM, созданной для этого курса. Не запускайте на продакшен-сервере или общей машине. Раздел со вторым пользователем создаёт аккаунт, поэтому выполняйте его только в своей лабораторной VM.

Создание и просмотр файла

bash
mkdir ~/permlab && cd ~/permlab
echo 'lab secret' > notes.txt && ls -l notes.txt

В Ubuntu 24.04 под WSL новый файл показал -rw-r--r--, а владелец и группа были названы по имени аккаунта. Ваши имя пользователя, дата и группа будут другими. Сравнивайте режим.

Изменение режима

bash
chmod 600 notes.txt && stat -c '%a %U:%G %n' notes.txt
umask

Полученный вывод:

text
600 usurio:usurio notes.txt
0022

Имя вашего аккаунта будет другим. 600 означает, что читать и писать может только владелец. 0022 — это umask в текущей оболочке, и ведущий ноль входит в восьмеричную запись.

Теперь каталог:

bash
mkdir sub && chmod 750 sub && stat -c '%a %n' sub

Результат: 750 sub. У владельца полный доступ, группа может читать и входить, у остальных нет ничего.

Символьные изменения, по одному, с чтением после каждого:

bash
chmod u=rw,go=r notes.txt && stat -c '%a %A %n' notes.txt
chmod g+w notes.txt && stat -c '%a %A %n' notes.txt
chmod o-r notes.txt && stat -c '%a %A %n' notes.txt

Вывод:

text
644 -rw-r--r-- notes.txt
664 -rw-rw-r-- notes.txt
660 -rw-rw---- notes.txt

Каждая команда изменила только те биты, которые указаны в ней.

Как umask меняет новые файлы

Запускайте umask в подоболочке, чтобы изменение не осталось в сессии:

bash
(umask 077; touch private.txt; stat -c '%a %A %n' private.txt)
(umask 002; touch shared.txt; mkdir made_dir; stat -c '%a %A %n' shared.txt made_dir)

Вывод:

text
600 -rw------- private.txt
664 -rw-rw-r-- shared.txt
775 drwxrwxr-x made_dir

С 077 файл потерял все биты группы и остальных. С 002 группа получила запись и на файл, и на каталог. Каталог начинался с 777 и потерял только 002.

Проверка доступа от имени второго локального пользователя

Для этого шага нужен аккаунт, который можно создать в своей VM. Выполняйте его только там.

bash
sudo useradd -m labuser
sudo -u labuser cat ~/permlab/notes.txt

Эти команды я не запускал: аккаунту WSL нужен пароль для sudo, а его я не вводил. На что смотреть: при режиме 600 вторая команда должна завершиться сообщением Permission denied, потому что labuser не владелец и не входит в группу.

Теперь ослабьте права файла для остальных:

bash
chmod 644 notes.txt
sudo -u labuser cat ~/permlab/notes.txt

На что смотреть: содержимое напечатается, только если labuser может войти и в ваш домашний каталог, и в ~/permlab. Многие дистрибутивы создают домашние каталоги с 755, но некоторые используют 750. Если родительский каталог не даёт x остальным, чтение всё равно не удастся, даже если файл доступен для чтения. Проверьте с помощью ls -ld ~ ~/permlab. В установке Ubuntu 24.04 на WSL, которой я пользовался, ls -ld ~ напечатал drwxr-x---, то есть 750, поэтому второй пользователь был бы заблокирован и после chmod 644. Это тот самый бит x каталога на практике.

Поиск опасных прав

Выведите обычные файлы в домашнем каталоге, доступные на запись всем, не переходя на другие файловые системы:

bash
find ~ -xdev -type f -perm -o+w 2>/dev/null

В чистой лаборатории это ничего не выведет. Чтобы увидеть поиск в работе, намеренно откройте один файл на запись:

bash
chmod 666 ~/permlab/notes.txt
find ~ -xdev -type f -perm -o+w 2>/dev/null
chmod 644 ~/permlab/notes.txt

Результат: первый поиск напечатал /home/usurio/permlab/notes.txt. После исправления тот же поиск ничего не напечатал.

Выведите setuid-бинарники в системном каталоге:

bash
find /usr/bin -perm -4000 -type f 2>/dev/null | sort

В Ubuntu 24.04 под WSL команда напечатала десять файлов, среди них /usr/bin/passwd, /usr/bin/sudo, /usr/bin/su, /usr/bin/mount и /usr/bin/umount. Ваш список зависит от дистрибутива и установленных пакетов. На ревью сравнивайте список с тем, что по данным менеджера пакетов должно иметь setuid. Неожиданную запись считайте вопросом, на который нужен ответ. Доказательством атаки она ещё не служит.

Проверьте sticky-бит на временных каталогах:

bash
stat -c '%a %A %n' /tmp /var/tmp

Результат: 1777 drwxrwxrwt для обоих. t означает, что пользователи могут создавать там файлы, но не могут удалять чужие.

Очистка

bash
rm -rf ~/permlab
sudo userdel -r labuser

userdel -r удаляет и домашний каталог аккаунта. Запускайте это только для созданного вами лабораторного аккаунта.

Что показала проверка в Windows

Те же первые шаги в Git Bash для Windows вели себя не так, как в Linux. После chmod 600 notes.txt команда stat по-прежнему показывала 644, и следующие вызовы chmod вывод тоже не меняли. Windows хранит доступ в списках управления доступом NTFS, а Git Bash сопоставляет только часть битов. Лабораторная в Windows научит командам, но не покажет, что делает режим Linux. Для этой статьи используйте WSL с дистрибутивом Linux или VM.

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

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

Забытый каталог. Доступный на чтение файл может оказаться недостижимым, если у родительского каталога нет x для этого пользователя. Проверяйте каждый каталог на пути.

chmod -R на всём дереве. Рекурсивные изменения часто выставляют выполнение обычным файлам или убирают его у каталогов. Чтобы выбрать один тип, используйте find с -type f или -type d.

Доверие режиму скопированного файла. cp, tar и архиваторы могут сохранять или сбрасывать режимы в зависимости от флагов. Проверяйте результат с помощью stat.

Чтение символьных режимов как абсолютных. chmod g+w добавляет один бит. chmod g=w сбрасывает чтение и выполнение для группы. Разницу легко проглядеть.

Первым делом root. Многие проблемы с чтением и записью решаются членством в группе или режимом каталога, setuid-хелпер или root-оболочка для них не нужны.

Почему это важно на ревью безопасности

Ревью прав начинается с одного вопроса: кто может изменить то, что читает или запускает привилегированный процесс? Снова и снова встречаются три находки:

  1. Файлы на привилегированном пути, доступные на запись. Конфиг или скрипт, который читает root-сервис и в который может писать обычный аккаунт, — это повышение привилегий, ожидающее одной правки.
  2. Неожиданные бинарники с setuid или setgid. Каждый из них — код, который работает с большими правами, чем у вызывающего. Сравнивайте список с эталоном.
  3. Доступные на запись каталоги в пути поиска или каталоге сервиса. Пользователь, который может создать или переименовать там файл, может заменить доверенный файл, даже если сам файл закрыт.

Описывая находку, укажите путь, режим, владельца, группу, процесс, который читает или запускает файл, и изменение, которое всё исправляет. Тестируйте в своей лаборатории. Не запускайте эти поиски на системах, которые вы не администрируете, и не используйте sudo -u на чужой машине.

Что дальше

Когда базовые режимы станут понятны, изучите списки управления доступом с getfacl и setfacl, они добавляют записи для отдельных пользователей сверх владельца, группы и остальных. Прочитайте руководство chattr о флагах immutable и append-only. Используйте namei -l /path/to/file, чтобы напечатать режим каждого компонента пути. Так быстрее всего найти каталог, который блокирует сервис.

Чтобы освоить привычки работы в оболочке, на которых держатся эти команды, начните с более ранней статьи Полевого руководства Основы Bash для студентов по безопасности. Следующая статья, что такое SSH и как работают SSH-ключи, рассказывает о ключах SSH, которые зависят от тех же режимов: файл приватного ключа должен быть доступен на чтение только владельцу, а клиент SSH откажется использовать ключ со слишком открытым режимом.

Наименьшие привилегии начинаются с режимов файлов. Процесс, который может писать меньше, причиняет меньше вреда, когда ошибается, а файл, который не могут изменить другие, можно не проверять лишний раз.

Источники

Источники

  1. GNU Coreutils manual: File permissions
  2. chmod(1) manual page, Linux man-pages
  3. umask(2) manual page, Linux man-pages
  4. chmod, POSIX.1-2024 utility specification (The Open Group)

Ещё по теме: Linux и инструменты разработчика

Linux и инструменты разработчика

Основы Bash для работы в безопасности

Пайпы, перенаправление, переменные, циклы, коды завершения и set -euo pipefail, а затем подсчёт неудачных входов и хеширование папки на этой основе.

Начальный11 мин чтения

Linux и инструменты разработчика

Ключи SSH: как они работают и как пользоваться ими безопасно

Как работают ключи хоста и пользователя в SSH, почему по умолчанию стоит брать Ed25519 с парольной фразой и как настроить и защитить вход по ключу на своей лабораторной VM.

Начальный9 мин чтения