Журнал Ubuntu связывает вход по SSH с последующими действиями администратора
Безопасность

Как проверить входы по SSH и действия sudo на Ubuntu Server

Находим успешные и неудачные входы, читаем журнал OpenSSH, сопоставляем события sudo и понимаем, когда начинать расследование.

Содержание

Проверка входов нужна не только после явного взлома. Она помогает ответить на обычные вопросы: кто подключался к VPS ночью, почему изменилась конфигурация и действительно ли автоматическая публикация использовала свою учётную запись.

Полной картины в одной команде нет. last показывает историю сеансов, журнал OpenSSH — решение об аутентификации, а события sudo — запросы на повышение прав. Их связывают по времени, пользователю и адресу. Ни один из этих признаков по отдельности не доказывает атаку.

Сначала зафиксируйте время сервера

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

timedatectl status
date --iso-8601=seconds

timedatectl должен показать правильный часовой пояс и строку System clock synchronized: yes. Вторая команда даёт точную отметку со смещением, например +03:00. Запишите её рядом с причиной проверки.

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

Узнайте, когда система загрузилась:

uptime -s
journalctl --list-boots

Первая команда печатает время текущей загрузки. Вторая перечисляет загрузки, которые сохранились в journal. Так можно отличить реальный выход пользователя от оборванной перезагрузкой записи и выбрать нужный boot для анализа.

Посмотрите активные и недавние сеансы

Начните с людей, которые подключены прямо сейчас. Две короткие команды показывают одни и те же сеансы с разной детализацией и не завершают их:

who
w

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

Историю последних входов выведите отдельно:

last -a -F | head -n 30

last читает системную базу wtmp. Параметр -F показывает полные даты, -a переносит адрес в конец строки, а head ограничивает объём. Запись still logged in требует проверки через who: после аварийной остановки она иногда остаётся без реального активного сеанса.

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

lastlog | head -n 30

Never logged in означает, что в базе lastlog нет успешного сеанса. Это нормально для многих системных пользователей. Не пытайтесь входить под ними ради проверки: сервисные учётные записи часто специально лишены интерактивного shell.

Отделите ошибки входа от успешной аутентификации

На системах, где ведётся база btmp, последние неудачные входы показывает lastb:

sudo lastb -a | head -n 30

Большое число неизвестных имён на публичном SSH обычно связано с автоматическим сканированием. Сама по себе строка отказа означает, что вход не состоялся. Опаснее последовательность, где после серии ошибок появляется успешная аутентификация того же пользователя или адреса.

Подробное решение принимает служба OpenSSH. Посмотрите её журнал за последний час:

sudo journalctl -u ssh.service --since '1 hour ago' --output short-iso --no-pager

В Ubuntu unit обычно называется ssh.service. Параметр --since ограничивает период, short-iso добавляет удобную дату, а --no-pager выводит результат прямо в терминал. Если unit не найден, узнайте фактическое имя через systemctl status ssh и проверьте журнал аутентификации, принятый в вашем выпуске.

В строках OpenSSH встречаются разные результаты:

  • Accepted publickey — ключ принят, сеанс разрешён;
  • Accepted password — пароль принят;
  • Failed password — пароль отвергнут;
  • Invalid user — запрошенного пользователя нет;
  • Connection closed до аутентификации — соединение закончилось без входа.

Для успешной строки запишите пользователя, IP, время и отпечаток ключа, если он присутствует. Сверьте отпечаток с перечнем выданных открытых ключей. Адрес тоже требует контекста: домашний интернет, мобильная сеть и VPN могут менять его без злого умысла.

Найдите события конкретного пользователя или адреса

Когда известен один признак, отфильтруйте узкий интервал. Например, для пользователя deploy за последние сутки:

sudo journalctl -u ssh.service --since yesterday --no-pager | grep 'deploy'

Слово deploy в команде — пример. Подставьте точное имя своей учётной записи. Просмотрите строки вокруг найденного времени в полном журнале: простой grep убирает соседний контекст и может совпасть с частью другого текста.

Поиск только по Accepted даёт быстрый список успешных решений SSH:

sudo journalctl -u ssh.service --since yesterday --no-pager | grep 'Accepted '

Каждая строка требует ответа на три вопроса: известен ли пользователь, принадлежит ли ему использованный ключ и объясним ли источник. Пустой вывод не доказывает, что входов не было: срок хранения, другой unit или внешний механизм аутентификации могли оставить события в другом месте.

Свяжите вход с использованием sudo

После успешного входа пользователь мог выполнять обычные команды либо запросить административные права. Выведите события программы sudo за тот же период:

sudo journalctl _COMM=sudo --since yesterday --output short-iso --no-pager

Фильтр _COMM=sudo выбирает сообщения процесса sudo. В зависимости от конфигурации строка содержит исходного пользователя, терминал, рабочий каталог, целевого пользователя и команду. Сопоставьте время и терминал со входом SSH.

Запись sudo не гарантирует, что указанная программа завершилась успешно. Кроме того, команда sudo -i открывает root-shell, после чего отдельные действия внутри неё не видны как новые вызовы sudo. Для повседневной работы отдельные команды с sudo оставляют более понятный след, чем длительная административная оболочка.

Если из журнала следует изменение службы, проверьте её собственные события в том же интервале. Если менялся файл, сравните его с доверенной копией в Git или системе управления конфигурацией. Время изменения файла помогает искать, но его можно изменить, поэтому оно не является самостоятельным доказательством.

Проверьте пользователей, ключи и административные файлы

Список всех локальных учётных записей выводится через системную базу пользователей:

getent passwd

Сравните имена и домашние каталоги с известным перечнем. Многие записи принадлежат пакетам и службам; неизвестное имя сначала проверьте через пакет и unit, а не удаляйте.

Найдите файлы authorized_keys и покажите только метаданные:

sudo find /home /root -path '*/.ssh/authorized_keys' -type f -printf '%TY-%Tm-%Td %TH:%TM %u %m %p\n'

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

Для разбора ключей локально используйте отпечатки, затем сопоставляйте их с владельцами в своём реестре. Неизвестная строка в authorized_keys после неизвестного успешного входа — достаточная причина перейти к плану реагирования.

Постройте короткую временную линию

Не копируйте в заметки тысячи строк. Начните с таблицы:

Время Источник Событие Что подтверждает Что ещё проверить
10:04 UTC журнал SSH принят ключ пользователя deploy отпечаток и IP был ли запланирован релиз
10:05 UTC sudo перезапущена служба терминал и команда журнал этой службы
10:06 UTC мониторинг сайт не отвечает внешний запрос конфигурация и релиз

Для просмотра всех системных сообщений вокруг конкретного события задайте точные границы:

sudo journalctl --since '2026-09-05 10:00:00 UTC' --until '2026-09-05 10:10:00 UTC' --output short-iso-precise --no-pager

Дата здесь только пример формата. Подставьте свой интервал и часовой пояс. Точный вывод позволяет увидеть запуск службы, сетевую ошибку и действие автоматизации рядом со входом, не теряясь во всём журнале.

Опишите нормальные способы доступа

Чтобы неизвестное событие действительно выделялось, заранее запишите:

  • какие люди имеют интерактивный SSH-доступ;
  • какой отпечаток ключа принадлежит каждому человеку и устройству;
  • используется ли VPN и какие адреса ожидаемы;
  • какая учётная запись выполняет публикацию;
  • в какое время работают плановые задачи;
  • кто проверяет предупреждение.

Такой перечень не объявляет любую новизну атакой. Он позволяет быстро спросить конкретного владельца и отличить ночной релиз от подключения, которому никто не может дать объяснение.

Убедитесь, что журнал хранится достаточно долго

Покажите, сколько места занимают активные и архивные данные systemd journal. Команда только читает текущую статистику и не запускает очистку:

journalctl --disk-usage

Ответ содержит суммарный размер активных и архивных журналов. Слишком маленький срок стирает полезную историю, слишком большой объём может заполнить диск. Ограничения зависят от размера VPS и количества событий, поэтому их выбирают после наблюдения, а не копируют как случайное число.

Локальный журнал можно удалить после получения root-доступа. Если модель угроз требует независимых доказательств, отправляйте важные события на отдельный защищённый узел. Такой канал тоже нуждается в шифровании, ограниченных правах, контроле места и проверке доставки.

Что делать при неизвестном успешном входе

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

После этого проверяются новые пользователи, ключи, задачи cron, systemd units, изменения приложения и внешние токены. Если неизвестный пользователь мог получить root, локальным журналам и программам уже нельзя полностью доверять. Действуйте по плану реагирования на инцидент и готовьте чистое восстановление.

Fail2Ban уменьшает повторные ошибки, но не замечает успешный вход украденным ключом. Основой остаются безопасная конфигурация SSH, отдельные ключи и регулярная проверка журнала.

Первоисточники

Рекламное местоВаша компания здесьРазместить рекламу

Самопроверка

Проверьте, что материал усвоен

Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.

01Почему анализ начинается с проверки времени сервера?
02Какая запись подтверждает успешную аутентификацию ключом?
03Доказывает ли строка sudo успешное выполнение команды?

Разбираем коротко

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

Показывает ли last все входы по SSH?

Нет. last даёт быстрый обзор сеансов по базе wtmp, но запись может отсутствовать или остаться незакрытой после сбоя. Решение OpenSSH об аутентификации нужно проверять в журнале службы ssh.

Почему в журнале много Failed password и Invalid user?

Публичный SSH постоянно сканируют автоматические программы. Важнее проверить, не было ли после отказов успешного входа, неизвестного пользователя, необычного ключа или административного действия.

Что делать при неизвестном успешном входе?

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