Короткий ответ
Аудит пользователей — таблица: имя, UID, shell, lock (passwd -S), lastlog, группы (sudo,docker), sudo -l, ключи SSH, crontab. Сверьтесь с HR и с system users. Действия по находкам — отдельные: мёртвые учётки, sudo ALL, ключи. Не удаляйте UID<1000. Хост host.example (10.0.20.10), живой вход admin.
Симптомы и как отличить
Нет процедуры, если «кто-то в sudo» неизвестно. Это не расследование конкретного взлома (там ещё auditd/journal). Для следов изменений: auditd.
Возможные причины мусора
- Cloud-init users.
- Уволенные.
- Тестовые adduser.
- Пакеты с system user ≥1000.
- Дубль локальный+домен.
Диагностика (чеклист съёмки)
Сохраняйте файлы.
1. Учётки
mkdir -p /home/admin/user-audit
getent passwd > /home/admin/user-audit/passwd.txt
getent passwd | awk -F: '{printf "%s uid=%s gid=%s shell=%s home=%s\n",$1,$3,$4,$7,$6}'Интерактивные кандидаты: UID≥1000 и shell не nologin/false.
getent passwd | awk -F: '$3>=1000 && $7 !~ /nologin|false/ {print}'Второй uid 0:
getent passwd | awk -F: '$3==0 {print}'Только root.
2. Lock и пароль
sudo passwd -S -a > /home/admin/user-audit/passwd-S.txtИнтерпретация: L locked, P usable password, NP empty. NP у интерактива + SSH ключ — зафиксируйте.
3. lastlog / last
lastlog > /home/admin/user-audit/lastlog.txt
last -a | head -n 40Never у человека из HR = кандидат на lock. Never у myservice = норма.
4. sudo
sudo visudo -c
sudo grep -REn '^[^#]' /etc/sudoers /etc/sudoers.d/ > /home/admin/user-audit/sudoers.txt
for u in admin deploy ivan; do echo "== $u"; sudo -l -U "$u"; doneПодставьте свои имена из шага 1.
5. Группы высокого риска
getent group sudo docker lxd adm systemd-journal
id admin6. Ключи и cron
sudo find /home -name authorized_keys -ls
sudo ls /var/spool/cron/crontabsFingerprint: ssh-keygen -lf.
7. Процессы «лишних»
ps -eo user,pid,cmd | awk 'NR==1 || $1=="ivan"'Решение (как оформить результат)
Таблица:
| User | UID | Shell | S | lastlog | sudo | docker | keys | Решение |
|---|---|---|---|---|---|---|---|---|
| admin | 1000 | bash | P | today | %sudo | нет | 1 | оставить |
| ivan | 1001 | bash | P | 400d | NOPASSWD ALL | да | 2 | lock+отзыв |
| myservice | 115 | nologin | L | never | нет | нет | нет | оставить |
Каждая строка «lock/отзыв» — тикет, не сюрприз ночью. Baseline хоста: hardening.
LDAP: повторите для доменных sudoers (sss). Локальный lock не снимает доменную учётку.
Скрипт съёмки, чтобы не забывать поля. Достаточно shell от admin:
{
echo '=== passwd uid>=1000 ==='
getent passwd | awk -F: '$3>=1000 {print}'
echo '=== passwd uid 0 ==='
getent passwd | awk -F: '$3==0 {print}'
echo '=== groups sudo docker ==='
getent group sudo docker
} | sudo tee /home/admin/user-audit/summary.txtНе парсите /etc/shadow в wiki. passwd -S достаточно.
Сверка с HR: таблица сотрудников vs интерактивные shells. Лишние в Linux — lock. Лишние в HR без учётки — не ваша дыра, но ключ мог жить под admin. Сверяйте fingerprint ключей с инвентарём ноутбуков.
nologin пользователи с tty в last: кто-то сменил shell обратно. Смотрите usermod -s.
Пакет accountsservice и GUI на сервере обычно не нужны; если есть gdm users — зачем графическая сессия на host.example.
w/who в момент аудита: живые сессии уволенных — terminate, затем lock.
Экспорт в тикет без секретов: не кладите содержимое authorized_keys целиком в публичный канал, только comment+fingerprint.
Повторный аудит после любого offboarding через 7 дней: ключ могли вернуть из cloud-init metadata. Сравните diff user-audit/ каталогов.
Группа adm на Ubuntu читает /var/log/syslog если rsyslog ещё кладёт файлы 640 adm. Это не sudo, но лишний доступ к auth.log. Инвентаризируйте getent group adm. Для journal используйте systemd-journal, не раздувайте adm.
root без пароля (NP) на cloud-образе: консоль гипервизора может пускать по ключу провайдера. Смените пароль root в сейф или заблокируйте пароль, оставьте только консольный ключ провайдера по политике. Не оставляйте пустой пароль root.
Повторяемость: тот же чеклист в ansible community.general.users факты + assert. Разовый audit через полгода тухнет.
Не забудьте технические учётки CI (gitlab-runner, jenkins). Их ключ в authorized_keys deploy — часть аудита. Срок жизни ключа и CIDR источника — в той же таблице, что люди. Иначе «пользователей почистили», runner с ключом 2019 жив.
getent shadow не для отчёта. Только passwd -S.
Сверьте /etc/adduser.conf DIR_MODE: новые home не должны рождаться как 777. На Ubuntu обычно 0750 или 0755 — зафиксируйте в эталоне, иначе каждый adduser плодит лишний other+rx на home с ключами.
Как проверить, что проблема устранена
Аудит выполнен, если в заявке лежат passwd.txt, passwd-S.txt, lastlog.txt, sudoers.txt и таблица с решениями. Повтор через квартал. Для уже применённых lock — проверки из статьи про неиспользуемые учётки. admin SSH жив.
Если не помогло
- getent медленный: sssd, не «passwd сломан».
- lastlog пустой на 24.04: пакет
lastlogvslastlog2— смотритеlast/loginctl. - sudo -l пустой при членстве sudo:
sudoersHost_Alias. - Ключи в AuthorizedKeysCommand — каталог, не файл home.
Профилактика
- Квартальный прогон чеклиста.
- Offboarding = обязательные поля таблицы.
- Запрет группы docker на проде.
- auditd watches на passwd/sudoers.
FAQ
UID_MIN
Смотрите /etc/login.defs UID_MIN (обычно 1000). Не гадайте.
root в lastlog
Консольные входы. SSH root должен быть запрещён.
NP и ключи
Пароль UNIX для sudo всё равно желателен. NP+NOPASSWD+ключ = один украденный файл = root.
Как учесть сервисных с UID 1001
Столбец «владелец unit». Не lastlog.
Windows-админ спрашивает «аналог AD users»
Это и есть. Нет GUI — таблица из getent.