Вопрос обычно возникает не на ровном месте. Сервер стал медленнее, хостер прислал письмо про исходящий трафик, или в почте нашлось уведомление о входе, которого вы не делали. Дальше начинается самое неприятное: непонятно, что смотреть и в каком порядке, а первое желание — снести и поставить заново — почти всегда преждевременно.
Ниже — порядок проверки, который занимает минут двадцать и в большинстве случаев даёт однозначный ответ. Он идёт от самого дешёвого к самому дорогому: сначала то, что видно сразу, потом то, что требует сверки.
Шаг первый: кто входил
Начинайте со входа. Если чужой попал внутрь, он почти наверняка попал через SSH, и след остался.
last -20
lastb | head -20
who
last покажет последние успешные входы, lastb — неудачные, who — кто сидит прямо сейчас. Смотреть надо не на количество, а на форму. Тысячи неудачных попыток с адресов, которые больше не возвращаются, — это обычный фоновый перебор, он идёт на любом публичном адресе непрерывно и ничего не значит.
Тревожно другое:
- успешный вход с адреса, где никого из ваших нет;
- вход под именем пользователя, которого вы не заводили;
- неудачные попытки под именем, которое на этой машине действительно есть — значит, кто-то узнал состав пользователей, а не бьёт по словарю;
- сессия, открытая сейчас, которую вы не открывали.
Отдельно проверьте, не появилось ли чужих ключей. Файл ~/.ssh/authorized_keys — самый частый способ закрепиться: пароль потом можно сменить сколько угодно раз, ключ останется.
cat ~/.ssh/authorized_keys
sudo cat /root/.ssh/authorized_keys
Каждая строка — это чей-то доступ. Если вы не можете сказать, чей именно, считайте, что чужой.
Шаг второй: что изменилось в системе
Проникновение почти всегда оставляет следы на диске: подменённый бинарник, дописанный конфиг, новый файл в каталоге веб-сервера. Проверять это глазами бесполезно — нужен эталон.
На Debian и Ubuntu эталон уже есть: каждый пакет знает контрольные суммы своих файлов.
sudo apt install debsums
sudo debsums -c
Команда выведет файлы, которые отличаются от того, что положил дистрибутив. Часть находок будет законной — конфигурационные файлы под /etc для того и существуют, чтобы их править. А вот изменённый исполняемый файл в /usr/bin, /usr/sbin или /bin на сервере, который вы не трогали руками, — это уже разговор.
Второй источник — свежие файлы там, где их быть не должно. Веб-шелл обычно лежит в каталоге загрузок и выглядит как безобидный .php:
find /var/www -type f -name '*.php' -mtime -14 -ls
Четырнадцать дней — просто отправная точка; подставьте срок, в течение которого вы точно ничего не выкладывали.
Шаг третий: что уходит наружу
Взломанный сервер редко ломают ради самого сервера. Его используют: рассылать спам, майнить, ходить в чужие сети, держать чужие файлы. Всё это создаёт исходящие соединения, которых раньше не было.
ss -tulpn
ss -tp state established
Первая команда покажет, что слушает входящие, вторая — что установлено сейчас. Читать надо колонку с процессом. Вопросы вызывают: незнакомый процесс, слушающий на 0.0.0.0; исходящие соединения на высокие порты к адресам, с которыми вашему приложению нечего делать; и особенно процесс, запущенный из /tmp или /dev/shm — из этих каталогов ничего легального не запускается.
Заодно посмотрите на нагрузку. Майнер выдаёт себя тем, что процессор занят постоянно, а сайт при этом никакой популярностью не пользуется.
Если признаки нашлись
Первое побуждение — быстро всё почистить: удалить чужой ключ, убить процесс, стереть файл. Так делать не надо, потому что вы уничтожите то, по чему потом можно было бы понять, как он вошёл. А если не понять — он войдёт снова, и уже завтра.
Порядок, который бережёт и данные, и картину:
- Сделать снимок диска у хостера, если такая возможность есть. Это единственный шаг, который потом нельзя повторить.
- Отрезать машину от сети или закрыть всё, кроме своего IP, — но не выключать. При выключении вы потеряете список процессов и открытые соединения, а это половина улик.
- Сохранить наружу логи:
/var/log/auth.log, логи веб-сервера, вывод трёх команд выше. - Только теперь разбираться, как вошли.
Переустановка с нуля — правильный финал, если доступ был получен с правами root. Никакая чистка не даёт гарантии, что не осталось закладки. Но переустанавливать, не поняв причину, бессмысленно: вы вернёте ту же дыру на свежую систему.
Как сделать, чтобы вопрос не возникал внезапно
Всё перечисленное — это разовая проверка вручную, и она отвечает на вопрос «что происходит прямо сейчас». Беда в том, что задают его обычно поздно: когда уже написал хостер или упал сайт.
Каждая из этих проверок существует как отдельный инструмент, который умеет следить постоянно: неудачные входы — fail2ban, изменения файлов — AIDE, целостность пакетов — debsums, открытые порты — регулярный снимок ss. Поставить их по отдельности несложно; сложнее приучиться каждый день заходить и читать шесть разных выводов, поэтому на практике их не читают.
Смысл собранной панели ровно в этом: те же самые данные, но на одной странице и с историей, чтобы «стало не так, как вчера» было видно без специального похода за этим. Ниже — страницы демо, где показано, как это выглядит в собранном виде.