MAATRIX / Блог / Аудит сервера своими силами: план на выходные без подрядчика

Аудит сервера своими силами: план на выходные без подрядчика

MAATRIX

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

Суббота, утро: инвентаризация — что вообще живёт на сервере

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

Начните с сети и сервисов:

# кто слушает порты и от чьего имени
ss -tulnp

# запущенные systemd-сервисы
systemctl list-units --type=service --state=running

# если используется docker — контейнеры и проброшенные порты
docker ps -a
docker port $(docker ps -q)

# сколько пакетов установлено — база для сравнения после обновлений
dpkg -l | wc -l          # Debian/Ubuntu
rpm -qa | wc -l          # AlmaLinux/RHEL

Сверьте список открытых портов с тем, что реально нужно снаружи: обычно это 22 (SSH), 80/443 (веб), может быть VPN-порт. Всё остальное, что слушает 0.0.0.0 — Redis, MySQL, admin-панели, Docker API на 2375 — кандидат на перевод на 127.0.0.1 или закрытие фаерволом, об этом подробнее в блоке про базовую защиту ниже.

Что смотримКомандаНа что обратить внимание
Открытые портыss -tulnpСервисы, слушающие 0.0.0.0 без явной причины
Активные сервисыsystemctl list-units --state=runningНезнакомые unit-файлы, сервисы «из коробки» дистрибутива
Контейнерыdocker ps -aОстановленные контейнеры с публичными портами
Пакетыdpkg -l / rpm -qaПросто фиксируем число — будет с чем сравнивать после апдейта

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

Суббота, день: пользователи, права и SSH-ключи

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

# реальные пользователи (не системные), UID от 1000
awk -F: '$3>=1000 && $3<60000 {print $1, $3, $6}' /etc/passwd

# кто, кроме root, имеет UID 0 — это всегда тревожный флаг
awk -F: '$3==0 {print $1}' /etc/passwd

# кто в sudo/wheel
getent group sudo
getent group wheel

# NOPASSWD-правила — вход без пароля к sudo
grep -r NOPASSWD /etc/sudoers /etc/sudoers.d/ 2>/dev/null

# когда кто последний раз заходил
lastlog -b 90

Отдельно и внимательно — SSH-ключи в authorized_keys у каждого пользователя. Это самая частая находка при аудите: ключ подрядчика, который давно не работает над проектом, или тестовый ключ, добавленный полгода назад и забытый. Полная методика такой проверки с разбором, как отличить «свой забытый» ключ от чужого, — в статье «Ключ подрядчика в authorized_keys: аудит за час», здесь ограничимся минимумом:

for f in /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys; do
  echo "== $f =="
  cat "$f" 2>/dev/null
done

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

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

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

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

Суббота, вечер: ищем следы уже случившегося

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

Процессы и сетевая активность:

# процессы по нагрузке CPU — майнер почти всегда выдаёт себя здесь
ps auxf --sort=-%cpu | head -30

# исходящие соединения — пулы для майнинга, спам на 25-й порт, сканирование
ss -tunp

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

Автозагрузка и планировщик — второе по частоте место для закладок:

# cron каждого пользователя
for u in $(cut -f1 -d: /etc/passwd); do crontab -u "$u" -l 2>/dev/null && echo "^ user: $u"; done

# системные cron-каталоги и rc.local
ls -la /etc/cron.d /etc/cron.daily /etc/cron.hourly
cat /etc/rc.local 2>/dev/null

# systemd-таймеры
systemctl list-timers --all

Задания, которые каждые несколько минут дёргают curl/wget на незнакомый адрес или перезапускают что-то из /tmp, — почти всегда закладка, а не легитимная задача.

SUID/SGID-бинарники — способ повышения привилегий, который легко проверить и почти никогда не проверяют:

find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | sort

У свежей системы этот список стабилен и состоит из известных утилит (passwd, sudo, mount и подобных). Любой SUID-файл в /tmp, /var/tmp, /dev/shm или в домашней директории пользователя — почти гарантированная закладка, легитимных причин для этого практически не бывает.

И логи:

grep -Ei 'accepted|failed password' /var/log/auth.log | tail -100
journalctl -u ssh --since "30 days ago" | grep -i fail

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

Если по итогам вечера вы нашли что-то из перечисленного — чужой ключ с активностью, неизвестный SUID-бинарник, майнер, cron с закладкой, — стоп. Дальше не по этому плану: переходите к полноценному разбору инцидента, изоляции и решению «чистить или переустанавливать» из статьи «Взломали сервер: пошаговый план». Продолжать хардening поверх активной компрометации бессмысленно.

Воскресенье, утро: закрываем базовые дыры

Если суббота прошла чисто — сервер не скомпрометирован, просто не хардился, — воскресенье уходит на закрытие типовых дыр. Начните с обновлений:

apt update && apt list --upgradable    # Debian/Ubuntu
dnf check-update                        # AlmaLinux/RHEL

# автоматические обновления безопасности на будущее
apt install unattended-upgrades
dpkg-reconfigure unattended-upgrades

Дальше firewall — по умолчанию закрыто, открыто только нужное:

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

SSH — самый частый вектор входа, и здесь стоит навести порядок системно, а не одной галочкой. Полный разбор типичных ошибок при переходе на ключи вместо пароля — что ломается, если отключить PasswordAuthentication раньше времени, как не потерять доступ — в статье «SSH-ключи вместо пароля на сервере: частые ошибки и решения». Базовый набор для /etc/ssh/sshd_config:

PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
MaxAuthTries 3

Смена порта SSH с 22 на нестандартный иногда даёт эффект — снижает шум ботов в логах, — но не путайте это со security-мерой: это гигиена логов, а не защита. Реальную защиту от перебора паролей даёт связка ключей и fail2ban:

apt install fail2ban
systemctl enable --now fail2ban

Отдельно закройте то, что нашли утром в субботу открытым наружу без причины: базы данных, Redis, Docker API. Правило простое — если сервису не нужен доступ извне, он должен слушать 127.0.0.1, а не 0.0.0.0, и точка входа для внешнего мира — только через приложение или обратный прокси.

Воскресенье, день: бэкапы, которые переживут повторный взлом

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

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

# пример: rsync на отдельный бэкап-сервер с ограниченным ключом
rsync -avz -e "ssh -i /root/.ssh/backup_only_key" /var/www/ backup@BACKUP_HOST:/backups/site/

Проверьте восстановление прямо сейчас, а не в момент инцидента — разница между «бэкап вроде есть» и «бэкап реально разворачивается» решается за десять минут:

# разворачиваем последний дамп в тестовую базу и проверяем целостность
mysql -u root -p test_restore < /backups/latest_dump.sql

И третье — шифрование самих бэкапов, если они содержат персональные данные или что-то ценное, с ключом, который хранится отдельно от сервера и от места хранения бэкапов. Иначе кража архива равносильна краже боевых данных.

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

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

  • Мониторинг доступности — простой аптайм-чекер, который присылает алерт, если сервер или сайт легли. Не заменяет security-мониторинг, но часто первым сигнализирует о DDoS или падении сервиса после атаки.
  • Алерты по логам — правило, которое шлёт уведомление при всплеске Failed password или при появлении нового пользователя в sudo/wheel. Не обязательно ставить тяжёлый SIEM — на старте достаточно скрипта, который раз в час гоняет grep по свежим логам и пишет в телеграм-бот при совпадении.
  • Контроль за cron-задачами — здесь удобны внешние сервисы вроде healthchecks-подобных: задача не просто выполняется по расписанию, а «отмечается» на внешнем сервисе, и вы узнаёте, если она вдруг перестала запускаться или, наоборот, стала запускаться слишком часто (второй случай иногда выдаёт закладку раньше, чем что-либо ещё).
  • Периодический повтор аудита — поставьте в календарь напоминание раз в квартал повторить блоки субботы: инвентаризацию портов, список SSH-ключей, SUID-бинарники. Разница со «свежим» снимком из этой статьи находится за минуты и почти всегда красноречивее, чем разовая проверка.

Отдельно стоит настроить auditd для отслеживания изменений в критичных файлах (/etc/passwd, /etc/sudoers, authorized_keys) — тогда любое будущее изменение прав или ключей будет зафиксировано в логе с указанием, кто и когда это сделал, а не останется незамеченным до следующего ручного аудита.

Если весь этот план идёт на новом сервере, а не унаследованном с сомнительной историей, часть работы можно сократить: чистая машина с выбранным вами образом и без чужих учёток избавляет от половины субботних сюрпризов. У MAATRIX можно развернуть такой сервер в RU, US или UK за несколько минут и с оплатой из России картой или криптой — удобная точка старта для аудита, который дальше проще поддерживать в чистоте, чем разгребать заново.

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

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

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

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

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

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

Реально ли уложиться в один день, а не в выходные?

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

Что делать, если не хватает уверенности отличить угрозу от ложной тревоги?

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

Нужен ли антивирус в дополнение к этому плану?

Для Linux-сервера классический антивирус закрывает малую часть рисков по сравнению с проверкой процессов, cron и SUID вручную — большинство серверных компрометаций не ловится сигнатурным антивирусом вообще. Он не вреден как дополнительный слой, но не заменяет ручной аудит из этого плана.

С какой периодичностью повторять такой аудит?

Полный цикл — раз в квартал достаточно для большинства небольших проектов. Быстрая проверка ключевых пунктов (открытые порты, новые пользователи, SUID) — раз в месяц, это занимает 20–30 минут, если у вас уже есть базовый снимок для сравнения.

А если сервер обслуживает несколько человек и нельзя всё перепроверить за выходные?

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

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

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

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