Неактивные учётные записи Linux: поиск и блокировка

Учётная запись, которую выдали под проект, давно закрытый, или сотруднику, сменившему роль, обычно никто не отзывает вручную — про неё просто забывают. Эта статья — про ежемесячную рабочую процедуру на серверах Linux без домена: выгрузить список, спросить владельца, заблокировать поимённо. Не гоняйте массовую блокировку без разбора: среди «тихих» окажутся сервисные учётки и системные записи с нетиповой оболочкой. Увольнение по-прежнему закрывайте в день события, не ждите отчёта о неактивности: чек-лист отзыва прав. Для доменных учётных записей — отдельная статья: неактивные учётные записи Active Directory.
Статья опирается на логику направления «Управление доступом» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Проверка скрипта выполнена в контейнере Debian 12, после неё всё удалено.
Что должно получиться
| Уровень | Что это значит на практике |
|---|---|
| 2. Гигиенический | Учётные записи без входа дольше установленного срока находятся автоматически, подтверждаются у владельца и блокируются поимённо, а не накапливаются молча |
Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.
Порог и исключения
Зафиксируйте порог в политике: 90 дней для обычных пользователей, 45 — для административных, одно число на компанию. Исключения до выгрузки: сервисные учётки с владельцем, учётные записи оборудования, задокументированный длительный отпуск. Без строки в исключениях «это сервис» не принимайте находку как повод для немедленной блокировки. Ведите исключения рядом с заявками на доступ: заявка на доступ.
Скрипт выгрузки
#!/usr/bin/env bash
# Поиск "забытых" учётных записей Linux: с правом входа, но без входа дольше заданного срока
# (или не входивших ни разу). Использует системную базу lastlog.
set -uo pipefail
DAYS="${1:-90}"
echo "--- учётные записи с правом входа без входа дольше ${DAYS} дней (включая ни разу не входившие)"
lastlog -b "$DAYS" | tail -n +2 | awk '{print $1}' | while read -r user; do
shell=$(getent passwd "$user" | cut -d: -f7)
case "$shell" in
*/nologin|*/false) continue ;; # технические учётные записи без входа пропускаем
"") continue ;; # нет такого пользователя в passwd (уже удалён)
esac
echo "$user ($shell)"
done
Запуск: ./stale-access.sh 90. Утилита lastlog -b N делает основную работу: показывает всех, кто не входил дольше N дней, включая тех, кто не входил вообще. Скрипт только читает, системные UID ниже 1000 и root в автоматическую блокировку всё равно не попадают — их исключают отдельно на следующем шаге, вручную.
Результат проверки
На тестовом сервере с четырьмя пользователями (один обычный с оболочкой, один технический с nologin, и ещё два без входа) скрипт с порогом 7 дней корректно показал все учётные записи с интерактивной оболочкой и пропустил техническую с nologin. Отдельно нашлась системная учётная запись sync с нестандартной оболочкой /bin/sync — она не входит в типовой список «нет входа» (nologin, false) и потому попала бы в список для разбора, хотя реально это не интерактивная учётная запись, а механизм (вход под ней вызывает синхронизацию диска и завершает сессию). Вывод: фильтр по имени оболочки неполон, и список кандидатов нужно просматривать глазами, а не блокировать автоматически по совпадению регулярного выражения.
Блокировка поимённо
Для кандидата после подтверждения владельца (или истечения срока ответа) проверьте текущее состояние и заблокируйте:
sudo passwd -S ИМЯ
sudo chage -l ИМЯ
В выводе passwd -S буква L значит, что пароль уже заблокирован. Если владельца нет и это не сервис:
sudo usermod --lock ИМЯ
sudo chage -E 0 ИМЯ
По документации usermod ключ --lock ставит ! перед хэшем пароля и сам по себе не закрывает вход по ключу SSH: ключи из ~/.ssh/authorized_keys уберите в архив отдельно, как при увольнении. Проверка: снова passwd -S (статус с L) и попытка входа этой учётной записью паролем на тестовой машине не должна проходить.
Подтверждение и журнал
- Раз в месяц отправьте список владельцам систем: «подтвердите, что человеку доступ ещё нужен» — срок ответа три рабочих дня.
- Молчание по обычной учётной записи — блокировка; молчание по привилегированной — блокировка в тот же день после напоминания.
- Запишите в журнал: дата выгрузки, сколько записей, сколько подтверждено, сколько заблокировано, какие исключения.
- Через 30 дней заблокированную личную учётную запись удаляйте по политике хранения; сервисную не трогайте без владельца системы.
Диагностика
| Симптом | Причина и что делать |
|---|---|
| В списке технические и служебные учётные записи | Оболочка нестандартна и не похожа на nologin/false (как sync, halt в некоторых дистрибутивах). Ведите явный список исключений для вашей системы |
lastlog у всех показывает «Never logged in» |
База lastlog пуста (свежий сервер) или входы идут через механизм, не пишущий в неё. Проверьте, не очищался ли /var/log/lastlog, и какие способы входа реально используются |
| После блокировки пароля сотрудник всё равно вошёл | Вход был по ключу SSH, а usermod --lock его не закрывает. Удалите ключ из authorized_keys отдельно |
| Список каждый раз одинаковый, решения не фиксируются | Находки обнаруживаются, но не разбираются. Назначьте срок принятия решения по каждой находке, а не только её обнаружение |
Ограничения
Скрипт видит только локальные учётные записи конкретного сервера и только вход через механизмы, которые пишут в lastlog (обычно стандартный вход по SSH и консоли). Для централизованного каталога и облачных сервисов нужен отдельный механизм на стороне каталога: идея та же — дата последнего использования и порог для разбора, но источник данных другой.
Где это в модели зрелости
Материал относится к направлению «Управление доступом» (материалы направления, карта зрелости). Уровень 2 требует периодического пересмотра выданного доступа, а не только отзыва при увольнении: автоматический поиск неиспользуемых учётных записей на серверах Linux закрывает эту задачу там, где нет центрального каталога.
Как проверить
- Скрипт запускается по расписанию с порогом, согласованным для компании.
- Результат доходит до ответственного за доступ, а не только сохраняется в файл.
- Каждая находка получает явное решение (блокировка, обоснованное сохранение, исключение из списка) с фиксацией.
- Список технических исключений (нестандартные системные оболочки) поддерживается в актуальном состоянии для вашей системы.
- Блокировка пароля сопровождается удалением ключей SSH там, где они были выданы.
Источники
- Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
- Debian,
lastlog(8): manpages.debian.org;usermod(8): manpages.debian.org. - CIS Controls v8.1, контроль 5 (дремлющие учётные записи). Это не закон РФ: cisecurity.org.


















