Права доступа в Linux: как работают chmod, ACL и SELinux — и почему Permission denied не лечится цифрой 777

  • Автор темы Автор темы ADMIN
  • Дата начала Дата начала

ADMIN

Administrator
ADMIN
Регистрация
18 Окт 1989
Сообщения
1,408
Реакции
93
Баллы
48
☑ ДЕПОЗИТ
0$
Почему одного chmod почти никогда не хватает и как в реальности работают владелец, группы, ACL, capabilities и SELinux.

image

На файл уже выставили 777. Команда ls -l подтверждает: владелец, группа и остальные пользователи получили чтение, запись и выполнение. Попытка открыть файл снова заканчивается тем же сообщением: Permission denied.

Причина обычно не в том, что Linux «не заметил» новые права. Биты rwx описывают лишь одну проверку из нескольких. Ядро должно сопоставить файл с идентификаторами процесса, пройти по каждому каталогу в пути, учесть ACL, атрибуты объекта, режим файловой системы, capabilities и, если механизм включён, политику SELinux или AppArmor.

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

Начинать разбор такого отказа с очередного chmod бессмысленно. Сначала нужно понять, какой процесс обращается к объекту и на каком слое доступ обрывается.

Твои секреты лайкают в даркнете.
Прячь.

Три набора прав и один конкретный процесс​

В базовой модели Linux каждый файл и каталог хранит права для трёх категорий: владельца, группы и всех остальных. Категория выбирается не по имени человека, который смотрит на экран, а по UID и группам процесса, выполняющего операцию.

Строка из ls -l может выглядеть так:

-rw-r----- 1 alice developers 2048 Apr 30 10:15 report.txt

Первый символ показывает тип объекта. Знак - обозначает обычный файл, d появляется у каталога, l у символической ссылки. Следующие девять символов разбиваются на три тройки:

rw- r-- ---
Владелец alice читает и изменяет report.txt. Группа developers получает только чтение. Любой пользователь вне этой группы не получает доступа.

Команда chmod меняет наборы rwx, но не передаёт файл другому владельцу и не назначает новую группу. Для этого служат chown и chgrp:

chown alice:developers report.txt

Почему права файла не объясняют доступ к пути​

Для обычного файла буквы читаются привычно. r разрешает получить содержимое, w позволяет его изменить, x даёт запускать файл как программу. Скрипт без x можно открыть в редакторе или передать интерпретатору, но прямой вызов через ./script.sh завершится отказом.

С каталогами действуют другие правила. Бит r разрешает вывести список находящихся внутри имён. Бит w позволяет добавлять, удалять и переименовывать записи. Бит x нужен для прохода через каталог к вложенному объекту.

Именно x чаще всего объясняет ситуацию, когда файл «открыт», но не открывается. Процесс может знать точное имя объекта и видеть корректные права конечного файла, однако каталог без права прохода не позволит обратиться к нему.

Допустим, приложению нужен файл /srv/app/config.yml. Для чтения мало разрешения r на самом config.yml. Процесс должен пройти через /srv, затем через /srv/app. Если хотя бы на одном из этих каталогов не хватает x, ядро вернёт отказ ещё до проверки содержимого файла.

По этой причине одиночная команда ls -l /srv/app/config.yml нередко показывает правду, но не показывает причину сбоя. Проверять нужно весь путь.

Что означают числа в chmod​

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

В числовой записи каждому действию соответствует значение: чтение получает 4, запись 2, выполнение 1. Значения складываются внутри каждой тройки. Поэтому rwx обозначается цифрой 7, rw- цифрой 6, r-- цифрой 4, а отсутствие прав записывается как 0.

chmod 640 report.txt
Режим 640 даёт владельцу чтение и запись, группе оставляет чтение, для остальных закрывает файл полностью. Для конфигурации сервиса, файла с настройками приложения или внутреннего отчёта такой режим обычно соответствует задаче точнее, чем открытие объекта всем пользователям системы.

Когда лучше менять один бит, а не весь режим​

Символьная запись chmod позволяет указать адресата и конкретное изменение. Буква u относится к владельцу, g к группе, o к остальным, a ко всем трём категориям. Знак + добавляет разрешение, - снимает, = заменяет текущий набор заданным.

chmod g+w shared.txt<br>chmod o-r secret.txt<br>chmod u=rw,g=r,o= file.txt
Команда chmod o-r secret.txt удаляет чтение только у посторонних пользователей. Владельца и группу правка не касается. На рабочем сервере такая операция предсказуемее, чем назначение нового числового режима, который случайно снимет нужный бит или, наоборот, откроет лишний.

Одинаковые цифры не означают одинаковый доступ​

Режим файла нельзя читать в отрыве от владельца и группы. Два объекта с правами 640 могут дать одному процессу разные результаты, поскольку ядро сначала выяснит, относится ли процесс к группе конкретного файла.

-rw-r----- 1 root nginx 1200 site.conf<br>-rw-r----- 1 root mysql 1200 database.conf
Процесс, входящий в группу nginx, прочитает site.conf. Файл database.conf для него останется закрытым, если процесс не входит также в группу mysql. Цифры совпадают. Решение меняет групповая принадлежность.

Отсюда возникает ещё один знакомый отказ. Администратор добавляет пользователя в группу, после чего доступ всё равно не появляется. Уже работающая оболочка сохраняет список групп, полученный при старте сессии. Новый состав начинает действовать после повторного входа или запуска newgrp:

usermod -aG docker alice<br>newgrp docker
Проверять нужно не сам факт записи пользователя в группу, а полномочия процесса, который прямо сейчас пытается открыть файл.

Почему удаление файла зависит от каталога​

При удалении Linux меняет не содержимое файла, а запись о нём в каталоге. Каталог связывает имя объекта с inode, поэтому решающими становятся права на родительскую директорию.

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

Для каталогов с совместной записью предусмотрен sticky bit. Его можно увидеть на примере /tmp:

drwxrwxrwt 10 root root 4096 /tmp
Последняя буква t показывает, что sticky bit включён. Пользователи создают файлы в каталоге, однако удалить чужой объект может только владелец файла, владелец каталога или root. Без такого ограничения общий временный каталог позволял бы одному пользователю очищать данные другого.

SUID и SGID: особые биты доступа​

Помимо обычных rwx, Linux поддерживает специальные биты. В строке прав их выдают символы s и t.

Бит SUID на исполняемом файле запускает программу с эффективными правами владельца файла. Утилита passwd служит классическим примером. Пользователь должен менять собственный пароль, хотя прямой доступ к системному хранилищу хешей ему не разрешён.

-rwsr-xr-x 1 root root /usr/bin/passwd
Символ s на месте пользовательского x указывает на SUID. Программа получает нужные полномочия во время выполнения предусмотренной операции.

Для общего каталога часто полезнее SGID. Если включить такой бит на директории, новые файлы наследуют её группу, а не основную группу пользователя, который создал объект:

chgrp developers /srv/shared<br>chmod g+s /srv/shared
После настройки файлы внутри /srv/shared будут создаваться с группой developers. Для проектных каталогов такой режим снимает постоянную необходимость вручную исправлять групповую принадлежность.

SUID требует осторожности. Уязвимость в программе, работающей с правами владельца root, способна превратиться в повышение привилегий. Поэтому узкие задачи всё чаще решают через capabilities, а не через запуск программы с полным набором административных возможностей.

umask: почему новый файл получает не те права, которые ожидали​

Команда chmod работает с уже существующим объектом. При создании новых файлов и каталогов в игру вступает umask. Маска снимает часть разрешений из набора, который запросило приложение.

umask<br>0022
При маске 0022 обычный файл чаще всего появляется с правами 644, а каталог с 755. Владелец может менять содержимое, группа и остальные получают чтение без записи.

Для общей рабочей директории нередко используют маску 0002, чтобы участники группы могли редактировать созданные коллегами файлы:

umask 0002
У служб маска может отличаться от настроек интерактивной оболочки администратора. В systemd её задаёт директива UMask внутри unit-файла. Поэтому приложение способно создавать слишком закрытые файлы не из-за ошибки в своём коде, а из-за параметров запуска службы.

ACL: права для пользователей вне основной группы​

Трёх стандартных категорий иногда недостаточно. Файл может принадлежать alice и группе developers, тогда как сотруднику bob требуется чтение одного конкретного отчёта без включения в рабочую группу. Такой доступ задают через ACL, расширенные списки прав.

Посмотреть действующие правила можно командой getfacl:

getfacl report.txt
Доступ на чтение для отдельного пользователя добавляется так:

setfacl -m u:bob:r report.txt
Для отдельной группы применяется похожая запись:

setfacl -m g:auditors:rx /srv/reports
Присутствие расширенных правил видно в выводе ls -l по знаку + после стандартных битов:

-rw-r-----+ 1 alice developers 2048 report.txt
Если строка содержит такой знак, одной проверки chmod уже недостаточно. Реальное решение может зависеть от ACL, скрытой за обычной тройкой прав.

У ACL есть маска, которая задаёт верхнюю границу доступа для именованных пользователей и групп. Отдельная запись может содержать rwx, но эффективные права окажутся уже, если маска разрешает только чтение и выполнение:

setfacl -m m::rx /srv/reports
Каталогам можно назначить ACL по умолчанию. Тогда новые файлы и вложенные директории получат правила автоматически:

setfacl -d -m g:developers:rwx /srv/project
При неожиданном отказе или неожиданно широком доступе проверка ACL должна идти сразу после просмотра обычных прав.

Проверяется процесс, а не имя пользователя​

Linux принимает решение по идентификаторам процесса. У каждого процесса есть реальный и эффективный UID, основная группа и набор дополнительных групп. При обычном запуске значения обычно совпадают с учётной записью пользователя. После sudo, SUID, запуска через systemd или работы внутри контейнера совпадение исчезает.

Полномочия текущей оболочки показывает команда id:

uid=1000(alice) gid=1000(alice) groups=1000(alice),1001(developers)
Сервисные процессы часто вводят администратора в заблуждение. Команда, запущенная вручную, успешно читает конфигурацию. Та же программа, стартовавшая через systemd от www-data, получает отказ. Файл не изменился. Изменился процесс, от имени которого идёт обращение.

Владельца уже работающего процесса можно проверить так:

ps -o user,group,comm -p 1234

Почему root тоже получает Permission denied​

В классической Unix-модели root обходит почти все ограничения обычных прав. Современный Linux добавляет механизмы, способные остановить и административный процесс: SELinux, AppArmor, пространства имён, параметры монтирования, специальные атрибуты файлов и ограниченный набор capabilities.

Файл с атрибутом immutable нельзя изменить или удалить, пока атрибут не снят. Одни только права rwx такого отказа не объяснят:

lsattr config.yml<br>----i--------- config.yml<br><br>chattr -i config.yml
Ограничения файловой системы действуют ещё прямее. Раздел с параметром noexec не позволит напрямую запустить исполняемый файл, хотя бит x будет присутствовать. Параметр ro запрещает запись независимо от режима конкретного объекта:

mount | grep /srv
В контейнере root также не обязан совпадать с root хостовой системы. Пространства имён, профили безопасности и параметры запуска могут оставить контейнерному процессу только ограниченный набор полномочий.

Capabilities: выдача отдельных привилегий вместо полного root​

Capabilities делят административные полномочия на отдельные разрешения. Веб-серверу, например, не обязательно работать от root целиком, если от административного режима ему нужна только возможность слушать порт ниже 1024.

Право привязки к порту 80 можно назначить бинарному файлу отдельно:

setcap 'cap_net_bind_service=+ep' /usr/local/bin/myserver<br>getcap /usr/local/bin/myserver
При компрометации такого сервиса атакующий получает конкретную выданную возможность, а не все полномочия root. Ограничение работает лишь тогда, когда capability действительно узкая.

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

Поэтому при аудите исполняемых файлов искать нужно не только SUID, но и capabilities:

getcap -r /usr/bin /usr/local/bin 2&gt;/dev/null

SELinux: правильные права ещё не гарантируют доступ​

SELinux добавляет мандатную политику поверх классических Unix-прав. Обычные биты отвечают на вопрос, разрешён ли доступ владельцу, группе или остальным. SELinux проверяет, вправе ли процесс конкретного типа выполнять нужную операцию с объектом конкретного типа.

Поэтому файл с режимом 644, ожидаемым владельцем и подходящей группой всё равно может вернуть Permission denied. Для SELinux решающим становится контекст безопасности:

ls -Z /var/www/html<br>-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html
В данном контексте ключевую роль играет тип httpd_sys_content_t. Политика разрешает веб-серверу httpd читать файлы такого типа, поскольку они относятся к публикуемому содержимому сайта.

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

semanage fcontext -a -t httpd_sys_content_t '/srv/site(/.*)?'<br>restorecon -Rv /srv/site
SELinux поддерживает три режима. Enforcing блокирует действия, запрещённые политикой. Permissive пропускает операции, но записывает нарушения в журнал. Disabled полностью отключает механизм.

getenforce<br>sestatus
На системах семейства RHEL, Fedora и CentOS Stream SELinux встречается регулярно и часто включён по умолчанию. В Debian и Ubuntu чаще применяют AppArmor: задача похожа, правила и инструменты отличаются.

Как разбирать отказы SELinux без отключения защиты​

При первом отказе SELinux легко принять механизм защиты за источник проблемы и просто выключить его. Такой шаг убирает блокировку вместе с контролем, но не объясняет, какое действие приложение пыталось выполнить и почему политика его остановила.

События отказа ищут в журнале:

ausearch -m avc -ts recent<br>journalctl -t setroubleshoot
Запись AVC обычно содержит домен процесса, тип объекта, запрошенное действие и результат проверки. Веб-сервер, например, может пытаться записать данные в каталог, помеченный как статическое содержимое. Читать такие файлы политика разрешает, изменять их запрещает.

Если приложению действительно требуется каталог для загрузок, каталогу назначают тип, допускающий запись со стороны веб-процесса. Для httpd используется httpd_sys_rw_content_t:

semanage fcontext -a -t httpd_sys_rw_content_t '/srv/site/uploads(/.*)?'<br>restorecon -Rv /srv/site/uploads
Политика при такой настройке продолжает работать. Запись открывается только для каталога, которому она нужна по назначению.

Как искать причину Permission denied​

Отказ доступа лучше разбирать последовательно, не меняя права наугад. Сначала нужно узнать, от чьего имени работает процесс. Для команды в терминале подходит id; для службы потребуется проверить unit systemd и владельца запущенного процесса.

Следом проверяют весь путь к объекту. Команда namei -l показывает права каждого каталога и файла в цепочке:

namei -l /srv/site/config.yml
Такой вывод быстро обнаруживает каталог без x, который невозможно заметить по правам одного только config.yml.

После пути проверяются обычные права и ACL:

ls -l /srv/site/config.yml<br>getfacl /srv/site/config.yml
Затем нужно исключить ограничения точки монтирования и специальные атрибуты:

mount | grep /srv<br>lsattr /srv/site/config.yml
В системе с SELinux дополнительно проверяют активный режим, контекст объекта и свежие события AVC:

getenforce<br>ls -Z /srv/site/config.yml<br>ausearch -m avc -ts recent
Такой порядок показывает, где оборвался доступ, и позволяет исправить конкретную причину вместо беспорядочной смены разрешений.

Рабочие режимы для типовых задач​

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

chmod 644 public.txt<br>chmod 600 secret.key
Каталог с публично читаемым содержимым обычно получает 755. Закрытая директория пользователя подходит под режим 700:

chmod 755 /srv/site<br>chmod 700 /home/alice/private
Для совместной работы над проектом пригодится общая группа, SGID и наследуемые ACL:

chgrp developers /srv/project<br>chmod 2775 /srv/project<br>setfacl -d -m g:developers:rwx /srv/project
Режим 2775 включает SGID на каталоге и сохраняет групповую запись. Новые объекты получают группу проекта, а ACL задаёт нужные права для создаваемых внутри файлов и подкаталогов.

Для ключей SSH требования строже. Клиент не станет использовать приватный ключ, доступный группе или посторонним пользователям:

chmod 700 ~/.ssh<br>chmod 600 ~/.ssh/id_ed25519<br>chmod 644 ~/.ssh/id_ed25519.pub
Веб-сайту не нужен режим 777 на всём дереве каталогов. Код и статические файлы можно оставить веб-процессу только для чтения, а запись разрешить в отдельной директории загрузок:

chown -R root:nginx /srv/site<br>chmod -R u=rwX,g=rX,o= /srv/site<br>chown -R nginx:nginx /srv/site/uploads<br>chmod -R u=rwX,g=rwX,o= /srv/site/uploads
При включённом SELinux для каталога загрузок потребуется также назначить тип, который разрешает запись веб-серверу.

Почему chmod 777 редко исправляет проблему​

Команда chmod 777 выдаёт чтение, запись и выполнение владельцу, группе и всем остальным пользователям системы. Если отказ вызван каталогом без права прохода, ACL, параметром ro, атрибутом immutable или политикой SELinux, такая команда ничего не починит.

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

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

Где заканчиваются возможности chmod​

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

Веб-процесс не должен записывать код приложения. Конфигурационные файлы требуется открывать только службе и административной группе. Загрузки следует хранить отдельно от исполняемых компонентов. Сервису лучше работать от выделенного пользователя, capabilities выдавать точечно, а обращения за пределами ожидаемого сценария ограничивать через SELinux или AppArmor.

Такая схема не устраняет уязвимость в приложении, если она уже существует, но сокращает последствия компрометации. Захваченный веб-процесс не сможет беспрепятственно переписать код, изменить конфигурацию или читать соседние каталоги.

Файл с режимом 777 и сообщением Permission denied требует проверки пути, процесса, ACL, точки монтирования и политики доступа, а не ещё одной попытки открыть всё всем.

Полезные ссылки​

Базовые правила описаны в страницах руководства chmod, chown и acl. Для работы с мандатными политиками пригодятся материалы SELinux Project и документация Red Hat по SELinux.
 
Защита от мошенничества: Использование посредника минимизирует риски столкнуться с «продавцами-однодневками» или недобросовестными заказчиками, которые исчезают после получения предоплаты или результата работы.
Назад
Сверху