Задача клиента
К нам обратилась юридическая компания из Новосибирска — 80 сотрудников, работа с конфиденциальными документами клиентов, персональными данными и судебными материалами. Причина обращения: внешний аудит безопасности выявил критические нарушения в управлении доступом на Linux-серверах компании.
Аудиторы обнаружили следующие проблемы:
- 12 пользователей имели полный sudo без ограничений — включая стажёров и уволенных сотрудников
- Права 777 на каталогах с документами клиентов — любой пользователь мог читать и изменять чужие дела
- 5 учётных записей уволенных сотрудников не были заблокированы — они всё ещё могли подключиться по SSH
- Отсутствие политики паролей — некоторые пароли не менялись более 2 лет
- Нет аудита действий — невозможно отследить, кто и когда обращался к конфиденциальным файлам
Компания рисковала не только утечкой данных, но и штрафами по 152-ФЗ. Нам поставили задачу: полностью перестроить систему управления доступом за одну рабочую неделю, не нарушая работу юристов.
Аудит текущей ситуации: что мы обнаружили
В Linux каждый процесс и каждый файл принадлежат определённому пользователю и группе. Система контроля доступа основана на трёх уровнях: владелец (user), группа (group), остальные (others). У клиента эта система была настроена хаотично.
Ревизия файлов учётных записей
Мы начали с анализа четырёх ключевых файлов, в которых хранится информация о пользователях:
# /etc/passwd — список пользователей
# Формат: имя:пароль:UID:GID:комментарий:домашний_каталог:оболочка
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
john:x:1001:1001:John Smith:/home/john:/bin/bash
# /etc/shadow — хеши паролей (доступен только root)
# Формат: имя:хеш:дата_смены:мин_дней:макс_дней:предупреждение:неактивность:истечение
john:$6$rounds=656000$salt$hash...:19813:0:90:7:30::
# /etc/group — группы
www-data:x:33:
developers:x:1100:john,alice,bob
# /etc/gshadow — пароли групп (редко используется)
developers:!::john,alice,bob
Мы обнаружили, что UID 0 был только у root (это нормально). Но системных пользователей (UID 1-999) было создано избыточно, а обычных пользователей (UID 1000+) — 93, из которых 13 уже не работали в компании.
Диагностика с помощью стандартных команд
Вот команды, которые мы использовали для быстрой диагностики:
# Информация о текущем пользователе
$ id
uid=1001(john) gid=1001(john) groups=1001(john),27(sudo),33(www-data),1100(developers)
# Информация о другом пользователе
$ id alice
uid=1002(alice) gid=1002(alice) groups=1002(alice),1100(developers)
# Список групп пользователя
$ groups john
john : john sudo www-data developers
# Кто сейчас залогинен
$ who
john pts/0 2026-03-31 10:15 (10.0.0.100)
alice pts/1 2026-03-31 09:30 (10.0.0.101)
# Последние входы
$ last -10
john pts/0 10.0.0.100 Mon Mar 31 10:15 still logged in
alice pts/1 10.0.0.101 Mon Mar 31 09:30 still logged in
# Неудачные попытки входа
$ lastb -10
admin ssh:notty 185.220.101.1 Mon Mar 31 08:12 - 08:12 (00:00)
Команда lastb показала тысячи попыток подбора паролей с внешних IP — ещё одна причина усилить безопасность.
Наведение порядка: создание правильной структуры пользователей
Мы выстроили чёткую иерархию пользователей и групп, отражающую структуру юридической компании: партнёры, юристы, помощники, IT-отдел, бухгалтерия.
Создание пользователей с правильными параметрами
Вот как мы создавали новые учётные записи и исправляли существующие:
# Создание пользователя с домашней директорией и bash
useradd -m -s /bin/bash -c "John Smith" john
passwd john
# Создание пользователя с конкретным UID и группами
useradd -m -u 1500 -g developers -G sudo,www-data -s /bin/bash -c "Alice Brown" alice
# Создание системного пользователя (для сервиса)
useradd -r -s /usr/sbin/nologin -d /opt/myapp -c "MyApp Service" myapp
# Создание с указанием срока действия аккаунта
useradd -m -s /bin/bash -e 2026-12-31 -c "Temporary contractor" contractor
# Создание с готовым хешем пароля
HASH=$(openssl passwd -6 'SecurePass123')
useradd -m -s /bin/bash -p "$HASH" newuser
# Массовое создание из файла
while IFS=: read -r user comment; do
useradd -m -s /bin/bash -G developers -c "$comment" "$user"
echo "$user:$(openssl rand -base64 12)" | chpasswd
echo "Created: $user"
done < users.txt
Для стажёров мы использовали параметр -e с датой окончания стажировки — аккаунт блокируется автоматически.
Корректировка существующих учётных записей
Для 80 существующих пользователей мы провели массовую корректировку:
# Добавить пользователя в группу (флаг -a важен!)
usermod -aG sudo john
usermod -aG docker,www-data john
# БЕЗ флага -a пользователь будет УДАЛЁН из всех групп кроме указанной!
# usermod -G docker john # ОПАСНО! Удалит из sudo и остальных
# Изменить оболочку
usermod -s /bin/zsh john
# Переименовать пользователя
usermod -l john_smith john
# Изменить домашнюю директорию (и переместить файлы)
usermod -d /home/john_smith -m john_smith
# Заблокировать учётную запись
usermod -L john # Добавляет ! перед хешем пароля
# Или установить nologin shell
usermod -s /usr/sbin/nologin john
# Разблокировать
usermod -U john
# Установить дату истечения аккаунта
usermod -e 2026-06-30 contractor
# Проверить статус
$ chage -l john
Last password change : Mar 31, 2026
Password expires : Jun 29, 2026
Account expires : never
Minimum number of days between changes : 0
Maximum number of days between changes : 90
Мы заблокировали 13 учётных записей уволенных сотрудников и установили срок действия паролей для всех остальных.
Блокировка уволенных и управление группами
Для каждого уволенного сотрудника мы выполнили процедуру деактивации:
# Удалить пользователя (без домашней директории)
userdel john
# Удалить пользователя с домашней директорией и почтой
userdel -r john
# Перед удалением — проверяем, нет ли запущенных процессов
ps -u john
# Если есть — завершаем
killall -u john
# Найти все файлы пользователя
find / -user john -ls 2>/dev/null
# Создание группы
groupadd -g 1100 developers
# Изменение группы
groupmod -n dev developers # Переименовать
groupmod -g 1200 dev # Изменить GID
# Удаление группы
groupdel dev
# Добавить пользователя в группу напрямую через gpasswd
gpasswd -a john developers
gpasswd -d john developers # Удалить из группы
# Назначить администратора группы
gpasswd -A john developers # John может управлять членством
Мы создали группы, соответствующие отделам: partners, lawyers, assistants, it-dept, accounting — и распределили пользователей по ним.
Исправление прав доступа: от 777 к правильной модели
Система прав доступа в Linux основана на трёх битах для каждого уровня: чтение (r=4), запись (w=2), выполнение (x=1). У клиента эта система была полностью проигнорирована.
Разбор прав доступа для IT-отдела клиента
Мы провели обучение IT-специалиста клиента. Вот что мы объяснили на реальных примерах:
$ ls -la /var/www/
total 16
drwxr-xr-x 4 root root 4096 Mar 31 10:00 .
drwxr-xr-x 14 root root 4096 Mar 31 09:00 ..
drwxrwxr-x 3 www-data www-data 4096 Mar 31 10:15 site.ru
-rw-r--r-- 1 www-data www-data 1234 Mar 31 10:20 index.html
# Разбор: drwxrwxr-x
# d — тип (d=каталог, -=файл, l=ссылка)
# rwx — права владельца (read+write+execute)
# rwx — права группы
# r-x — права остальных (read+execute, без write)
# В числовом формате:
# rwx = 4+2+1 = 7
# r-x = 4+0+1 = 5
# rw- = 4+2+0 = 6
# r-- = 4+0+0 = 4
# drwxrwxr-x = 775
# -rw-r--r-- = 644
Массовое исправление прав с chmod
Мы написали скрипт для массового исправления прав на всех каталогах с документами:
# Числовой формат (наиболее распространён)
chmod 755 /var/www/site.ru # rwxr-xr-x
chmod 644 /var/www/site.ru/*.html # rw-r--r--
chmod 600 /root/.ssh/id_rsa # rw------- (только владелец)
chmod 700 /root/.ssh # rwx------ (только владелец)
# Символьный формат
chmod u+x script.sh # Добавить execute владельцу
chmod g+w /shared/docs # Добавить write группе
chmod o-rwx sensitive.conf # Убрать все права у others
chmod a+r readme.txt # Добавить read всем (all)
chmod u=rwx,g=rx,o= private/ # Установить точные права
# Рекурсивное применение
chmod -R 755 /var/www/site.ru/
# Разные права для файлов и каталогов
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;
# Специальные биты
chmod u+s /usr/bin/passwd # SUID — выполняется от имени владельца
chmod g+s /shared/project # SGID — новые файлы наследуют группу каталога
chmod +t /tmp # Sticky bit — удалять файлы может только владелец
Для каталогов с делами клиентов мы установили SGID — все новые файлы автоматически наследуют группу каталога, что упрощает совместную работу юристов.
Настройка chown и umask
Мы перенастроили владельцев и установили строгую маску создания файлов:
# Изменить владельца
chown www-data:www-data /var/www/site.ru
# Рекурсивно
chown -R www-data:www-data /var/www/site.ru/
# Только группу
chown :developers /shared/project
chgrp developers /shared/project # Эквивалент
# umask — маска прав для новых файлов
# Формула: права = базовые - umask
# Базовые: файлы 666, каталоги 777
$ umask
0022 # Файлы создаются с 644, каталоги с 755
# Установить более строгую маску
umask 0077 # Файлы 600, каталоги 700 (доступ только владельцу)
# Постоянная установка umask
echo "umask 0027" >> /etc/profile.d/umask.sh
# Результат: файлы 640, каталоги 750
# umask для конкретного пользователя
echo "umask 0077" >> /home/john/.bashrc
Для юристов мы установили umask 0027 — файлы, создаваемые юристом, доступны ему и его группе, но не другим отделам.
ACL: гибкие права для межотдельной работы
Стандартная модель ugo (user/group/others) не покрывала все потребности юридической компании. Например, нужно было дать доступ к делу конкретному юристу из другого отдела. Для этого мы внедрили ACL (Access Control Lists).
Настройка и использование ACL
Вот как мы настроили ACL на серверах клиента:
# Проверить, поддерживается ли ACL
$ mount | grep acl
/dev/sda1 on / type ext4 (rw,relatime) # ACL включен по умолчанию в ext4
# Если нет — включить в fstab:
# /dev/sda1 / ext4 defaults,acl 0 1
# Установить пакет
apt install acl -y
# Просмотр ACL
$ getfacl /shared/project/
# file: shared/project/
# owner: root
# group: developers
user::rwx
group::rwx
other::r-x
# Добавить права пользователю
setfacl -m u:john:rwx /shared/project/
setfacl -m u:alice:rx /shared/project/
# Добавить права группе
setfacl -m g:designers:rx /shared/project/
# Проверяем
$ getfacl /shared/project/
# file: shared/project/
# owner: root
# group: developers
user::rwx
user:john:rwx
user:alice:r-x
group::rwx
group:designers:r-x
mask::rwx
other::r-x
# Значок + в ls указывает на наличие ACL
$ ls -la /shared/
drwxrwxr-x+ 3 root developers 4096 Mar 31 10:00 project
Теперь партнёр может предоставить доступ к конкретному делу юристу из другого отдела, не меняя общую структуру групп.
Default ACL для автоматического наследования
Мы настроили Default ACL, чтобы новые файлы в каталогах дел автоматически получали правильные права:
# Установить default ACL (для новых объектов в каталоге)
setfacl -d -m u:john:rwx /shared/project/
setfacl -d -m g:developers:rwx /shared/project/
setfacl -d -m o::r-x /shared/project/
# Рекурсивное применение к существующим файлам
setfacl -R -m u:john:rwx /shared/project/
setfacl -R -m g:developers:rwx /shared/project/
# Удалить ACL для пользователя
setfacl -x u:alice /shared/project/
# Удалить все ACL
setfacl -b /shared/project/
# Копировать ACL с одного каталога на другой
getfacl /shared/project/ | setfacl --set-file=- /shared/project2/
# Backup и восстановление ACL
getfacl -R /shared/ > /backup/acl_backup.txt
setfacl --restore=/backup/acl_backup.txt
Sudo: принцип минимальных привилегий
12 пользователей с полным sudo — это были 12 потенциальных точек компрометации. Мы полностью перестроили файл /etc/sudoers, применив принцип минимальных привилегий.
Новая политика sudo
Мы использовали visudo для безопасного редактирования — он проверяет синтаксис перед сохранением:
# Открываем файл sudoers
visudo
# Формат: кто откуда = (от_чьего_имени) команды
# Полный доступ для группы sudo (по умолчанию)
%sudo ALL=(ALL:ALL) ALL
# Конкретные команды без пароля
john ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php*-fpm
# Группа разработчиков может деплоить
%developers ALL=(www-data) NOPASSWD: /usr/local/bin/deploy.sh
# DBA может управлять PostgreSQL
%dba ALL=(postgres) ALL
# Мониторинг без пароля (read-only команды)
%monitoring ALL=(ALL) NOPASSWD: /usr/bin/systemctl status *, /usr/bin/journalctl *, /usr/bin/df, /usr/bin/free
# Запретить su для безопасности
john ALL=(ALL) ALL, !/usr/bin/su, !/bin/su
# Логирование всех sudo-команд
Defaults log_output
Defaults logfile="/var/log/sudo.log"
Defaults timestamp_timeout=5 # Пароль действует 5 минут
Из 12 пользователей с полным sudo мы оставили полный доступ только двум IT-администраторам.
Отдельные файлы sudoers.d для каждого отдела
Для удобства управления мы создали отдельные файлы для каждого отдела:
# Создаём файл для разработчиков
visudo -f /etc/sudoers.d/developers
# Содержимое:
# Разработчики могут перезапускать сервисы и смотреть логи
%developers ALL=(ALL) NOPASSWD: \
/usr/bin/systemctl restart nginx, \
/usr/bin/systemctl restart php*-fpm, \
/usr/bin/systemctl restart gunicorn, \
/usr/bin/journalctl -u nginx*, \
/usr/bin/journalctl -u php*, \
/usr/bin/tail -f /var/log/nginx/*
# Проверяем синтаксис
visudo -c -f /etc/sudoers.d/developers
# Права на файл (обязательно 440)
chmod 440 /etc/sudoers.d/developers
Best practices sudo, которые мы внедрили:
- Никогда не давайте
ALL=(ALL) NOPASSWD: ALL обычным пользователям - Используйте группы вместо отдельных пользователей
- Ограничивайте список разрешённых команд
- Включайте логирование
- Запрещайте
su, bash, sh через sudo для ограниченных пользователей
PAM: политика паролей и двухфакторная аутентификация
PAM (Pluggable Authentication Modules) — фреймворк аутентификации в Linux. Мы использовали его для внедрения строгой политики паролей и 2FA.
Настройка PAM-модулей
Мы объяснили IT-специалисту клиента структуру PAM:
# Формат: тип контроль модуль [аргументы]
# Типы: auth, account, password, session
# Контроль: required, requisite, sufficient, optional
# Просмотр конфигурации SSH
$ cat /etc/pam.d/sshd
auth required pam_sepermit.so
auth substack password-auth
auth include postlogin
account required pam_nologin.so
account include password-auth
password include password-auth
session required pam_selinux.so close
session required pam_loginuid.so
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
Ключевые модули, которые мы настроили:
- pam_unix.so — стандартная аутентификация по /etc/shadow
- pam_faillock.so — блокировка после неудачных попыток
- pam_pwquality.so — проверка сложности пароля
- pam_limits.so — ограничение ресурсов
- pam_google_authenticator.so — двухфакторная аутентификация
Строгая политика паролей и блокировка брутфорса
Для юридической компании, работающей с персональными данными, мы настроили максимально строгую политику:
# Установка модуля проверки качества паролей
apt install libpam-pwquality -y
# Настройка /etc/security/pwquality.conf
cat > /etc/security/pwquality.conf << 'EOF'
# Минимальная длина пароля
minlen = 12
# Минимум классов символов (цифры, буквы, спецсимволы)
minclass = 3
# Максимум одинаковых символов подряд
maxrepeat = 3
# Запрет на использование имени пользователя
usercheck = 1
# Максимум символов из старого пароля
difok = 5
# Запрет словарных слов
dicpath = /usr/share/dict
EOF
# Блокировка после неудачных попыток входа
# /etc/pam.d/common-auth (Debian)
auth required pam_faillock.so preauth silent deny=5 unlock_time=900
auth required pam_unix.so
auth required pam_faillock.so authfail deny=5 unlock_time=900
# Просмотр заблокированных аккаунтов
faillock --user john
# Разблокировка
faillock --user john --reset
# Настройка срока действия паролей
# /etc/login.defs
PASS_MAX_DAYS 90
PASS_MIN_DAYS 1
PASS_WARN_AGE 14
# Для конкретного пользователя
chage -M 90 -m 1 -W 14 john
chage -l john # Проверить
Теперь пользователи обязаны менять пароль каждые 90 дней, а после 5 неудачных попыток входа аккаунт блокируется на 15 минут.
Двухфакторная аутентификация для партнёров
Для учётных записей партнёров (с доступом к самым конфиденциальным данным) мы настроили 2FA:
# Установка
apt install libpam-google-authenticator -y
# Настройка для пользователя (выполняется от имени пользователя)
su - john -c 'google-authenticator -t -d -f -r 3 -R 30 -w 3'
# Подключение PAM-модуля
# /etc/pam.d/sshd — добавляем строку:
auth required pam_google_authenticator.so
# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
systemctl restart sshd
Теперь для входа партнёра требуется SSH-ключ + одноразовый код из Google Authenticator.
Система аудита: отслеживаем каждое действие
Для юридической компании аудит действий — не просто рекомендация, а требование для расследования инцидентов и соответствия 152-ФЗ.
Настройка auditd
Мы развернули Linux Audit Framework и настроили правила для отслеживания критичных действий:
# Установка
apt install auditd audispd-plugins -y
systemctl enable --now auditd
# Добавляем правила аудита
# /etc/audit/rules.d/security.rules
# Отслеживать изменения учётных записей
-w /etc/passwd -p wa -k user_accounts
-w /etc/shadow -p wa -k user_accounts
-w /etc/group -p wa -k user_accounts
-w /etc/sudoers -p wa -k sudoers_changes
-w /etc/sudoers.d/ -p wa -k sudoers_changes
# Отслеживать команды sudo
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_commands
# Отслеживать SSH-ключи
-w /root/.ssh/ -p wa -k ssh_keys
-w /home/ -p wa -k home_changes
# Отслеживать изменения конфигурации сети
-w /etc/network/ -p wa -k network_config
-w /etc/hosts -p wa -k network_config
# Применяем правила
augenrules --load
# Поиск по логам
ausearch -k user_accounts -i
ausearch -k sudoers_changes --start today
# Отчёт по пользователю
aureport -au --start today # Отчёт по аутентификации
aureport -x --summary # Сводка по исполняемым файлам
Еженедельный скрипт аудита безопасности
Мы написали скрипт для регулярного аудита, который запускается по cron каждый понедельник:
#!/bin/bash
# /usr/local/bin/security-audit.sh
echo "=== Security Audit Report: $(date) ==="
echo -e "\n--- Users with UID 0 (root-level) ---"
awk -F: '$3 == 0 {print $1}' /etc/passwd
echo -e "\n--- Users with login shell ---"
grep -v '/nologin\|/false' /etc/passwd | awk -F: '{print $1, $7}'
echo -e "\n--- Users without password (!) ---"
awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow 2>/dev/null
echo -e "\n--- Files with SUID bit ---"
find / -perm -4000 -type f 2>/dev/null
echo -e "\n--- Files with SGID bit ---"
find / -perm -2000 -type f 2>/dev/null
echo -e "\n--- World-writable directories ---"
find / -type d -perm -o+w ! -path '/proc/*' ! -path '/sys/*' 2>/dev/null
echo -e "\n--- Failed SSH logins (last 24h) ---"
journalctl -u sshd --since '24 hours ago' | grep -c 'Failed password'
echo -e "\n--- Sudo usage (last 24h) ---"
journalctl --since '24 hours ago' | grep 'sudo:' | tail -20
echo -e "\n--- Open ports ---"
ss -tlnp
echo -e "\n=== Audit Complete ==="
Отчёт отправляется IT-директору и управляющему партнёру:
# Crontab
0 8 * * 1 /usr/local/bin/security-audit.sh | mail -s "Security Audit $(hostname)" admin@itfresh.ru
Результаты внедрения
Проект был реализован за 5 рабочих дней без простоя в работе юристов. Вот измеримые результаты:
- Заблокировано 13 учётных записей уволенных сотрудников — потенциальные точки несанкционированного доступа устранены
- Пользователей с полным sudo сократили с 12 до 2 — только IT-администраторы
- Каталоги с правами 777 — 0 (было 47 каталогов с конфиденциальными данными)
- Внедрена политика паролей — минимум 12 символов, 3 класса, ротация 90 дней
- 2FA для партнёров — защита от компрометации учётных записей руководства
- ACL на каталогах дел — гибкое управление доступом к конкретным делам
- Полный аудит действий — каждое изменение конфигурации, файлов и учётных записей логируется
- Еженедельный автоматический отчёт безопасности — IT-директор видит состояние системы
При повторном аудите через месяц все замечания были закрыты, и компания получила заключение о соответствии требованиям 152-ФЗ в части технической защиты. Если ваша компания работает с конфиденциальными данными и вам нужен аудит безопасности Linux-инфраструктуры — обратитесь в АйТи Фреш.