MAATRIX / Блог / Аудит доступов на унаследованном сервере: кто ещё может сюда зайти

Аудит доступов на унаследованном сервере: кто ещё может сюда зайти

MAATRIX

Сервер достался вам не с чистого листа: прежний администратор ушёл, подрядчик закрыл проект, компанию купили вместе с инфраструктурой. У вас есть root — но нет представления, сколько ещё людей и систем технически могут сюда зайти прямо сейчас. Не «кто должен иметь доступ по вашим правилам» — таких правил на унаследованном сервере обычно не существует, — а буквально: кто способен подключиться, зная то, что знает. Ниже — единый организованный процесс аудита именно этого вопроса: SSH-ключи, пароли системных пользователей, sudo-права, токены и учётки панели хостинга, доступ к бэкапам. На выходе — не ощущение «вроде разобрались», а таблица с конкретными именами, способами входа и статусом каждого.

Почему это отдельная задача, а не пункт в общем разборе

Разбор унаследованного сервера обычно устроен так: сначала общая разведка — что вообще работает, где конфиги, есть ли бэкапы (этому посвящён отдельный порядок в статье «Достался чужой сервер без документации»), а вопрос доступов идёт одной из строк в общем списке. Для первого часа этого достаточно. Но как только острая фаза прошла, доступы заслуживают отдельного, полного прохода — и вот почему поверхностной проверки здесь мало.

На обычном, «живом» сервере с известной командой карта доступов — это сверка того, что вы и так примерно знаете, с реальностью: пять-семь имён, пара систем, расхождения в деталях. На унаследованном сервере вы не знаете даже примерного списка, а спросить часто не у кого — прежнего администратора либо нет на связи, либо доверять его словам «доступ был только у меня» не стоит. Каждое найденное имя, ключ или токен — это не сверка с ожиданием, а факт, который сначала нужно вообще обнаружить.

Вторая причина — точки входа почти никогда не ограничиваются SSH. Прежний администратор мог настраивать всё через панель хостинга, к которой у вас изначально нет доступа вообще. Бэкапы могли уходить во внешнее хранилище с отдельными учётными данными, зашитыми в скрипт, который вы ещё не нашли. API-токен CI/CD мог быть выписан подрядчику, который в глаза не видел сервер по SSH, но имеет право деплоить на него код. Пропустить любую из этих категорий — значит закрыть один замок, оставив дверь рядом открытой.

Важно: цель этого аудита — не сразу всё поменять. Смена паролей и отзыв ключей вслепую, до того как понятно, что от чего зависит, сама по себе рискует уронить рабочий сервис — безопасный порядок такой замены разобран отдельно в статье «Меняем пароли и ключи на живом сервере». Задача этой статьи — раньше: собрать полную и достоверную картину «кто технически может зайти», прежде чем решать, что с этим делать.

Карта точек доступа: что входит в аудит целиком

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

КатегорияЧто именно проверяемГде искать
SSH-доступКлючи в authorized_keys, разрешён ли вход по паролюСам сервер
Системные пользователиКто имеет login shell, у кого есть пароль в /etc/shadowСам сервер
Sudo и rootКто может стать root, есть ли NOPASSWDСам сервер
Панель хостинга/облакаСписок пользователей аккаунта провайдера, привязанные emailЛичный кабинет провайдера
API-токены и IAM-ключиПрограммные ключи с доступом к серверу, снапшотам, DNSПанель провайдера, конфиги на сервере
DNS-регистраторКто может менять записи и, значит, перехватить трафик доменаЛичный кабинет регистратора
Прямой доступ к БДУчётки СУБД отдельно от доступа на уровне ОССам сервер, конфиги приложения
БэкапыКто может читать, скачивать или удалять резервные копииХранилище бэкапов, отдельно от сервера
Мониторинг и CI/CDАгенты и пайплайны с ключами, которые заходят на сервер самиКонфиги systemd, .env, панели SaaS-сервисов

Часть этих категорий не видна с самого сервера в принципе — токен API хостинг-провайдера или список участников в панели регистратора нельзя найти через grep в /etc, для них нужен отдельный проход через веб-интерфейсы. Аудит доступов на унаследованном сервере — это не один скрипт, а минимум два параллельных фронта: «на сервере» и «в панелях снаружи».

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

SSH-ключи, системные пользователи и sudo: полная выгрузка с сервера

Начните с того, что видно изнутри — это даёт основной объём находок. Смотрите не выборочно по «известным» пользователям, а по всем сразу.

# все пользователи с интерактивным входом (не /nologin и не /false)
awk -F: '$7 !~ /nologin|false/ {print $1, $7}' /etc/passwd

# authorized_keys каждого такого пользователя, включая root
for u in $(awk -F: '$7 !~ /nologin|false/ {print $1}' /etc/passwd); do
  home=$(getent passwd "$u" | cut -d: -f6)
  if [ -s "$home/.ssh/authorized_keys" ]; then
    echo "== $u =="
    cat "$home/.ssh/authorized_keys"
  fi
done

# на случай нестандартного пути к файлу ключей
grep -i AuthorizedKeysFile /etc/ssh/sshd_config
find / -name authorized_keys 2>/dev/null -exec ls -la {} \;

Каждая строка в authorized_keys — потенциально отдельный человек или сервис, а комментарий в конце строки (user@host) — единственная подсказка о происхождении, которой нельзя всецело доверять: он редактируется так же легко, как любой текстовый файл. Если находите ключ с непонятным комментарием, не пытайтесь угадать владельца по одному файлу — сопоставление ключа с конкретным человеком за час, включая проверку истории входов, разобрано в статье «Ключ подрядчика в authorized_keys: аудит за час»; метод годится для любого найденного ключа, а не только подрядчицкого.

Дальше — пароли на уровне ОС, не только ключи:

# кто может входить по паролю (второе поле в shadow не начинается с ! или *)
sudo awk -F: '$2 !~ /^[!*]/ {print $1}' /etc/shadow

# разрешён ли вообще парольный вход по SSH
grep -E "^PasswordAuthentication|^PermitRootLogin" /etc/ssh/sshd_config

PasswordAuthentication yes — весомая находка сама по себе: пароль, в отличие от ключа, можно подобрать или узнать устно, и круг потенциальных «кто может зайти» шире любого списка файлов ключей.

Sudo проверяйте отдельно от факта наличия shell — ограниченный на вид аккаунт может иметь полный NOPASSWD: ALL:

getent group sudo wheel docker 2>/dev/null
cat /etc/sudoers
ls -la /etc/sudoers.d/
cat /etc/sudoers.d/* 2>/dev/null

Членство в группе docker по факту равносильно root, даже если человек формально не в sudo — через контейнер можно смонтировать корень хостовой файловой системы. Если натыкаетесь на пользователя, о котором никто в команде ничего не знает, — остановитесь на нём отдельно: как отличить забытый сервисный аккаунт от следа взлома, разобрано в статье «На сервере живёт пользователь, которого никто не создавал».

Отдельно посмотрите, кто заходил по факту — это отличает пассивный, забытый ключ от активно используемого:

last -50
lastb -20 2>/dev/null
lastlog | awk '$2 != "**Never" {print}'

Панель хостинга, API-токены и внешние сервисы, до которых не дотянуться по SSH

Самая частая ошибка — считать аудит законченным после проверки authorized_keys и sudo. Часть доступов, реально управляющих судьбой сервера, вообще не хранится на самой машине.

Панель провайдера или облачного аккаунта. Если у прежнего администратора остались права владельца или соадминистратора в личном кабинете хостинга (или в консоли AWS/DigitalOcean/аналогичном), он может остановить, удалить или пересоздать сервер снаружи, вообще не заходя внутрь по SSH — независимо от того, что вы нашли или не нашли в authorized_keys. Зайдите в раздел «Пользователи» или «Команда» личного кабинета и выпишите список руками — список из интерфейса надёжнее любого предположения.

API-токены и ключи с программным доступом. У большинства панелей хостинга и облачных провайдеров есть отдельный раздел API-ключей, не пересекающийся со списком людей: токен мог быть выписан для скрипта деплоя или интеграции и с тех пор не отзывался, а прав у него часто больше, чем у человеческого пользователя — например, полное управление инстансами. Проверьте этот раздел отдельно и для каждого токена выясните дату создания и последнего использования, если панель это показывает.

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

whois vashdomen.ru | grep -i "registrar\|admin"
dig NS vashdomen.ru +short

Список пользователей и API-ключей регистратора смотрите так же руками, в личном кабинете.

Токены, зашитые прямо в конфиги на сервере. Обратный случай, который тоже стоит учитывать в общей карте: ключи, которыми сам сервер стучится в сторонние сервисы — хранилище бэкапов, платёжный шлюз, почтовый релей.

grep -rniE "(api[_-]?key|token|secret)\s*[:=]" \
  /etc /opt /var/www /home --include="*.env" --include="*.yml" \
  --include="*.conf" 2>/dev/null | grep -v "^Binary"

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

Доступ к бэкапам — отдельная категория, которую часто забывают

Бэкапы обычно проверяют на предмет «есть ли они и работают ли» — это другой вопрос, чем «кто может их прочитать, скачать или удалить». Опасны они по двум причинам: содержат полный слепок остальных секретов сервера (пароли из дампа базы, ключи из архива /etc), а доступ к ним нередко устроен небрежнее, чем к самому серверу.

Где физически лежат копии. Если бэкап хранится на том же сервере или в том же облачном аккаунте без отдельных учётных данных — доступ к серверу автоматически означает доступ к бэкапам, отдельного пункта в таблице не появляется. Если копии уходят во внешнее хранилище (S3-совместимый бакет, другой сервер, сервис вроде Backblaze или аналога) — это отдельная система, которую нужно проверять как самостоятельную панель.

# ищем, куда именно и чем уходят бэкапы
crontab -l | grep -iE "backup|rsync|dump|restic|borg|rclone"
which restic borgbackup rclone 2>/dev/null
cat ~/.config/rclone/rclone.conf 2>/dev/null
grep -riE "RESTIC_REPOSITORY|RESTIC_PASSWORD|AWS_ACCESS_KEY" /etc/systemd/system/*.service* 2>/dev/null

Ключи доступа к самому хранилищу. У S3-совместимого бакета есть свои access-ключи — нередко у одного хранилища их заведено несколько, с разными правами (только запись против чтения и удаления), выданных в разное время разным людям. Смотрите список в панели хранилища, а не только в конфиге на сервере — конфиг покажет один ключ, в панели их может быть больше.

Ключ шифрования, если бэкап зашифрован. Легко упускаемая точка доступа: даже без прав на само хранилище, наличие ключа шифрования равносильно возможности прочитать содержимое любой скачанной копии. Проверьте, где он хранится — рядом с доступом к хранилищу (тогда это не отдельная защита, а иллюзия) или действительно отдельно.

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

Собираем итоговую таблицу «кто / как / зачем» и решаем, что делать с находками

Ценность этого аудита не в отдельных списках по категориям, а в одной сведённой таблице, которую можно открыть через месяц и сразу понять, кто и почему до сих пор может зайти. Формат — по одной строке на каждую точку доступа, а не на человека: если у одного имени есть и SSH-ключ, и учётка в панели хостинга — это две строки, отзывать их придётся по отдельности и в разных местах.

Кто/чтоКак заходитУровень доступаСтатусДействие
Прежний администраторSSH-ключ root@dmitry-laptopПолный (root)Не подтверждена легитимностьОтозвать после проверки зависимостей
agency-x (бывший подрядчик)Пользователь deploy, sudo без пароляПолный (через sudo)Проект закрытЗаблокировать, затем удалить
Панель хостингаУчётка с email прежнего админаВладелец аккаунтаТребует переоформленияСменить владельца/email
API-токен CIТокен в панели провайдера, создан давноУправление инстансамиИспользование не подтвержденоПроверить по логам, затем отозвать или перевыпустить

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

Прежде чем переходить от таблицы к действиям, для каждой критичной строки проверьте, не завязана ли на неё автоматизация — деплой-скрипт, мониторинг, интеграция, которая перестанет работать при отзыве:

crontab -u имя_пользователя -l 2>/dev/null
sudo systemctl list-units | grep -i имя_пользователя
grep -rl "имя_пользователя\|найденный-токен" /etc/systemd/system/ 2>/dev/null

Сама таблица — конечный продукт этой статьи, но не конечная точка процесса: как безопасно отозвать лишнее и сменить то, что остаётся, не уронив рабочий сервис, — отдельный, тоже методичный процесс, описанный в статье «Меняем пароли и ключи на живом сервере». Разница ролей простая: эта статья отвечает на вопрос «кто и как может сюда попасть прямо сейчас», та — «как это безопасно исправить, ничего не сломав».

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

С чего начинать, если времени мало и хочется закрыть самое опасное первым?

С root-доступа и sudo-прав — самая прямая и долгоживущая точка входа. Дальше — панель хостинга и DNS-регистратор: потеря контроля там означает потенциальную потерю всего сервера или домена, а не одной учётки. Остальное (бэкапы, второстепенные токены) можно закрыть вторым проходом в течение нескольких дней.

Сколько реально занимает такой аудит на сервере среднего размера?

Часть на самом сервере — обычно час-два, если сервисов немного. Внешние панели (хостинг, регистратор, хранилище бэкапов) добавляют ещё столько же, потому что там нет автоматизации и приходится смотреть руками. На сервер с историей в несколько лет закладывайте день, а не один вечер.

Чем это отличается от карты доступов, которую советуют вести постоянно?

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

Что делать, если найден токен или ключ, а понять, кому он принадлежит, не получается?

Не удалять вслепую и не оставлять вслепую. Проверьте логи использования, где они есть, поищите упоминания в переписке и cron/systemd на предмет зависимостей, и если ясности всё равно нет — зафиксируйте статус «неизвестно, требует наблюдения» и не откладывайте выяснение надолго.

Нужно ли аудировать доступ к базе данных отдельно, если уже проверили SSH и sudo?

Да — учётки СУБД живут по своей логике и не обязаны совпадать со списком системных пользователей. Прямой доступ в PostgreSQL или MySQL под отдельным паролем может быть у человека, у которого никогда не было SSH-ключа на этот сервер, и наоборот.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →