Большинство взломов и аварий на серверах начинается не с хитрых уязвимостей, а с банальной небрежности в правах: общий пароль root на всех, учётная запись уволенного сотрудника, которая жива уже два года, файлы с правами 777 «чтобы заработало». Правильная модель доступа не требует дорогих продуктов, она строится из базовых средств Linux: пользователей, групп, прав на файлы и sudo. В этой статье мы выстроим такую модель на примере хостов srv-linux01, srv-web01 и srv-db01 из домена itpages.lab.local и сети 192.168.10.0/24: заведём людей и сервисные учётки, разложим их по группам, настроим sudo с принципом минимальных привилегий и подружим всё с SSH-ключами.

Принципы, на которых всё держится, просты. Первое: у каждого человека своя личная учётная запись, общих логинов нет, потому что иначе в журнале не видно, кто что сделал. Второе: права выдаются группам, а не людям, чтобы при приходе и уходе сотрудника менялось членство в группе, а не десятки настроек. Третье: никто не работает под root, а повышает привилегии точечно через sudo, и каждое такое действие остаётся в журнале. Четвёртое: сервисы запускаются от отдельных непривилегированных пользователей без интерактивного входа.

Шаг 1. Анатомия учётных записей

Всё хранится в простых файлах. Посмотри на них, чтобы понимать, что делают утилиты:

getent passwd anna
anna:x:1001:1001:Anna Petrova:/home/anna:/bin/bash

id anna
uid=1001(anna) gid=1001(anna) groups=1001(anna),27(sudo)

sudo grep anna /etc/shadow | cut -d: -f1-3
anna:$y$j9T$...:20374

В /etc/passwd лежат имя, идентификатор, домашний каталог и оболочка. Хэши паролей находятся в /etc/shadow, который читает только root. Идентификаторы до 999 (в некоторых дистрибутивах до 499) зарезервированы под системные учётки, обычные пользователи начинаются с 1000. Команда getent полезна тем, что покажет и локальных, и доменных пользователей, если сервер подключён к каталогу вроде FreeIPA или Active Directory (через sssd).

Шаг 2. Создаём группы и пользователей

Определим роли заранее. Команда эксплуатации (ops) администрирует всё, веб-разработчики (webdev) работают на srv-web01, администраторы баз (dbadmin) на srv-db01. Группы создаём заранее:

sudo groupadd ops
sudo groupadd webdev
sudo groupadd dbadmin

sudo useradd -m -s /bin/bash -c 'Anna Petrova' -G ops anna
sudo useradd -m -s /bin/bash -c 'Igor Smirnov' -G webdev igor
sudo passwd -l anna     # блокируем пароль: будем входить только по ключу
sudo passwd -l igor

Ключ -m создаёт домашний каталог, -s задаёт оболочку, -G добавляет во вторичные группы. Пользователя в группу позже добавляют командой usermod с обязательным ключом -a. Вот классическая ловушка: без -a команда usermod -G заменит все вторичные группы на указанную, и человек внезапно потеряет доступ ко всему остальному.

sudo usermod -aG dbadmin anna
id anna
uid=1001(anna) gid=1001(anna) groups=1001(anna),1003(ops),1005(dbadmin)

sudo gpasswd -d anna dbadmin     # убрать из группы

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

Шаг 3. Права на файлы: группа вместо 777

Теперь вместо «открыть всем» используем группы. Допустим, каталог /srv/www на srv-web01 должен быть доступен на запись разработчикам и на чтение веб-серверу:

sudo chown -R root:webdev /srv/www
sudo chmod -R 2775 /srv/www
ls -ld /srv/www
drwxrwsr-x 4 root webdev 4096 Oct 13 10:30 /srv/www

Цифра 2 в начале включает бит setgid на каталоге: все новые файлы внутри наследуют группу webdev, а не основную группу того, кто их создал. Без этого разработчики постоянно создавали бы файлы, недоступные коллегам. Для тонкой настройки, когда одной группы мало, используй ACL:

sudo setfacl -m g:ops:rx /srv/www
sudo setfacl -d -m g:ops:rx /srv/www     # по умолчанию для новых файлов
getfacl /srv/www
# file: srv/www
# owner: root
# group: webdev
user::rwx
group::rwx
group:ops:r-x
mask::rwx
other::r-x

Плюс в конце вывода ls -l (например, drwxrwsr-x+) подскажет, что на объекте есть ACL. Не злоупотребляй ими: чем больше исключений, тем труднее понять, кто имеет доступ, и тем сложнее проводить аудит.

Шаг 4. Настраиваем sudo правильно

Sudo позволяет выдать конкретные права без передачи пароля root. Главное правило: редактируй конфигурацию только через visudo, потому что он проверяет синтаксис перед сохранением, а ошибка в sudoers может лишить тебя административного доступа целиком. Не правь /etc/sudoers напрямую, а складывай настройки в отдельные файлы каталога /etc/sudoers.d/:

sudo visudo -f /etc/sudoers.d/10-ops

# члены группы ops могут всё, но с паролем
%ops ALL=(ALL:ALL) ALL

sudo visudo -f /etc/sudoers.d/20-webdev

# разработчики управляют только веб-сервисом на srv-web01
Cmnd_Alias WEBCTL = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx
%webdev srv-web01=(root) WEBCTL

Во втором файле права ограничены именно тремя командами и именно одним хостом. Это принцип минимальных привилегий в действии: разработчик может перезапустить nginx, но не может прочитать /etc/shadow. Одна оговорка: не разрешай через sudo команды, из которых легко выйти в оболочку (редакторы vim, less, некоторые варианты find), иначе ограничение превращается в формальность. Проверить, что именно доступно пользователю, можно так:

sudo -l -U igor
User igor may run the following commands on srv-web01:
    (root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx,
        /usr/bin/systemctl status nginx

Для беспарольного sudo (NOPASSWD) применяй осторожно: оно оправдано для автоматизации и сервисных учёток под жёстко ограниченными командами, но не для живых людей. Журнал действий sudo пишется в /var/log/auth.log на Debian и в /var/log/secure на RHEL, и его легко разбирать:

sudo grep sudo /var/log/auth.log | tail -3
Oct 13 10:41:07 srv-web01 sudo: igor : TTY=pts/0 ; PWD=/home/igor ; USER=root ; COMMAND=/usr/bin/systemctl restart nginx

Шаг 5. SSH-ключи и запрет парольного входа

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

# на рабочей станции пользователя
ssh-keygen -t ed25519 -C 'anna@itpages.lab.local'
ssh-copy-id anna@srv-linux01.itpages.lab.local

# на сервере проверяем права
ls -ld ~anna/.ssh ~anna/.ssh/authorized_keys
drwx------ 2 anna anna 4096 Oct 13 10:50 /home/anna/.ssh
-rw------- 1 anna anna  101 Oct 13 10:50 /home/anna/.ssh/authorized_keys

Права 700 на каталог и 600 на файл обязательны: при более открытых правах sshd молча откажется использовать ключ. Затем усиливаем настройки службы в отдельном файле, чтобы не трогать основной:

sudo tee /etc/ssh/sshd_config.d/50-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
AllowGroups ops webdev dbadmin
MaxAuthTries 3
EOF
sudo sshd -t && sudo systemctl reload sshd

Перед перезагрузкой конфигурации обязательно держи открытой вторую сессию: если ошибёшься, у тебя останется путь назад. Директива AllowGroups пускает на сервер только членов перечисленных групп, и это быстрый способ ограничить круг людей на каждом хосте: на srv-db01 можно оставить только ops и dbadmin.

Шаг 6. Сервисные учётки и жизненный цикл

Для приложений создавай системных пользователей без входа и без домашней папки:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc
getent passwd appsvc
appsvc:x:998:998::/home/appsvc:/usr/sbin/nologin

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

sudo usermod -L -e 1 igor                 # блокировка и истёкший срок
sudo find / -xdev -user igor 2>/dev/null | head
sudo crontab -l -u igor
sudo userdel -r igor                      # когда всё передано

Раз в квартал делай ревизию: список пользователей с оболочкой, членство в привилегированных группах и последние входы.

getent passwd | awk -F: '$7 !~ /nologin|false/ {print $1, $3}'
getent group sudo ops
lastlog -b 90 | head

Команда lastlog -b 90 покажет учётки, под которыми не входили больше трёх месяцев, это первые кандидаты на блокировку.

Шаг 7. Парольная политика, блокировки и аудит

Даже если основной вход идёт по ключам, пароли всё равно остаются: для sudo, для консоли, для сервисных случаев. Поэтому задай разумные правила их жизни. Срок действия и предупреждения настраиваются утилитой chage:

sudo chage -l anna
Last password change                : Oct 13, 2026
Password expires                    : Jan 11, 2027
Minimum number of days between password change : 1
Maximum number of days between password change : 90
Number of days of warning before password expires : 7

sudo chage -M 90 -m 1 -W 7 anna

Сложность пароля контролирует модуль pam_pwquality, настройки которого лежат в /etc/security/pwquality.conf: минимальная длина, обязательные классы символов, запрет словарных слов. Для защиты от перебора пригодится pam_faillock, который временно блокирует учётку после нескольких неудачных входов; разблокировка выполняется командой faillock —user anna —reset. Не делай политику абсурдно жёсткой: слишком частая смена и непосильные требования приводят к тому, что люди клеят пароли на мониторы.

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

sudo tee /etc/audit/rules.d/identity.rules <<'EOF'
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
EOF
sudo augenrules --load
sudo ausearch -k sudoers -i | tail -5

Ключ -k даёт событиям метку, по которой потом удобно искать. Эти журналы имеет смысл отправлять на центральный сервер, потому что злоумышленник с правами root способен подчистить локальные записи. Для небольшой сети 192.168.10.0/24 хватит rsyslog с пересылкой на srv-linux01, как на общий сборщик журналов.

И последнее: учётные записи root и аварийные доступы. Пароль root пусть будет длинным, уникальным и записанным в менеджер паролей; вход под ним на консоли используй только в аварийных ситуациях. Проверяй, нет ли пользователей с нулевым идентификатором, кроме root (awk -F: ‘$3==0’ /etc/passwd), и пользователей с пустым паролем (sudo awk -F: ‘$2==»»‘ /etc/shadow). Такие простые проверки, запущенные по расписанию, находят ошибки раньше, чем их найдёт кто-то посторонний.

Частые ошибки и как их избежать

  • Общие учётные записи и пароль root на всех. Журнал не отвечает на вопрос «кто это сделал». Заведи личные учётки, запрети вход root по SSH (PermitRootLogin no), а для админов используй sudo и ключи.
  • Править sudoers в обход visudo. Одна опечатка, и sudo перестаёт работать у всех. Используй visudo -f для файлов в /etc/sudoers.d/, проверяй командой visudo -c, а на время работ держи открытую root-сессию.
  • Забывать ключ -a в usermod -G. Без него вторичные группы пользователя заменяются, и он внезапно теряет доступ. Всегда пиши usermod -aG и проверяй результат командой id.

Что дальше

Администрирование Linux — это набор связанных навыков, вот соседние темы серии: