Кто заходил на сервер, пока вас не было: разбор истории входов
Вы открываете сервер после отпуска, недели простоя проекта или просто давно не заходили — и первая мысль: а не побывал ли тут кто-то посторонний? Ответ уже лежит на диске: Linux с первого дня пишет, кто, когда и откуда входил, причём и удачные попытки, и неудачные. Проблема не в отсутствии данных, а в том, что их редко смотрят до момента, когда уже поздно. Разберём, какими командами поднять эту историю и на какие паттерны в ней обращать внимание, а какие тревоги окажутся ложными.
Содержание
- Три источника: wtmp, btmp и auth.log — что за что отвечает
- last и lastb: кто входил и кто пытался войти
- lastlog: когда каждый пользователь заходил в последний раз
- Разбор auth.log/secure: успешный вход после серии неудач
- Необычное время и новая география
- Ложные срабатывания: чего не стоит пугаться
- Что делать, если находка подтвердилась
Три источника: wtmp, btmp и auth.log — что за что отвечает
Прежде чем звать команды, стоит понимать, откуда они берут данные — это объясняет, почему одни события видны, а другие нет.
/var/log/wtmp— бинарный журнал успешных входов и выходов, сессий reboot/shutdown. Его читает командаlast./var/log/btmp— бинарный журнал неудачных попыток входа (bad). Его читаетlastb./var/log/lastlog— бинарный файл с временем *последнего* входа каждого пользователя системы. Его читаетlastlog./var/log/auth.log(Debian/Ubuntu) или/var/log/secure(RHEL/AlmaLinux/CentOS) — текстовый лог PAM и sshd, где события расписаны подробно: с какого IP, каким методом (пароль/ключ), для какого пользователя, с точным сообщением об ошибке.
Первые три файла — компактные структурированные записи, удобные для быстрого обзора. auth.log/secure — подробный текстовый журнал, туда стоит идти, когда нужен контекст конкретного события: например, при попытке подключения по ключу, который не подошёл, last просто не покажет ничего (сессия не открылась), а в auth.log останется строка с причиной отказа.
Важный практический момент: все три бинарных файла — это плоские журналы без ротации по умолчанию на многих дистрибутивах, либо ротируются logrotate с ограниченной глубиной (обычно несколько месяцев). Если нужна история глубже — настраивайте отдельное хранение заранее, после инцидента её уже не восстановить.
last и lastb: кто входил и кто пытался войти
last без аргументов выдаёт список успешных сессий, начиная с самой свежей:
last -F | head -20
Флаг -F печатает полные даты входа и выхода (без него год иногда опускается, что путает при разборе логов за прошлые месяцы). Типичная строка:
ivan pts/0 203.0.113.45 Wed Aug 26 09:14:02 2026 - Wed Aug 26 18:40:11 2026 (09:26)
root pts/1 198.51.100.20 Fri Aug 28 03:12:47 2026 - Fri Aug 28 03:13:02 2026 (00:00)
Что здесь читать: пользователь, IP источника, время входа и выхода, продолжительность сессии в скобках. Вторая строка в примере — пример того, что должно насторожить: вход под root в 03:12 ночи, сессия длиной 15 секунд. Само по себе это не доказательство взлома, но повод посмотреть внимательнее.
Полезные варианты вызова:
last -a # IP-адрес выносится в последний столбец, удобнее для grep
last root # только сессии конкретного пользователя
last -s "2026-08-20" # сессии начиная с даты
last -x # показывает события reboot/shutdown вперемешку с входами
lastb работает так же, но показывает неудачные попытки входа — то есть, по сути, сырой журнал перебора паролей:
sudo lastb -F | head -20
root ssh:notty 185.220.101.45 Thu Aug 27 22:14:01 2026 - Thu Aug 27 22:14:01 2026 (00:00)
admin ssh:notty 185.220.101.45 Thu Aug 27 22:14:03 2026 - Thu Aug 27 22:14:03 2026 (00:00)
oracle ssh:notty 185.220.101.45 Thu Aug 27 22:14:05 2026 - Thu Aug 27 22:14:05 2026 (00:00)
Требует root или чтения /var/log/btmp (файл обычно доступен только root/adm). Если сервер вообще смотрит в интернет, lastb почти гарантированно покажет сотни или тысячи строк — это фоновый шум ботов, перебирающих типовые логины (root, admin, oracle, ubuntu, test). Разбирать его построчно бессмысленно, но полезно смотреть агрегированно:
sudo lastb | awk '{print $3}' | sort | uniq -c | sort -rn | head -10
Эта команда покажет, с каких IP было больше всего неудачных попыток — если один адрес резко выделяется на общем фоне, стоит проверить, не пробовал ли он в итоге войти успешно (следующий раздел).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверlastlog: когда каждый пользователь заходил в последний раз
last и lastb дают историю событий, а lastlog — снимок «последний раз» по каждому пользователю системы разом:
lastlog
Username Port From Latest
root pts/1 198.51.100.20 Fri Aug 28 03:12:47 +0000 2026
ivan pts/0 203.0.113.45 Wed Aug 26 09:14:02 +0000 2026
deploy **Never logged in**
backup **Never logged in**
Это удобно для двух задач. Первая — быстро увидеть, входил ли вообще пользователь, под именем которого что-то произошло: если сервисный аккаунт backup вдруг оказался с реальным Latest, а не Never logged in, значит под ним кто-то логинился интерактивно, чего быть не должно. Вторая — инвентаризация: lastlog -b 90 покажет пользователей, не входивших последние 90 дней — кандидатов на отключение или удаление, особенно если это учётки бывших сотрудников или подрядчиков.
lastlog -u ivan # только по одному пользователю
lastlog -b 90 # не входившие 90+ дней
Ограничение: lastlog показывает только *последний* вход, не историю. Для конкретного пользователя историю всех его сессий смотрите через last ivan.
Разбор auth.log/secure: успешный вход после серии неудач
Самый показательный паттерн компрометации — не сам факт перебора (он идёт постоянно и почти всегда безрезультатно), а успешный вход, которому предшествовала серия неудачных попыток с того же IP. Это выглядит как подобранный пароль или угаданный логин.
Смотрим сырые записи sshd в auth.log (Debian/Ubuntu):
sudo grep "sshd" /var/log/auth.log | grep -E "Failed password|Accepted"
или secure (RHEL/AlmaLinux):
sudo grep "sshd" /var/log/secure | grep -E "Failed password|Accepted"
Типичные строки:
Aug 27 22:14:01 srv sshd[8821]: Failed password for root from 185.220.101.45 port 51230 ssh2
Aug 27 22:14:03 srv sshd[8822]: Failed password for invalid user admin from 185.220.101.45 port 51244 ssh2
...
Aug 27 22:19:47 srv sshd[8901]: Accepted password for root from 185.220.101.45 port 51890 ssh2
Если после десятков Failed password с одного IP вдруг идёт Accepted с того же адреса и в тот же временной интервал — это почти наверняка удачный подбор, а не совпадение. Быстрый способ найти такие IP по всему логу:
sudo grep "Failed password" /var/log/auth.log | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn > /tmp/failed_ips.txt
sudo grep "Accepted" /var/log/auth.log | grep -oE "from [0-9.]+" | sort -u > /tmp/accepted_ips.txt
grep -Ff <(awk '{print $3}' /tmp/accepted_ips.txt) /tmp/failed_ips.txt
Первая команда считает неудачные попытки по IP, вторая собирает список адресов, с которых был хоть один успешный вход, третья пересекает их — на выходе список IP, которые одновременно перебирали пароль *и* в итоге зашли. Ноль строк на выходе — хороший знак. Непустой список — повод разбираться прямо сейчас: менять пароли, проверять authorized_keys на добавленные ключи, смотреть history и запущенные процессы под скомпрометированной учёткой.
Отдельно стоит смотреть на строку Invalid user — она означает, что подключались под логином, которого вообще нет в системе (боты перебирают типовые имена). Это нормальный фон, но если среди них мелькает реальное имя пользователя, которого не должно быть в публичном обороте (например, личное имя админа, а не root/admin), это может значить, что список ваших логинов кто-то уже разведал — например, из утечки или из старого репозитория с конфигами.
Необычное время и новая география
Второй паттерн — вход, который формально успешен и не связан с перебором, но выбивается по контексту: время суток или источник, нетипичные для этого пользователя.
Для времени суток полезно построить простое распределение входов по часам:
last -F | grep -oE '[0-9]{2}:[0-9]{2}:[0-9]{2}' | cut -d: -f1 | sort | uniq -c
Если у вас команда, работающая в дневное время по одному часовому поясу, а история показывает регулярные единичные всплески в 3-4 часа ночи — это либо cron-задача, ошибочно попавшая в интерактивный лог (проверьте, не деплой ли это через SSH), либо вход, который стоит уточнить у владельца учётки напрямую.
Для географии/IP всё несколько сложнее, потому что сама по себе Linux-система не хранит гео-привязку — только IP. Практический способ: вывести уникальные IP по пользователю за период и проверить их через whois или любой IP-lookup сервис:
last ivan -F | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | sort -u
whois 203.0.113.45 | grep -i country
Если пользователь обычно заходит с одного-двух статичных IP (домашний, офисный), а в истории появился адрес из совершенно другой страны или подсети дата-центра (не провайдера, не мобильного оператора) — это стоит уточнить. Особенно если такой вход совпал по времени с чем-то ещё подозрительным: изменением файлов, новым cron-заданием, неожиданным исходящим трафиком.
Для регулярного контроля такие сверки удобнее автоматизировать, а не гонять руками при каждой проверке — собрать данные один раз в скрипт и получать готовый отчёт, а не искать вручную каждый раз.
Ложные срабатывания: чего не стоит пугаться
Прежде чем поднимать тревогу по каждому необычному входу, стоит знать типичные легитимные причины, которые выглядят подозрительно, но ими не являются.
- VPN и смена провайдера. Пользователь включил VPN или сменил домашнего провайдера — IP резко изменился, иногда даже страна (для VPN с выходом в другой регион). Это самая частая причина ложной тревоги. Если у вас настроена двухфакторная аутентификация для SSH, риск от таких скачков IP снижается — успешный вход всё равно требует второго фактора, а не только знания пароля или наличия ключа. Как её включить, разобрано в статье про двухфакторную аутентификацию SSH на VPS.
- Мобильный интернет. У операторов мобильной связи IP клиента может меняться по несколько раз в день из-за NAT на стороне оператора, и гео-привязка через whois часто указывает не на реальный город, а на ближайший узел оператора — иногда в другом регионе или стране. Не полагайтесь на whois-гео как на точный факт местоположения.
- Динамический IP + долгий перерыв. Если пользователь не заходил месяц и IP за это время сменился провайдером на новый диапазон — это нормально для домашнего интернета с динамической адресацией.
- CI/CD и автоматизация. Деплой-скрипты, бэкап-джобы и мониторинг тоже заходят по SSH, часто в ночное время (когда нагрузка ниже) и с IP облачных провайдеров, которые могут показаться «чужими», если вы не держите в голове список используемых сервисов.
- Короткие сессии под root. Не любая короткая сессия — взлом. Автоматизированные скрипты (Ansible, деплой через
ssh user@host 'command') создают сессии длиной в секунды — это нормально, если совпадает с расписанием ваших задач.
Ключевой принцип: единичный необычный признак — это повод посмотреть внимательнее, а не повод паниковать. Тревожен *набор* признаков вместе: новый IP + нетипичное время + короткая сессия под привилегированной учёткой + отсутствие объяснения от владельца аккаунта.
Что делать, если находка подтвердилась
Если после разбора логов картина складывается в подтверждённую компрометацию — успешный вход после перебора, вход под учёткой, которой никто не пользовался, действия, о которых пользователь не знает — дальше это уже не вопрос анализа логов, а вопрос реагирования: смена всех паролей и ключей, проверка authorized_keys и cron на посторонние записи, изоляция сервера от сети до выяснения масштаба. Пошаговый план на такой случай разобран в статье что делать при взломе сервера — держите её под рукой ещё до того, как она понадобится.
Если по итогам разбора всё чисто, но сам процесс проверки истории входов делался впервые и вручную — имеет смысл закрыть базовые дыры на будущее: перейти на вход по SSH-ключу вместо пароля (это резко уменьшит шум и сами возможности перебора — как настроить, описано в статье про SSH-ключи вместо пароля на Ubuntu 24.04) и поставить fail2ban, чтобы IP с сериями неудачных попыток банились автоматически, не дожидаясь, пока вы вручную прогоните lastb — установка описана в статье про Fail2ban на Ubuntu 24.04.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли подделать вывод last, чтобы скрыть следы взлома?
Да, если у злоумышленника есть root-доступ, он может отредактировать /var/log/wtmp специальными утилитами или просто затереть файл. Это одна из причин, почему для серьёзного расследования логи стоит централизованно копировать на отдельный сервер сразу, а не полагаться только на локальные файлы — при компрометации локальные записи не гарантированно надёжны.
Почему lastb показывает пустой вывод, хотя я точно вижу неудачные попытки в auth.log?
Обычно причина в правах — /var/log/btmp читается только с root, попробуйте sudo lastb. Реже — файл отсутствует или не создаётся, тогда нужно проверить, что PAM-модуль pam_lastlog/pam_tally2 (или его аналог для вашего дистрибутива) действительно пишет в btmp, и что файл существует (sudo touch /var/log/btmp && sudo chmod 660 /var/log/btmp).
Как долго хранится история в wtmp/btmp по умолчанию?
Зависит от logrotate-конфигурации дистрибутива, обычно это несколько недель-месяцев с ротацией и сжатием старых копий (wtmp.1, wtmp.2.gz и т.д.). Если нужна история на год и больше — под требования комплаенса или внутренней политики — настраивайте отдельное хранение и увеличивайте rotate в конфиге логротейта заранее.
Что делать, если сервер вообще не пишет auth.log?
Проверьте, что запущен и работает rsyslog или journald (systemctl status rsyslog или journalctl -u sshd --since today) — на некоторых минимальных образах логирование в файл отключено по умолчанию в пользу только journald, тогда события sshd смотрите через journalctl -u ssh (или sshd, в зависимости от дистрибутива).
Разница между Failed password и Invalid user в логе — это важно?
Да. Failed password for <user> значит, что учётка существует, но пароль не подошёл — то есть атакующий (или ошибающийся легитимный пользователь) знает верный логин. Invalid user <name> значит, что такого пользователя вообще нет — это почти всегда автоматический перебор типовых имён ботом, не связанный с конкретным знанием о вашей системе.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →