# Использование системных команд systemctl и journalctl

В этой инструкции мы рассмотрим две системные команды, которые нужны для полноценного администрирования на Linux. Дополнительные возможности этих команд позволяют собрать общую информацию о работе сервера и установленных приложений, не используя при этом каких-то сложных инструментов.

Для начала работы нам понадобится:

  • подготовленный к работе сервер под управлением Ubuntu. Мы будем рассматривать работу именно на Ubuntu, но общий синтаксис и принцип работы команды распространяются также на Debian и CentOS.
  • установленный веб-сервер, например, Nginx. На самом деле обе команды универсальны, использовать Nginx мы будем исключительно в качестве образца для исследования.

# Systemctl

Начнём изучение с команды systemctl. Она предназначена для прямой работы с приложениями. С помощью базовых функций этой команды можно запустить приложение:

sudo systemctl start app

Остановить его:

sudo systemctl stop app

Добавить его в автозагрузку:

sudo systemctl enable app

Удалить оттуда:

sudo systemctl disable app

Важно помнить, что команда systemctl выполняется от имени администратора, поэтому не забывайте указывать префикс sudo.

Также при работе с командой systemctl можно не указывать .service расширение после названия приложения — команда сама проверяет доступность приложений в списке сервисов и выполняет команды в соответствии с ним. Это упрощает синтаксис команды.

# restart vs reload

Для перезапуска приложений у systemctl есть две опции: restart и reload. Синтаксис команды для запуска этих функций стандартный:

sudo systemctl restart app

sudo systemctl reload app

Основное различие этих функций — во взаимодействии с приложениями. Если restart полностью останавливает приложение и запускает его заново, то reload просто позволяет приложению перечитать конфигурационный файл, с которым оно работает, без полного перезапуска.

# Статус

Одна из основных функций для проверки работы приложений — status:

sudo systemctl status nginx

# Output

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-03-30 08:01:48 +05; 5h 12min ago
       Docs: man:nginx(8)
    Process: 354 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 370 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 383 (nginx)
      Tasks: 3 (limit: 19660)
     Memory: 11.3M
     CGroup: /system.slice/nginx.service
             ├─383 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             ├─384 nginx: worker process
             └─385 nginx: worker process

Mar 24 10:19:27 host systemd[1]: Stopping A high performance web server and a reverse proxy server...
Mar 24 10:19:28 host systemd[1]: nginx.service: Succeeded.

Эта команда выводит на экран общую информацию о приложении — его статус (Active / Inactive (dead)), добавлено оно в автозагрузку или нет (Enabled / Disabled), PID процесса, количество используемой памяти, зависимости и последние несколько строк лога. Здесь же выводятся системные ошибки при запуске приложения.

Эта информация бывает очень полезной при поиске ошибок и отладке работы приложения.

Вариации этой команды — is-active, is-enabled, is-failed — позволяют проверить одно конкретное состояние приложения без вывода на экран всей остальной информации:

sudo systemctl is-enabled nginx

# Output
enabled

# Просмотр установленных приложений

Также systemctl позволяет проверить список всех установленных на машине приложений:

sudo systemctl list-units

# Output

UNIT                               LOAD   ACTIVE SUB       DESCRIPTION

console-getty.service              loaded active running   Console Getty
containerd.service                 loaded active running   containerd container runtime
  cron.service                     loaded active running   Regular background program processing daemon
  dbus.service                     loaded active running   D-Bus System Message Bus
  docker.service                   loaded active running   Docker Application Container Engine
  fail2ban.service                 loaded active running   Fail2Ban Service
  getty@tty2.service               loaded active running   Getty on tty2
  ifup@venet0.service              loaded active exited    ifup for venet0
  ifupdown-pre.service             loaded active exited    Helper to synchronize boot up for ifupdown
  ifupdown-wait-online.service     loaded active exited    Wait for network to be configured by ifupdown
  kibana.service                   loaded active running   Kibana

…

На экран будет выведена таблица со следующей информацией:

  • UNIT — наименование приложения;
  • LOAD — правильно ли загружено описание приложения;
  • ACTIVE — статус приложения на данный момент;
  • SUB — более детальная информация о состоянии приложения;
  • DESCRIPTION — описание приложения.

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

systemctl list-units --all --state=inactive

Логичное продолжение этой команды — опция вывода информации об исполняемом файле приложения:

systemctl cat nginx.service

Правильное название сервиса, который нужно указать в данной команде, можно взять из списка, выведенного командой systemctl list-units.

Зависимости выбранного сервиса можно посмотреть командой list-dependencies:

sudo systemctl list-dependencies nginx.service
nginx.service
● ├─system.slice
● └─sysinit.target
●   ├─apparmor.service
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
●   ├─kmod-static-nodes.service
●   ├─proc-sys-fs-binfmt_misc.automount
●   ├─proc-sys-fs-binfmt_misc.mount
●   ├─sys-fs-fuse-connections.mount
●   ├─sys-kernel-config.mount
●   ├─sys-kernel-debug.mount
●   ├─sys-kernel-tracing.mount
●   ├─systemd-ask-password-console.path
●   ├─systemd-binfmt.service
●   ├─systemd-boot-system-token.service
●   ├─systemd-hwdb-update.service
●   ├─systemd-journal-flush.service

…

Полное описание сервиса можно вызвать командой:

sudo systemctl show nginx.service

# Output

Type=forking
Restart=no
PIDFile=/run/nginx.pid
NotifyAccess=none
RestartUSec=100ms
TimeoutStartUSec=1min 30s
TimeoutStopUSec=5s
TimeoutAbortUSec=5s
RuntimeMaxUSec=infinity
WatchdogUSec=0
WatchdogTimestampMonotonic=0
RootDirectoryStartOnly=no

…

# Маскировка сервиса

Иногда в работе нужно временно исключить из работы один сервис — запретить автоматический доступ к нему и не перезапускать его при перезагрузке системы. Это можно сделать с помощью команды mask:

sudo systemctl mask nginx.service

После этого при попытке запуска сервиса можно будет увидеть сообщение:

# Output
Failed to start nginx.service: Unit nginx.service is masked.

И в общем списке приложений напротив указанного сервиса будет сообщение masked.

Снятие маскировки производится обратной командой:

sudo systemctl unmask nginx.service

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

# journalctl

Команда journalctl — один из основных элементов работы с системными логами. Она позволяет не только читать общие системные логи, но и выбирать из них интересующую нас информацию — от временного интервала до конкретного сервиса или приложения.

# Установка локального времени

Начнём работу с логами с установки локального времени на сервере.

Обычно время, установленное на сервере, совпадает с его реальным временем в его часовом поясе. Это бывает неудобно при удалённом администрировании сервера: он подписывает логи своим локальным временем, которое может отличаться от времени администратора. Установим своё время на сервере.

Введите команду:

timedatectl

Она выведет на экран локальное время, установленное на сервере, UTC-время и укажет часовой пояс, выбранный на сервере. Чтобы изменить время на сервере, нужно указать часовой пояс, время которого будет считаться актуальным. Для этого выведем на экран список всех доступных часовых поясов:

timedatectl list-timezones

Выберем из списка нужный и установим его:

sudo timedatectl set-timezone zone_name

После этого командой timedatectl можно проверить, установилось ли нужное нам время, и переходить непосредственно к чтению логов.

# Работа с логами

Введите общую команду:

journalctl

Она выведет в консоль все логи событий сервера. Будьте внимательны — их может быть очень много.

Чтобы сократить число таких строк, можно добавить флаг -b к основной команде, тогда будут показаны логи только с момента последней перезагрузки сервера. Но даже в этом случае, если сервер нагружен и имеет большой аптайм, список может быть очень длинным.

# Сортировка по времени

Чтобы прочитать логи в определённом временном промежутке, используются флаги --before и --since, после которых указывается время в формате YYYY-MM-DD HH:MM:SS. Также эти флаги можно использовать совместно, чтобы выводить на экран события из определённого временного окна:

journalctl --since "2022-01-01" --until "2022-01-02 12:00"

Также эта команда поддерживает более свободный формат указания времени. Например, логи со вчерашнего дня:

sudo journalctl --since yesterday

А вот так выглядит указание на то, что временное окно логов нужно закончить час назад:

journalctl --since 12:00 --until "1 hour ago"

# Выбор логов конкретного сервиса

Один из наиболее популярных и полезных инструментов при работе с командой journalctl — вывод логов определённого сервиса или приложения. Для этого используется флаг -u, после которого указывается наименование интересующего нас сервиса или приложения. В частности вывод логов SSH-подключений выглядит так:

journalctl -u ssh

Этот флаг также сочетается с флагами времени:

journalctl -u ssh --since yesterday

Он может сочетаться и с командами на ограничение выводимых строк. Например, можно вывести в консоль последние 20 позиций из логов ssh-подключений:

journalctl -u ssh |tail -20

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

journalctl -n 20

# Логи и дисковое пространство

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

Введите команду:

journalctl --disk-usage

Она выведет в консоль сведения о занимаемом дисковом пространстве в данный момент:

#Output
Archived and active journals take up 16.0M in the file system.

Далее введите следующую команду:

sudo journalctl --vacuum-size=

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

Аналогично работает и эта команда:

sudo journalctl --vacuum-time=

Различие в том, что здесь в качестве значения указывается системное время, за которое нужно хранить журналы событий.

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