Сервер ведёт себя странно неделю: семь признаков, что вы уже не одни
Сервер вроде работает, сайты отдаются, почта ходит — но что-то не так: раз в пару дней подскакивает нагрузка без видимой причины, мониторинг присылает алерт в три часа ночи, а вы не можете вспомнить, чтобы что-то деплоили. Это не повод паниковать и переустанавливать систему с нуля, но это повод потратить двадцать минут и пройтись по семи конкретным местам, где посторонний обычно оставляет следы. Ниже — не теория про кибербезопасность, а чек-лист: что смотреть и какой командой.
Содержание
- 1. Нагрузка CPU или сети скачет без объяснимой причины
- 2. В списке процессов есть то, чему вы не давали команду запускаться
- 3. В cron появились задачи, которые вы не создавали
- 4. Системные файлы изменились без вашего участия
- 5. Появились SSH-ключи или пользователи, которых вы не создавали
- 6. Сервер сам зачем-то стучится наружу
- 7. В логах авторизации — записи, которые не складываются в привычную картину
1. Нагрузка CPU или сети скачет без объяснимой причины
Первый сигнал — не сам факт высокой нагрузки, а то, что вы не можете её объяснить. Если днём трафик растёт из-за реальных посетителей — это нормально. Если нагрузка держится ночью, когда обычных пользователей нет, или сеть отдаёт мегабиты исходящего трафика, хотя сервер ничего никуда не должен отправлять, — это стоит разобрать.
# кто ест CPU прямо сейчас, сортировка по нагрузке
top -o %CPU
# то же самое, но с историей: сколько CPU процесс съел с момента запуска
ps aux --sort=-%cpu | head -20
# сколько трафика реально идёт по интерфейсам за интервал
sar -n DEV 1 5
Если sar не установлен — это тоже симптом, но не постороннего, а того, что на сервере нет базового мониторинга ресурсов, и разбираться придётся по логам постфактум. Отдельно посмотрите на средние значения нагрузки за долгий период: если uptime показывает average load, ощутимо выше числа ядер, а видимых процессов под это нет — это первый повод копать глубже, а не списывать на «сервер просто старый».
2. В списке процессов есть то, чему вы не давали команду запускаться
Второй признак — не нагрузка, а сам факт присутствия процесса, которого вы не заводили. Проблема в том, что «обычный» список процессов на сервере, где крутится десяток сервисов, довольно длинный, и глазами найти лишнее сложно. Здесь помогает не разглядывание вывода ps, а сравнение с тем, что должно быть.
# полный список процессов с деревом родитель-потомок
ps auxf
# процессы, которые слушают сеть — обычно интереснее всего
ss -tulnp
# что конкретно скрывается за странным PID
ls -la /proc/<PID>/exe
cat /proc/<PID>/cmdline
Обращайте внимание на процессы с именами, маскирующимися под системные (например, что-то похожее на kworker или systemd, но не в стандартном пути), на процессы, запущенные от www-data или nobody, но открывающие сетевые сокеты, и на процессы без родителя init/systemd — это может означать, что их запустили из cron или другой скрытой точки входа, а не через обычный сервис. Если бинарник, на который ссылается /proc/<PID>/exe, лежит во временной директории вроде /tmp или /dev/shm — это почти всегда повод остановиться и разобраться отдельно, легитимные сервисы так не работают.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать сервер3. В cron появились задачи, которые вы не создавали
Cron — один из самых удобных способов закрепиться на сервере: задача выполняется по расписанию, не привязана к конкретной сессии и легко теряется среди десятков легитимных заданий. Стоит проверить не только crontab текущего пользователя, но и системные точки, о которых часто забывают.
# crontab текущего и root-пользователя
crontab -l
sudo crontab -l -u root
# у всех пользователей системы сразу
for u in $(cut -f1 -d: /etc/passwd); do sudo crontab -l -u "$u" 2>/dev/null && echo "^-- $u"; done
# системные точки, которые часто забывают проверить
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/
cat /etc/crontab
# systemd-таймеры — современная альтернатива cron, тоже стоит проверить
systemctl list-timers --all
Особенно подозрительны задачи у пользователей, которых вы не заводили сами, задачи с обфусцированными командами (закодированными в base64 через echo ... | base64 -d | bash) и задачи, ссылающиеся на скрипты во временных директориях. Про один такой случай — когда задачу нашли у пользователя, которого никто не создавал, — есть отдельный разбор: реверс-шелл в cron у пользователя, которого не заводили. Если история знакома — не поленитесь прочитать, там разобран конкретный путь диагностики от подозрения до находки.
4. Системные файлы изменились без вашего участия
Изменённые бинарники и конфиги — более тревожный признак, чем cron-задача, потому что означают, что у постороннего, скорее всего, уже был root. Проверка сводится к сравнению текущего состояния файлов с тем, что должно быть по данным пакетного менеджера.
# Debian/Ubuntu: какие файлы из установленных пакетов изменены
sudo apt install -y debsums
debsums -c 2>/dev/null
# RHEL/AlmaLinux/CentOS: проверка целостности через rpm
rpm -Va --nomtime | grep -E '^..5'
# время изменения ключевых бинарников и конфигов
stat /bin/bash /usr/sbin/sshd /etc/passwd /etc/shadow /etc/ssh/sshd_config
# файлы, изменённые за последние 3 дня в системных директориях
find /etc /usr/bin /usr/sbin -mtime -3 -type f 2>/dev/null
Особое внимание — на /etc/ld.so.preload: этот файл в норме пустой или не существует вовсе, а его наличие с содержимым — классический способ подгрузить вредоносную библиотеку в каждый запускаемый процесс. Проверяется одной командой:
cat /etc/ld.so.preload 2>/dev/null && echo "файл существует и не пуст — разбираться немедленно"
Учтите: сама по себе команда debsums или rpm -Va покажет расхождения и по легитимным причинам — например, если конфиг правили вручную мимо пакетного менеджера, что на живом сервере встречается сплошь и рядом. Задача не паниковать при первом же расхождении, а смотреть на файлы, которые обычно не трогают руками: сам sshd, bash, sudo, login.
5. Появились SSH-ключи или пользователи, которых вы не создавали
Это один из самых опасных признаков, потому что чужой ключ в authorized_keys даёт постоянный доступ без пароля и без следов брутфорса в логах — вход будет выглядеть как обычная легитимная авторизация. Проверяйте по всем пользователям сразу, а не только по root.
# ключи авторизации у всех пользователей
sudo find / -name authorized_keys -exec ls -la {} \; -exec cat {} \;
# список пользователей системы с UID от 0 (обычные + системные)
awk -F: '{print $1, $3}' /etc/passwd | sort -n -k2
# пользователи с непустым паролем или интерактивным shell, которых не должно быть
awk -F: '($7 !~ /nologin|false/) {print $1, $7}' /etc/passwd
# кто состоит в sudo/wheel — группа, дающая полные права
getent group sudo wheel 2>/dev/null
Сверьте список пользователей с интерактивным shell со своим представлением о том, кто должен иметь доступ к серверу. Отдельно проверьте файл /etc/sudoers и /etc/sudoers.d/ на предмет строк, которые вы не добавляли. Похожая ситуация — когда доступ остаётся действующим для человека, который давно не должен иметь его, — разобрана в статье SSH-ключ уволенного сотрудника работал восемь месяцев: механика та же, посторонний доступ, просто в этом случае «посторонний» — бывший коллега, а не злоумышленник.
6. Сервер сам зачем-то стучится наружу
Легитимные сервисы обычно обращаются наружу по понятному и стабильному набору адресов: репозитории пакетов, DNS, API, к которому подключено приложение. Если сервер держит соединения с незнакомыми IP, особенно на нестандартных портах, или регулярно резолвит домены, которых нет ни в одном конфиге — это стоит проверить в первую очередь именно с точки зрения исходящего трафика, а не входящего.
# все установленные соединения с процессами, которые их держат
sudo ss -tunap
# только исходящие соединения на внешние адреса
sudo ss -tup state established | grep -v -E '127\.0\.0\.1|::1'
# кто и куда резолвит DNS чаще всего (если установлен tcpdump)
sudo tcpdump -i any -n port 53 -c 50
# статистика по соединениям с конкретным процессом
sudo lsof -i -P -n | grep <имя_процесса>
Отдельно обратите внимание на соединения на порт 6667 (классический IRC, до сих пор используется в части ботнетов), нестандартные высокие порты вроде 4444 или 1337, а также на исходящие подключения по протоколу, который сервер в норме не использует вообще — например, исходящий SSH с веб-сервера, у которого нет причин куда-то ходить по SSH. Если один и тот же внешний IP появляется в соединениях с интервалом в несколько минут — похоже на маячок (beacon), который «отзванивается» на управляющий сервер.
7. В логах авторизации — записи, которые не складываются в привычную картину
Последний и часто самый информативный признак — логи входа. Даже если посторонний зашёл легитимным ключом и не оставил следов брутфорса, факт самого входа обычно виден — просто теряется среди обычного шума.
# Debian/Ubuntu
sudo grep -E "Accepted|Failed" /var/log/auth.log | tail -100
# RHEL/AlmaLinux/CentOS и системы с journald
sudo journalctl -u sshd --since "7 days ago" | grep -E "Accepted|Failed"
# история входов с указанием IP и времени сессии
last -a | head -30
# кто сейчас залогинен
w
# последние успешные входы по каждому пользователю
sudo lastlog
Смотрите на вход с IP-адреса или геолокации, откуда никто из команды не работает, на успешный вход сразу после серии неудачных попыток (типичная картина для подбора пароля, который в итоге сработал), и на вход в нерабочее время под учёткой, которой обычно никто не пользуется в это время. Если auth.log короче, чем вы ожидали, или обрывается на конкретной дате без объяснения — это тоже сигнал: логи могли почистить, чтобы скрыть активность.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Один из семи признаков совпал — это точно взлом?
Не обязательно. Каждый пункт по отдельности может иметь безобидное объяснение: забытая cron-задача коллеги, легитимный скрипт мониторинга, старый пользователь, которого забыли удалить. Тревогу должны вызывать два и больше совпадения одновременно, особенно в комбинации «чужой процесс + чужое исходящее соединение» или «новый пользователь + вход с незнакомого IP».
С чего начать проверку, если времени мало?
С пунктов 5 и 7 — SSH-ключи/пользователи и логи авторизации. Они быстрее всего проверяются и чаще всего дают однозначный ответ: либо вы видите чужой доступ, либо нет.
Что делать, если признак подтвердился?
Не удалять и не перезагружать сервер сразу — это стирает улики и мешает понять, как посторонний попал внутрь. Сначала зафиксируйте находки (списки процессов, соединений, файлов — скопируйте на другую машину), затем изолируйте сервер от сети на уровне firewall, а дальше действуйте по плану: подробный порядок действий есть в статье что делать при взломе: план реагирования на инцидент.
Можно ли автоматизировать эти проверки, чтобы не гонять их руками?
Да, большинство команд из этой статьи можно собрать в скрипт и запускать по cron с отправкой отчёта на почту или в мессенджер, либо один раз внедрить полноценный аудит, который логирует изменения файлов и запуск процессов сам, не полагаясь на ручной обход раз в неделю.
Как не доводить до такой проверки в принципе?
Регулярный чек-лист базовой защиты — ключи вместо паролей, firewall по умолчанию deny, fail2ban, автообновления безопасности — закрывает большинство типовых путей проникновения ещё до того, как они понадобятся. Полный список пунктов — в чек-листе безопасности нового сервера.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →