На сервере живёт пользователь, которого никто не создавал: разбор
Вы разбираете сервер — свой старый, доставшийся от подрядчика или просто давно не открывавшийся — и в списке пользователей натыкаетесь на имя, которое не может вспомнить никто из команды. Первая реакция — тревога: это взлом? Вторая, более трезвая, — не спешить с выводами, потому что половина таких находок оказывается забытым сервисным аккаунтом от давно установленного пакета. Разница между «ничего страшного» и «нас взломали три месяца назад» решается не интуицией, а конкретной последовательностью проверок. Разберём её по шагам.
Содержание
Первое действие: зафиксировать, не трогать
Пока вы не понимаете природу находки, любое резкое движение работает против вас. userdel удаляет домашний каталог и вместе с ним — улики: что там лежало, когда создавалось, чем пользовались. Блокировка входа тоже подождёт минуту: сначала соберите то, что может исчезнуть само — например, активную сессию, если она есть прямо сейчас.
Начните с копии, прежде чем что-либо менять:
mkdir -p /root/investigation
cp /etc/passwd /etc/shadow /etc/group /root/investigation/
getent passwd имя_пользователя >> /root/investigation/finding.txt
id имя_пользователя >> /root/investigation/finding.txt
Если у аккаунта есть домашний каталог — заархивируйте его целиком, не заходя внутрь и не запуская в нём ничего:
tar czf /root/investigation/home-snapshot.tar.gz -C /home имя_пользователя 2>/dev/null
Это не значит «ничего не делайте вообще» — если сервер продовый и находка выглядит подозрительно с первого взгляда (UID 0 у не-root, shell вместо nologin у якобы системной учётки), логичный компромисс — заблокировать вход, но оставить всё остальное как есть:
usermod -L имя_пользователя
usermod -s /usr/sbin/nologin имя_пользователя
Дальше разбирайтесь по пунктам ниже, уже не рискуя, что находка тем временем зайдёт по SSH и подчистит следы.
Что говорит сама запись в /etc/passwd
Формат строки: имя:x:UID:GID:комментарий:домашний_каталог:shell. Прежде чем идти дальше, вытащите из неё всё, что можно.
UID и его диапазон. Системные учётки (созданные пакетами при установке — www-data, postgres, redis, _apt) обычно занимают низкие UID, обычно до 999 или 1000 — точную границу смотрите в /etc/login.defs по параметрам UID_MIN/SYS_UID_MAX, она отличается между дистрибутивами. Пользовательские аккаунты, заведённые вручную, — выше этой границы. Несовпадение диапазона и назначения — первый маркер: системный на вид UID с обычным пользовательским номером, или наоборот.
Shell. У чисто сервисных аккаунтов, которым не нужен интерактивный вход, в норме стоит /usr/sbin/nologin или /bin/false. Если у учётки с «служебным» именем стоит /bin/bash или /bin/sh — кто-то либо сознательно сделал её интерактивной для конкретной задачи (и это должно быть задокументировано), либо это не тот сервисный аккаунт, за который она себя выдаёт.
Домашний каталог. /home/имя — нормально для пользовательской учётки. /var/tmp, /dev/shm, /opt/.что-то-скрытое вместо ожидаемого пути — сильный повод присмотреться внимательнее: легитимные пакеты так не делают.
Комментарий (поле GECOS). Часто пустое даже у легитимных сервисных аккаунтов, так что само по себе ни о чём не говорит — но если оно есть и явно шаблонное или бессмысленное, добавьте это в список наблюдений.
Дальше — проверка происхождения. Если учётку создал пакет, это должно быть видно в логе установки:
# Debian/Ubuntu
grep имя_пользователя /var/log/dpkg.log* 2>/dev/null
# RHEL/AlmaLinux/CentOS
grep имя_пользователя /var/log/yum.log* /var/log/dnf.log* 2>/dev/null
Если совпадений нет — учётку никакой пакет не заводил, и она либо создана вручную человеком (тогда должна быть причина, которую кто-то помнит), либо появилась в обход штатных механизмов управления пакетами, что для легитимной установки нехарактерно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверИстория входов: last, lastb, lastlog
Это раздел, который чаще всего пропускают, хотя именно он отвечает на самый практичный вопрос: пользовались ли этой учёткой вообще, и если да — когда и откуда.
lastlog показывает время последнего входа по каждому пользователю системы, включая тех, кто не заходил ни разу:
lastlog | grep имя_пользователя
Строка Never logged in для «служебного» аккаунта, у которого при этом есть рабочий shell и, как выяснится дальше, ключ в authorized_keys, — сама по себе странность: зачем тогда вообще давать ему возможность интерактивного входа.
last читает бинарный журнал /var/log/wtmp и показывает историю успешных входов и выходов с указанием источника:
last имя_пользователя
Обратите внимание не только на факт входа, но и на IP или хост, откуда заходили — знакомый ли это адрес (ваш офис, известный VPN, CI-раннер) или что-то незнакомое, особенно из другой страны или диапазона хостинг-провайдера, никак не связанного с вашей инфраструктурой.
Не забудьте и про неудачные попытки — они читаются из /var/log/btmp:
lastb имя_пользователя 2>/dev/null
Серия неудачных попыток входа под этим именем незадолго до первой удачной — характерный след подбора пароля до того, как он подошёл (или до того, как для учётки добавили ключ).
Если сервер работает не первый месяц, а wtmp уже перезаписан ротацией — расширьте поиск по архивным журналам:
last -f /var/log/wtmp.1 имя_пользователя 2>/dev/null
zgrep имя_пользователя /var/log/auth.log*.gz 2>/dev/null # Debian/Ubuntu
zgrep имя_пользователя /var/log/secure*.gz 2>/dev/null # RHEL-based
В auth.log/secure дополнительно ищите сам момент создания учётки — команда useradd или adduser обычно пишет туда строку с указанием, кто и когда это сделал (если, конечно, лог не подчищен, что тоже само по себе диагностический признак):
grep -E "useradd|new user|adduser" /var/log/auth.log* 2>/dev/null
Развёрнутый разбор всех источников истории входов, включая то, как отличать ложные тревоги от реальных, — в статье «Кто заходил на сервер, пока вас не было: разбор истории входов».
Права, группы и crontab: что аккаунт может и что делает
Даже безобидный на вид пользователь опасен, если у него есть повышенные права или что-то тихо выполняется от его имени по расписанию.
Проверьте группы:
groups имя_пользователя
id имя_пользователя
Членство в sudo, wheel или docker — это фактически root, вне зависимости от того, насколько скромно выглядит сама учётка (доступ в группу docker даёт возможность смонтировать корень хостовой файловой системы через контейнер). Проверьте и явные записи в судоерсах — членства в группе может не быть, а персональное правило есть:
grep -R "имя_пользователя" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
Дальше — crontab именно этого пользователя, отдельно от системного /etc/crontab и /etc/cron.d/:
crontab -u имя_пользователя -l
ls -la /var/spool/cron/crontabs/ 2>/dev/null # Debian/Ubuntu
ls -la /var/spool/cron/ 2>/dev/null # RHEL-based
Если crontab пуст, это не значит «ничего не запланировано» — проверьте ещё systemd-таймеры и юниты, ссылающиеся на этого пользователя:
systemctl list-timers --all
grep -rl "User=имя_пользователя" /etc/systemd/system/ 2>/dev/null
Найденная строка вида периодического исходящего соединения на нестандартный порт — классический признак закладки. Если хотите системно пройтись по всему расписанию сервера, а не только по одному пользователю, — отдельная методология в статье «Чужие cron-задачи: расписание, которое никто не помнит».
Заодно посмотрите, что ещё принадлежит этому пользователю в файловой системе — иногда там обнаруживаются скрипты, бинарники или конфиги, не имеющие отношения ни к одному известному сервису:
find / -user имя_пользователя 2>/dev/null | grep -v "^/proc"
authorized_keys и SSH-ключи: как заходит
Даже если пароль учётки заблокирован (! или * в /etc/shadow), вход всё равно возможен через SSH-ключ — блокировка пароля его не отключает.
find / -name authorized_keys -exec ls -la {} \; 2>/dev/null
cat /home/имя_пользователя/.ssh/authorized_keys 2>/dev/null
Обязательно проверьте не только домашний каталог самой находки, но и authorized_keys у root и у остальных пользователей — если аккаунт скомпрометирован, велика вероятность, что атакующий на всякий случай прописал ключ ещё в одном-двух местах, чтобы не зависеть от одной точки входа. Отдельный, довольно частый сценарий закрепления — чужой ключ, дописанный в authorized_keys легитимного пользователя без создания новой учётки вообще; если параллельно с находкой видите незнакомую строку в чужом файле ключей, это тот же самый инцидент, просто с другой стороны.
Обратите внимание на комментарий в конце строки ключа (после самого base64-блока) — часто там user@host, откуда ключ сгенерирован, и это может подсказать происхождение: если это что-то похожее на root@ip-адрес-в-другой-стране — вывод почти очевиден, если deploy@ci-runner-компании — вероятно, легитимно, но стоит уточнить у команды.
Легитимный сервис или взлом: как решить и что делать дальше
К этому моменту у вас на руках достаточно фактов, чтобы принять решение, а не гадать. Сведите находки в таблицу — она почти всегда однозначно указывает в одну из двух сторон.
| Признак | Похоже на легитимный сервис | Похоже на компрометацию |
|---|---|---|
| Происхождение | Есть запись в логе установки пакета (dpkg/rpm) | Ни один пакет её не заводил, никто из команды не признаётся |
| UID / диапазон | Соответствует системному диапазону из /etc/login.defs | Диапазон не соответствует назначению учётки |
| Shell | /usr/sbin/nologin или /bin/false при отсутствии интерактивных задач | /bin/bash у якобы служебного аккаунта без объяснимой причины |
| Домашний каталог | /home/имя или профильный путь пакета | /var/tmp, /dev/shm, скрытые каталоги |
История входов (last, lastlog) | Входы с известных, ожидаемых адресов или вообще отсутствуют при nologin-shell | Входы с незнакомых IP, особенно вскоре после серии неудачных попыток |
| Группы и sudo | Минимально необходимые для задачи | sudo/wheel/docker без документированной причины |
| Crontab / таймеры | Понятная, воспроизводимая задача (бэкап, отчёт) | Исходящие соединения на нестандартные порты, обфусцированные команды |
| authorized_keys | Ключ с понятным комментарием, известный источник | Чужой или анонимный ключ, дублирование в других учётках |
Если большинство признаков — в правом столбце, дальше действуете как при подтверждённом инциденте, но здесь важен порядок, а не скорость:
- Изоляция. Отрежьте сервер от внешнего трафика фаерволом, не выключая машину — вы потеряете улики из оперативной памяти и активных сетевых соединений, если выключите её физически.
- Смена паролей и ключей. Считайте скомпрометированным всё, к чему сервер имел доступ: базы данных, внешние API, панели управления, а также ключи, которыми сам сервер подключался к другим машинам — бэкапам, мониторингу, CI/CD.
- Аудит остальной системы. Одна найденная учётка редко бывает единственной точкой закрепления — проверьте другие подозрительные crontab, изменённые systemd-юниты, правки в
/etc/rc.local, свежие бинарники в нетипичных местах. - Восстановление из проверенного состояния. Если сомнений в целостности системы больше одного пункта — надёжнее поднять окружение заново из чистого образа, чем вычищать находки построчно, надеясь ничего не пропустить.
Полный порядок действий при подтверждённом взломе, со всеми командами по изоляции и восстановлению, — в статье «Взломали сервер: пошаговый план». А чтобы такая находка не повторялась незамеченной месяцами, стоит поставить регулярный контроль изменений в /etc/passwd и /etc/shadow — конкретная настройка и типичные ошибки разобраны в статье «Свежая учётка в /etc/passwd: как заметить и что делать дальше».
Если же по итогам таблицы картина указывает на легитимный сервисный аккаунт — не спешите закрывать вопрос молча. Задокументируйте, для чего он нужен, кто отвечает, и приведите его в порядок: замените shell на nologin, если интерактивный вход ему не нужен, урежьте лишние группы, если он состоит в sudo без явной причины. Забытый, но легитимный аккаунт с избыточными правами — это не взлом сегодня, но готовая цель для него завтра.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Сколько времени в среднем занимает такой разбор?
От получаса, если находка объясняется первой же проверкой (есть в логе установки пакета, nologin, входов не было), до нескольких часов, если признаки смешанные и нужно поднимать архивные логи и проверять другие учётки на этом же сервере.
Учётка заблокирована, но подозрение осталось — можно просто перестраховаться и снести сервер?
Это разумный вариант, если сомнения серьёзные, а простой пересборки дешевле, чем расследование. Но сначала снимите копии /etc/passwd, /etc/shadow, домашнего каталога и релевантных логов на другую машину — иначе вы не узнаете, что именно произошло, и не сможете исключить повторение того же вектора на новом сервере.
UID 0 у второго пользователя — это всегда взлом?
Практически всегда. Легитимных причин заводить второй аккаунт с правами root под другим именем крайне мало, и почти любая из них была бы задокументирована и известна команде.
А если это старый сервисный аккаунт от давно удалённого софта — можно просто удалить и забыть?
Да, но только после того, как вы прошли по чек-листу выше и убедились, что признаков компрометации нет. Удаляйте после фиксации состояния, а не вместо неё — если ошиблись в оценке, у вас должна остаться возможность вернуться к фактам.
Нужно ли сообщать о находке провайдеру сервера?
Если есть подтверждённые признаки взлома и тем более следы использования сервера для атак на других (спам, сканирование, майнинг) — да, это снижает риск блокировки аккаунта по чужим жалобам и иногда провайдер может помочь с логами на своей стороне.
Есть ли способ проверять это автоматически, а не руками при каждом подозрении?
Да — ежедневный снапшот /etc/passwd с диффом от предыдущего дня или auditd с правилом на запись в passwd/shadow/sudoers ловят новую учётку сразу, а не спустя месяцы. Настройка обоих вариантов — в статье про свежую учётку в /etc/passwd, на которую есть ссылка в разделе выше.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →